From c6d2f498142c29ed62241ab6d89cb7b5e38f2fca Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 12 Feb 2017 19:18:00 +0300 Subject: [PATCH 001/340] bpo-27122: Fix comment to point to correct issue number (#50) It took me quite a bit to figure out what this was referring to, since the given issue number is wrong, and the original commit message I found through git blame lists a different, also wrong issue number... see https://bugs.python.org/issue27122#msg279449 (cherry picked from commit af88e7eda4101f36e904771d3cf59a5f740b3b00) --- Lib/contextlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index d44edd6e198ad9..4a7bd079a7dbb8 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -82,7 +82,7 @@ def __exit__(self, type, value, traceback): # raised inside the "with" statement from being suppressed. return exc is not value except RuntimeError as exc: - # Don't re-raise the passed in exception. (issue27112) + # Don't re-raise the passed in exception. (issue27122) if exc is value: return False # Likewise, avoid suppressing if a StopIteration exception From ae828714ebdb7a0d69bf23c1f6d606e5e63bdcfe Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 12 Feb 2017 08:21:36 -0800 Subject: [PATCH 002/340] bpo-29474: Improve documentation for weakref.WeakValueDictionary (#23) There were some grammatical errors in weakref.WeakValueDictionary documentation. --- Doc/library/weakref.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/weakref.rst b/Doc/library/weakref.rst index e289b971e7c269..b02a006d733b6e 100644 --- a/Doc/library/weakref.rst +++ b/Doc/library/weakref.rst @@ -166,8 +166,8 @@ Extension types can easily be made to support weak references; see performed by the program during iteration may cause items in the dictionary to vanish "by magic" (as a side effect of garbage collection). -:class:`WeakKeyDictionary` objects have the following additional methods. These -expose the internal references directly. The references are not guaranteed to +:class:`WeakKeyDictionary` objects have an additional method that +exposes the internal references directly. The references are not guaranteed to be "live" at the time they are used, so the result of calling the references needs to be checked before being used. This can be used to avoid creating references that will cause the garbage collector to keep the keys around longer @@ -192,9 +192,9 @@ than needed. by the program during iteration may cause items in the dictionary to vanish "by magic" (as a side effect of garbage collection). -:class:`WeakValueDictionary` objects have the following additional methods. -These method have the same issues as the and :meth:`keyrefs` method of -:class:`WeakKeyDictionary` objects. +:class:`WeakValueDictionary` objects have an additional method that has the +same issues as the :meth:`keyrefs` method of :class:`WeakKeyDictionary` +objects. .. method:: WeakValueDictionary.valuerefs() From cabd1c7462ef991937e0e759b9bf307b3091ef06 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 12 Feb 2017 13:08:00 -0800 Subject: [PATCH 003/340] [backport to 3.5] bpo-28929: Link the documentation to its source file on GitHub (#36) * bpo-28929: Link the documentation to its source file on GitHub Change the documentation's `Show Source` link on the left menu to GitHub source file. (cherry picked from commit 23bafa294c75c20cb85ae5d97d7571a3a0ad8dd3) * remove if statement --- Doc/tools/templates/customsourcelink.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Doc/tools/templates/customsourcelink.html b/Doc/tools/templates/customsourcelink.html index 243d8107779361..71d0bba683074e 100644 --- a/Doc/tools/templates/customsourcelink.html +++ b/Doc/tools/templates/customsourcelink.html @@ -3,8 +3,11 @@

{{ _('This Page') }}

{%- endif %} From 06a4fcb2458c5904968b5c8fe6b64940ba83a50d Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Mon, 13 Feb 2017 09:16:20 +0900 Subject: [PATCH 004/340] bpo-29438: Fixed use-after-free in key sharing dict (#40) --- Misc/NEWS | 2 ++ Objects/dictobject.c | 10 ++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index e1b32add0ef3ca..6a1abf174c35a5 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-29438: Fixed use-after-free problem in key sharing dict. + - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0]. - Issue #29337: Fixed possible BytesWarning when compare the code objects. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 11c086ffb47ae0..7299f36b2bf88c 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -3893,20 +3893,18 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, } if (value == NULL) { res = PyDict_DelItem(dict, key); - if (cached != ((PyDictObject *)dict)->ma_keys) { - CACHED_KEYS(tp) = NULL; - DK_DECREF(cached); - } } else { - int was_shared = cached == ((PyDictObject *)dict)->ma_keys; + int was_shared = (cached == ((PyDictObject *)dict)->ma_keys); res = PyDict_SetItem(dict, key, value); /* PyDict_SetItem() may call dictresize() and convert split table * into combined table. In such case, convert it to split * table again and update type's shared key only when this is * the only dict sharing key with the type. */ - if (was_shared && cached != ((PyDictObject *)dict)->ma_keys) { + if (was_shared && + (cached = CACHED_KEYS(tp)) != NULL && + cached != ((PyDictObject *)dict)->ma_keys) { if (cached->dk_refcnt == 1) { CACHED_KEYS(tp) = make_keys_shared(dict); } else { From af456b241bd4889ac94eb215e73da400380460a0 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 13 Feb 2017 12:11:25 -0800 Subject: [PATCH 005/340] Support "bpo-" in Misc/NEWS (#1) (#43) Change the url to 3.5 (cherry picked from commit 79ab8be05fb4ffb5c258d2ca49be5fc2d4880431) Contributed by Brett Cannon --- Doc/tools/extensions/pyspecific.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 63112830ba02eb..00c9356927f853 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -34,7 +34,7 @@ ISSUE_URI = 'https://bugs.python.org/issue%s' -SOURCE_URI = 'https://hg.python.org/cpython/file/3.5/%s' +SOURCE_URI = 'https://github.com/python/cpython/tree/3.5/%s' # monkey-patch reST parser to disable alphabetic and roman enumerated lists from docutils.parsers.rst.states import Body @@ -79,7 +79,7 @@ def new_depart_literal_block(self, node): def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): issue = utils.unescape(text) - text = 'issue ' + issue + text = 'bpo-' + issue refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) return [refnode], [] @@ -225,7 +225,7 @@ def run(self): # Support for including Misc/NEWS -issue_re = re.compile('([Ii])ssue #([0-9]+)') +issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)') whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$") @@ -253,7 +253,7 @@ def run(self): text = 'The NEWS file is not available.' node = nodes.strong(text, text) return [node] - content = issue_re.sub(r'`\1ssue #\2 `__', + content = issue_re.sub(r'`bpo-\1 `__', content) content = whatsnew_re.sub(r'\1', content) # remove first 3 lines as they are the main heading From 9c5684e0d380cf5bc109888603756084588ce617 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 13 Feb 2017 14:28:58 -0800 Subject: [PATCH 006/340] bpo-28556: Various updates to typing (#28) (#78) various updates from upstream python/typing repo: - Added typing.Counter and typing.ChainMap generics - More flexible typing.NamedTuple - Improved generic ABC caching - More tests - Bugfixes - Other updates * Add Misc/NEWS entry * Add issue number Contributed by Ivan Levkivskyi @ilevkivskyi (cherry picked from commit b692dc8475a032740576129d0990ddc3edccab2b) --- Lib/test/mod_generics_cache.py | 14 ++ Lib/test/test_typing.py | 237 +++++++++++++++++++++++++++++---- Lib/typing.py | 138 ++++++++++++++----- Misc/NEWS | 7 + 4 files changed, 338 insertions(+), 58 deletions(-) create mode 100644 Lib/test/mod_generics_cache.py diff --git a/Lib/test/mod_generics_cache.py b/Lib/test/mod_generics_cache.py new file mode 100644 index 00000000000000..d9a60b4b28c325 --- /dev/null +++ b/Lib/test/mod_generics_cache.py @@ -0,0 +1,14 @@ +"""Module for testing the behavior of generics across different modules.""" + +from typing import TypeVar, Generic + +T = TypeVar('T') + + +class A(Generic[T]): + pass + + +class B(Generic[T]): + class A(Generic[T]): + pass diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index fce6b5aaffdf93..64d8276658ee7f 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -190,6 +190,10 @@ def test_bound_errors(self): with self.assertRaises(TypeError): TypeVar('X', str, float, bound=Employee) + def test_no_bivariant(self): + with self.assertRaises(ValueError): + TypeVar('T', covariant=True, contravariant=True) + class UnionTests(BaseTestCase): @@ -254,6 +258,11 @@ def test_repr(self): self.assertEqual(repr(u), 'typing.Union[%s.Employee, int]' % __name__) u = Union[int, Employee] self.assertEqual(repr(u), 'typing.Union[int, %s.Employee]' % __name__) + T = TypeVar('T') + u = Union[T, int][int] + self.assertEqual(repr(u), repr(int)) + u = Union[List[int], int] + self.assertEqual(repr(u), 'typing.Union[typing.List[int], int]') def test_cannot_subclass(self): with self.assertRaises(TypeError): @@ -304,6 +313,15 @@ def test_union_instance_type_error(self): with self.assertRaises(TypeError): isinstance(42, Union[int, str]) + def test_no_eval_union(self): + u = Union[int, str] + def f(x: u): ... + self.assertIs(get_type_hints(f)['x'], u) + + def test_function_repr_union(self): + def fun() -> int: ... + self.assertEqual(repr(Union[fun, int]), 'typing.Union[fun, int]') + def test_union_str_pattern(self): # Shouldn't crash; see http://bugs.python.org/issue25390 A = Union[str, Pattern] @@ -401,6 +419,8 @@ def test_callable_wrong_forms(self): Callable[[()], int] with self.assertRaises(TypeError): Callable[[int, 1], 2] + with self.assertRaises(TypeError): + Callable[int] def test_callable_instance_works(self): def f(): @@ -546,15 +566,27 @@ def test_basics(self): Y[str] with self.assertRaises(TypeError): Y[str, str] + self.assertIsSubclass(SimpleMapping[str, int], SimpleMapping) def test_generic_errors(self): T = TypeVar('T') + S = TypeVar('S') with self.assertRaises(TypeError): Generic[T]() + with self.assertRaises(TypeError): + Generic[T][T] + with self.assertRaises(TypeError): + Generic[T][S] with self.assertRaises(TypeError): isinstance([], List[int]) with self.assertRaises(TypeError): issubclass(list, List[int]) + with self.assertRaises(TypeError): + class NewGeneric(Generic): ... + with self.assertRaises(TypeError): + class MyGeneric(Generic[T], Generic[S]): ... + with self.assertRaises(TypeError): + class MyGeneric(List[T], Generic[S]): ... def test_init(self): T = TypeVar('T') @@ -738,6 +770,53 @@ def test_subscript_meta(self): self.assertEqual(Union[T, int][GenericMeta], Union[GenericMeta, int]) self.assertEqual(Callable[..., GenericMeta].__args__, (Ellipsis, GenericMeta)) + def test_generic_hashes(self): + try: + from test import mod_generics_cache + except ImportError: # for Python 3.4 and previous versions + import mod_generics_cache + class A(Generic[T]): + ... + + class B(Generic[T]): + class A(Generic[T]): + ... + + self.assertEqual(A, A) + self.assertEqual(mod_generics_cache.A[str], mod_generics_cache.A[str]) + self.assertEqual(B.A, B.A) + self.assertEqual(mod_generics_cache.B.A[B.A[str]], + mod_generics_cache.B.A[B.A[str]]) + + self.assertNotEqual(A, B.A) + self.assertNotEqual(A, mod_generics_cache.A) + self.assertNotEqual(A, mod_generics_cache.B.A) + self.assertNotEqual(B.A, mod_generics_cache.A) + self.assertNotEqual(B.A, mod_generics_cache.B.A) + + self.assertNotEqual(A[str], B.A[str]) + self.assertNotEqual(A[List[Any]], B.A[List[Any]]) + self.assertNotEqual(A[str], mod_generics_cache.A[str]) + self.assertNotEqual(A[str], mod_generics_cache.B.A[str]) + self.assertNotEqual(B.A[int], mod_generics_cache.A[int]) + self.assertNotEqual(B.A[List[Any]], mod_generics_cache.B.A[List[Any]]) + + self.assertNotEqual(Tuple[A[str]], Tuple[B.A[str]]) + self.assertNotEqual(Tuple[A[List[Any]]], Tuple[B.A[List[Any]]]) + self.assertNotEqual(Union[str, A[str]], Union[str, mod_generics_cache.A[str]]) + self.assertNotEqual(Union[A[str], A[str]], + Union[A[str], mod_generics_cache.A[str]]) + self.assertNotEqual(typing.FrozenSet[A[str]], + typing.FrozenSet[mod_generics_cache.B.A[str]]) + + if sys.version_info[:2] > (3, 2): + self.assertTrue(repr(Tuple[A[str]]).endswith('.A[str]]')) + self.assertTrue(repr(Tuple[B.A[str]]).endswith('.B.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.A[str]]) + .endswith('mod_generics_cache.A[str]]')) + self.assertTrue(repr(Tuple[mod_generics_cache.B.A[str]]) + .endswith('mod_generics_cache.B.A[str]]')) + def test_extended_generic_rules_eq(self): T = TypeVar('T') U = TypeVar('U') @@ -835,6 +914,8 @@ def test_fail_with_bare_generic(self): Tuple[Generic[T]] with self.assertRaises(TypeError): List[typing._Protocol] + with self.assertRaises(TypeError): + isinstance(1, Generic) def test_type_erasure_special(self): T = TypeVar('T') @@ -853,6 +934,11 @@ class MyDict(typing.Dict[T, T]): ... class MyDef(typing.DefaultDict[str, T]): ... self.assertIs(MyDef[int]().__class__, MyDef) self.assertIs(MyDef[int]().__orig_class__, MyDef[int]) + # ChainMap was added in 3.3 + if sys.version_info >= (3, 3): + class MyChain(typing.ChainMap[str, T]): ... + self.assertIs(MyChain[int]().__class__, MyChain) + self.assertIs(MyChain[int]().__orig_class__, MyChain[int]) def test_all_repr_eq_any(self): objs = (getattr(typing, el) for el in typing.__all__) @@ -1203,6 +1289,19 @@ def test_forwardref_instance_type_error(self): with self.assertRaises(TypeError): isinstance(42, fr) + def test_forwardref_subclass_type_error(self): + fr = typing._ForwardRef('int') + with self.assertRaises(TypeError): + issubclass(int, fr) + + def test_forward_equality(self): + fr = typing._ForwardRef('int') + self.assertEqual(fr, typing._ForwardRef('int')) + self.assertNotEqual(List['int'], List[int]) + + def test_forward_repr(self): + self.assertEqual(repr(List['int']), "typing.List[_ForwardRef('int')]") + def test_union_forward(self): def foo(a: Union['T']): @@ -1285,6 +1384,15 @@ def foo(a: 'whatevers') -> {}: ith = get_type_hints(C().foo) self.assertEqual(ith, {}) + def test_no_type_check_no_bases(self): + class C: + def meth(self, x: int): ... + @no_type_check + class D(C): + c = C + # verify that @no_type_check never affects bases + self.assertEqual(get_type_hints(C.meth), {'x': int}) + def test_meta_no_type_check(self): @no_type_check_decorator @@ -1401,11 +1509,16 @@ class A: class B(A): x: ClassVar[Optional['B']] = None y: int + b: int class CSub(B): z: ClassVar['CSub'] = B() class G(Generic[T]): lst: ClassVar[List[T]] = [] +class NoneAndForward: + parent: 'NoneAndForward' + meaning: None + class CoolEmployee(NamedTuple): name: str cool: int @@ -1419,10 +1532,13 @@ class XMeth(NamedTuple): def double(self): return 2 * self.x -class XMethBad(NamedTuple): +class XRepr(NamedTuple): x: int - def _fields(self): - return 'no chance for this' + y: int = 1 + def __str__(self): + return f'{self.x} -> {self.y}' + def __add__(self, other): + return 0 """ if PY36: @@ -1431,7 +1547,7 @@ def _fields(self): # fake names for the sake of static analysis ann_module = ann_module2 = ann_module3 = None A = B = CSub = G = CoolEmployee = CoolEmployeeWithDefault = object - XMeth = XMethBad = object + XMeth = XRepr = NoneAndForward = object gth = get_type_hints @@ -1466,6 +1582,8 @@ def test_get_type_hints_classes(self): {'y': Optional[ann_module.C]}) self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) self.assertEqual(gth(ann_module.foo), {'x': int}) + self.assertEqual(gth(NoneAndForward, globals()), + {'parent': NoneAndForward, 'meaning': type(None)}) @skipUnless(PY36, 'Python 3.6 required') def test_respect_no_type_check(self): @@ -1482,17 +1600,22 @@ def meth(x: int): ... class Der(ABase): ... self.assertEqual(gth(ABase.meth), {'x': int}) - def test_get_type_hints_for_builins(self): + def test_get_type_hints_for_builtins(self): # Should not fail for built-in classes and functions. self.assertEqual(gth(int), {}) self.assertEqual(gth(type), {}) self.assertEqual(gth(dir), {}) self.assertEqual(gth(len), {}) + self.assertEqual(gth(object.__str__), {}) + self.assertEqual(gth(object().__str__), {}) + self.assertEqual(gth(str.join), {}) def test_previous_behavior(self): def testf(x, y): ... testf.__annotations__['x'] = 'int' self.assertEqual(gth(testf), {'x': int}) + def testg(x: None): ... + self.assertEqual(gth(testg), {'x': type(None)}) def test_get_type_hints_for_object_with_annotations(self): class A: ... @@ -1506,9 +1629,10 @@ def test_get_type_hints_ClassVar(self): self.assertEqual(gth(ann_module2.CV, ann_module2.__dict__), {'var': typing.ClassVar[ann_module2.CV]}) self.assertEqual(gth(B, globals()), - {'y': int, 'x': ClassVar[Optional[B]]}) + {'y': int, 'x': ClassVar[Optional[B]], 'b': int}) self.assertEqual(gth(CSub, globals()), - {'z': ClassVar[CSub], 'y': int, 'x': ClassVar[Optional[B]]}) + {'z': ClassVar[CSub], 'y': int, 'b': int, + 'x': ClassVar[Optional[B]]}) self.assertEqual(gth(G), {'lst': ClassVar[List[T]]}) @@ -1628,6 +1752,11 @@ def test_list(self): def test_deque(self): self.assertIsSubclass(collections.deque, typing.Deque) + class MyDeque(typing.Deque[int]): ... + self.assertIsInstance(MyDeque(), collections.deque) + + def test_counter(self): + self.assertIsSubclass(collections.Counter, typing.Counter) def test_set(self): self.assertIsSubclass(set, typing.Set) @@ -1680,13 +1809,10 @@ class MyDict(typing.Dict[str, int]): self.assertIsSubclass(MyDict, dict) self.assertNotIsSubclass(dict, MyDict) - def test_no_defaultdict_instantiation(self): - with self.assertRaises(TypeError): - typing.DefaultDict() - with self.assertRaises(TypeError): - typing.DefaultDict[KT, VT]() - with self.assertRaises(TypeError): - typing.DefaultDict[str, int]() + def test_defaultdict_instantiation(self): + self.assertIs(type(typing.DefaultDict()), collections.defaultdict) + self.assertIs(type(typing.DefaultDict[KT, VT]()), collections.defaultdict) + self.assertIs(type(typing.DefaultDict[str, int]()), collections.defaultdict) def test_defaultdict_subclass(self): @@ -1699,13 +1825,49 @@ class MyDefDict(typing.DefaultDict[str, int]): self.assertIsSubclass(MyDefDict, collections.defaultdict) self.assertNotIsSubclass(collections.defaultdict, MyDefDict) - def test_no_deque_instantiation(self): - with self.assertRaises(TypeError): - typing.Deque() - with self.assertRaises(TypeError): - typing.Deque[T]() - with self.assertRaises(TypeError): - typing.Deque[int]() + @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') + def test_chainmap_instantiation(self): + self.assertIs(type(typing.ChainMap()), collections.ChainMap) + self.assertIs(type(typing.ChainMap[KT, VT]()), collections.ChainMap) + self.assertIs(type(typing.ChainMap[str, int]()), collections.ChainMap) + class CM(typing.ChainMap[KT, VT]): ... + self.assertIs(type(CM[int, str]()), CM) + + @skipUnless(sys.version_info >= (3, 3), 'ChainMap was added in 3.3') + def test_chainmap_subclass(self): + + class MyChainMap(typing.ChainMap[str, int]): + pass + + cm = MyChainMap() + self.assertIsInstance(cm, MyChainMap) + + self.assertIsSubclass(MyChainMap, collections.ChainMap) + self.assertNotIsSubclass(collections.ChainMap, MyChainMap) + + def test_deque_instantiation(self): + self.assertIs(type(typing.Deque()), collections.deque) + self.assertIs(type(typing.Deque[T]()), collections.deque) + self.assertIs(type(typing.Deque[int]()), collections.deque) + class D(typing.Deque[T]): ... + self.assertIs(type(D[int]()), D) + + def test_counter_instantiation(self): + self.assertIs(type(typing.Counter()), collections.Counter) + self.assertIs(type(typing.Counter[T]()), collections.Counter) + self.assertIs(type(typing.Counter[int]()), collections.Counter) + class C(typing.Counter[T]): ... + self.assertIs(type(C[int]()), C) + + def test_counter_subclass_instantiation(self): + + class MyCounter(typing.Counter[int]): + pass + + d = MyCounter() + self.assertIsInstance(d, MyCounter) + self.assertIsInstance(d, typing.Counter) + self.assertIsInstance(d, collections.Counter) def test_no_set_instantiation(self): with self.assertRaises(TypeError): @@ -2018,6 +2180,14 @@ def test_basics(self): collections.OrderedDict([('name', str), ('id', int)])) self.assertIs(Emp._field_types, Emp.__annotations__) + def test_namedtuple_pyversion(self): + if sys.version_info[:2] < (3, 6): + with self.assertRaises(TypeError): + NamedTuple('Name', one=int, other=str) + with self.assertRaises(TypeError): + class NotYet(NamedTuple): + whatever = 0 + @skipUnless(PY36, 'Python 3.6 required') def test_annotation_usage(self): tim = CoolEmployee('Tim', 9000) @@ -2055,10 +2225,18 @@ class NonDefaultAfterDefault(NamedTuple): @skipUnless(PY36, 'Python 3.6 required') def test_annotation_usage_with_methods(self): - self.assertEquals(XMeth(1).double(), 2) - self.assertEquals(XMeth(42).x, XMeth(42)[0]) - self.assertEquals(XMethBad(1)._fields, ('x',)) - self.assertEquals(XMethBad(1).__annotations__, {'x': int}) + self.assertEqual(XMeth(1).double(), 2) + self.assertEqual(XMeth(42).x, XMeth(42)[0]) + self.assertEqual(str(XRepr(42)), '42 -> 1') + self.assertEqual(XRepr(1, 2) + XRepr(3), 0) + + with self.assertRaises(AttributeError): + exec(""" +class XMethBad(NamedTuple): + x: int + def _fields(self): + return 'no chance for this' +""") @skipUnless(PY36, 'Python 3.6 required') def test_namedtuple_keyword_usage(self): @@ -2138,6 +2316,12 @@ def test_basics(self): Pattern[Union[str, bytes]] Match[Union[bytes, str]] + def test_alias_equality(self): + self.assertEqual(Pattern[str], Pattern[str]) + self.assertNotEqual(Pattern[str], Pattern[bytes]) + self.assertNotEqual(Pattern[str], Match[str]) + self.assertNotEqual(Pattern[str], str) + def test_errors(self): with self.assertRaises(TypeError): # Doesn't fit AnyStr. @@ -2152,6 +2336,9 @@ def test_errors(self): with self.assertRaises(TypeError): # We don't support isinstance(). isinstance(42, Pattern[str]) + with self.assertRaises(TypeError): + # We don't support issubclass(). + issubclass(Pattern[bytes], Pattern[str]) def test_repr(self): self.assertEqual(repr(Pattern), 'Pattern[~AnyStr]') diff --git a/Lib/typing.py b/Lib/typing.py index c9e341753769e0..efe358faf20988 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -10,6 +10,12 @@ import collections.abc as collections_abc except ImportError: import collections as collections_abc # Fallback for PY3.2. +try: + from types import SlotWrapperType, MethodWrapperType, MethodDescriptorType +except ImportError: + SlotWrapperType = type(object.__init__) + MethodWrapperType = type(object().__str__) + MethodDescriptorType = type(str.join) # Please keep __all__ alphabetized within each category. @@ -62,6 +68,7 @@ 'SupportsRound', # Concrete collection types. + 'Counter', 'Deque', 'Dict', 'DefaultDict', @@ -849,19 +856,6 @@ def _next_in_mro(cls): return next_in_mro -def _valid_for_check(cls): - """An internal helper to prohibit isinstance([1], List[str]) etc.""" - if cls is Generic: - raise TypeError("Class %r cannot be used with class " - "or instance checks" % cls) - if ( - cls.__origin__ is not None and - sys._getframe(3).f_globals['__name__'] not in ['abc', 'functools'] - ): - raise TypeError("Parameterized generics cannot be used with class " - "or instance checks") - - def _make_subclasshook(cls): """Construct a __subclasshook__ callable that incorporates the associated __extra__ class in subclass checks performed @@ -872,7 +866,6 @@ def _make_subclasshook(cls): # Registered classes need not be checked here because # cls and its extra share the same _abc_registry. def __extrahook__(subclass): - _valid_for_check(cls) res = cls.__extra__.__subclasshook__(subclass) if res is not NotImplemented: return res @@ -887,7 +880,6 @@ def __extrahook__(subclass): else: # For non-ABC extras we'll just call issubclass(). def __extrahook__(subclass): - _valid_for_check(cls) if cls.__extra__ and issubclass(subclass, cls.__extra__): return True return NotImplemented @@ -974,6 +966,7 @@ def __new__(cls, name, bases, namespace, # remove bare Generic from bases if there are other generic bases if any(isinstance(b, GenericMeta) and b is not Generic for b in bases): bases = tuple(b for b in bases if b is not Generic) + namespace.update({'__origin__': origin, '__extra__': extra}) self = super().__new__(cls, name, bases, namespace, _root=True) self.__parameters__ = tvars @@ -982,8 +975,6 @@ def __new__(cls, name, bases, namespace, self.__args__ = tuple(... if a is _TypingEllipsis else () if a is _TypingEmpty else a for a in args) if args else None - self.__origin__ = origin - self.__extra__ = extra # Speed hack (https://github.com/python/typing/issues/196). self.__next_in_mro__ = _next_in_mro(self) # Preserve base classes on subclassing (__bases__ are type erased now). @@ -994,20 +985,56 @@ def __new__(cls, name, bases, namespace, # with issubclass() and isinstance() in the same way as their # collections.abc counterparts (e.g., isinstance([], Iterable)). if ( - # allow overriding '__subclasshook__' not in namespace and extra or - hasattr(self.__subclasshook__, '__name__') and - self.__subclasshook__.__name__ == '__extrahook__' + # allow overriding + getattr(self.__subclasshook__, '__name__', '') == '__extrahook__' ): self.__subclasshook__ = _make_subclasshook(self) if isinstance(extra, abc.ABCMeta): self._abc_registry = extra._abc_registry + self._abc_cache = extra._abc_cache + elif origin is not None: + self._abc_registry = origin._abc_registry + self._abc_cache = origin._abc_cache if origin and hasattr(origin, '__qualname__'): # Fix for Python 3.2. self.__qualname__ = origin.__qualname__ - self.__tree_hash__ = hash(self._subs_tree()) if origin else hash((self.__name__,)) + self.__tree_hash__ = (hash(self._subs_tree()) if origin else + super(GenericMeta, self).__hash__()) return self + # _abc_negative_cache and _abc_negative_cache_version + # realised as descriptors, since GenClass[t1, t2, ...] always + # share subclass info with GenClass. + # This is an important memory optimization. + @property + def _abc_negative_cache(self): + if isinstance(self.__extra__, abc.ABCMeta): + return self.__extra__._abc_negative_cache + return _gorg(self)._abc_generic_negative_cache + + @_abc_negative_cache.setter + def _abc_negative_cache(self, value): + if self.__origin__ is None: + if isinstance(self.__extra__, abc.ABCMeta): + self.__extra__._abc_negative_cache = value + else: + self._abc_generic_negative_cache = value + + @property + def _abc_negative_cache_version(self): + if isinstance(self.__extra__, abc.ABCMeta): + return self.__extra__._abc_negative_cache_version + return _gorg(self)._abc_generic_negative_cache_version + + @_abc_negative_cache_version.setter + def _abc_negative_cache_version(self, value): + if self.__origin__ is None: + if isinstance(self.__extra__, abc.ABCMeta): + self.__extra__._abc_negative_cache_version = value + else: + self._abc_generic_negative_cache_version = value + def _get_type_vars(self, tvars): if self.__origin__ and self.__parameters__: _get_type_vars(self.__parameters__, tvars) @@ -1095,8 +1122,10 @@ def __getitem__(self, params): _check_generic(self, params) tvars = _type_vars(params) args = params + + prepend = (self,) if self.__origin__ is None else () return self.__class__(self.__name__, - self.__bases__, + prepend + self.__bases__, _no_slots_copy(self.__dict__), tvars=tvars, args=args, @@ -1104,6 +1133,17 @@ def __getitem__(self, params): extra=self.__extra__, orig_bases=self.__orig_bases__) + def __subclasscheck__(self, cls): + if self.__origin__ is not None: + if sys._getframe(1).f_globals['__name__'] not in ['abc', 'functools']: + raise TypeError("Parameterized generics cannot be used with class " + "or instance checks") + return False + if self is Generic: + raise TypeError("Class %r cannot be used with class " + "or instance checks" % self) + return super().__subclasscheck__(cls) + def __instancecheck__(self, instance): # Since we extend ABC.__subclasscheck__ and # ABC.__instancecheck__ inlines the cache checking done by the @@ -1398,6 +1438,11 @@ def _get_defaults(func): return res +_allowed_types = (types.FunctionType, types.BuiltinFunctionType, + types.MethodType, types.ModuleType, + SlotWrapperType, MethodWrapperType, MethodDescriptorType) + + def get_type_hints(obj, globalns=None, localns=None): """Return type hints for an object. @@ -1452,12 +1497,7 @@ def get_type_hints(obj, globalns=None, localns=None): hints = getattr(obj, '__annotations__', None) if hints is None: # Return empty annotations for something that _could_ have them. - if ( - isinstance(obj, types.FunctionType) or - isinstance(obj, types.BuiltinFunctionType) or - isinstance(obj, types.MethodType) or - isinstance(obj, types.ModuleType) - ): + if isinstance(obj, _allowed_types): return {} else: raise TypeError('{!r} is not a module, class, method, ' @@ -1824,8 +1864,7 @@ class Deque(collections.deque, MutableSequence[T], extra=collections.deque): def __new__(cls, *args, **kwds): if _geqv(cls, Deque): - raise TypeError("Type Deque cannot be instantiated; " - "use deque() instead") + return collections.deque(*args, **kwds) return _generic_new(collections.deque, cls, *args, **kwds) @@ -1894,11 +1933,35 @@ class DefaultDict(collections.defaultdict, MutableMapping[KT, VT], def __new__(cls, *args, **kwds): if _geqv(cls, DefaultDict): - raise TypeError("Type DefaultDict cannot be instantiated; " - "use collections.defaultdict() instead") + return collections.defaultdict(*args, **kwds) return _generic_new(collections.defaultdict, cls, *args, **kwds) +class Counter(collections.Counter, Dict[T, int], extra=collections.Counter): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, Counter): + return collections.Counter(*args, **kwds) + return _generic_new(collections.Counter, cls, *args, **kwds) + + +if hasattr(collections, 'ChainMap'): + # ChainMap only exists in 3.3+ + __all__.append('ChainMap') + + class ChainMap(collections.ChainMap, MutableMapping[KT, VT], + extra=collections.ChainMap): + + __slots__ = () + + def __new__(cls, *args, **kwds): + if _geqv(cls, ChainMap): + return collections.ChainMap(*args, **kwds) + return _generic_new(collections.ChainMap, cls, *args, **kwds) + + # Determine what base class to use for Generator. if hasattr(collections_abc, 'Generator'): # Sufficiently recent versions of 3.5 have a Generator ABC. @@ -1975,6 +2038,13 @@ def _make_nmtuple(name, types): _PY36 = sys.version_info[:2] >= (3, 6) +# attributes prohibited to set in NamedTuple class syntax +_prohibited = ('__new__', '__init__', '__slots__', '__getnewargs__', + '_fields', '_field_defaults', '_field_types', + '_make', '_replace', '_asdict') + +_special = ('__module__', '__name__', '__qualname__', '__annotations__') + class NamedTupleMeta(type): @@ -2002,7 +2072,9 @@ def __new__(cls, typename, bases, ns): nm_tpl._field_defaults = defaults_dict # update from user namespace without overriding special namedtuple attributes for key in ns: - if not hasattr(nm_tpl, key): + if key in _prohibited: + raise AttributeError("Cannot overwrite NamedTuple attribute " + key) + elif key not in _special and key not in nm_tpl._fields: setattr(nm_tpl, key, ns[key]) return nm_tpl diff --git a/Misc/NEWS b/Misc/NEWS index 6a1abf174c35a5..fe50135c01615c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -25,6 +25,13 @@ Extension Modules Library ------- +- Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap, + improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, + Manuel Krebber, and Łukasz Langa. + +- Issue #29100: Fix datetime.fromtimestamp() regression introduced in Python + 3.6.0: check minimum and maximum years. + - Issue #29519: Fix weakref spewing exceptions during interpreter shutdown when used with a rare combination of multiprocessing and custom codecs. From 3ae8fd43fd18160dcb619d7d367cb1b41aeab32a Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 13 Feb 2017 15:49:08 -0800 Subject: [PATCH 007/340] A few README tweaks (#73) (#80) * Add a paragraph at the top for users, not builders, of Python. * Use nicer rst url syntax to avoid borking paragraphs in the plain text. Contributed by Ned Batchelder @nedbat (cherry picked from commit 3cdbd68ce8230cff1afb67472b96fbfa7f047e32) --- README | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README b/README index de3a091e07a598..8133b3191689ef 100644 --- a/README +++ b/README @@ -11,6 +11,14 @@ especially how built-in objects like dictionaries and strings work, have changed considerably, and a lot of deprecated features have finally been removed. +Using Python +------------ + +Installable Python kits, and information about using Python, are available at +`python.org`_. + +.. _python.org: https://www.python.org/ + Build Instructions ------------------ @@ -151,7 +159,7 @@ IMPORTANT: If the tests fail and you decide to mail a bug report, *don't* include the output of "make test". It is useless. Run the failing test manually, as follows: - ./python -m test -v test_whatever + ./python -m test -v test_whatever (substituting the top of the source tree for '.' if you built in a different directory). This runs the test in verbose mode. @@ -198,11 +206,12 @@ Proposals for enhancement ------------------------- If you have a proposal to change Python, you may want to send an email to the -comp.lang.python or python-ideas mailing lists for inital feedback. A Python +comp.lang.python or `python-ideas`_ mailing lists for initial feedback. A Python Enhancement Proposal (PEP) may be submitted if your idea gains ground. All current PEPs, as well as guidelines for submitting a new PEP, are listed at http://www.python.org/dev/peps/. +.. _python-ideas: https://mail.python.org/mailman/listinfo/python-ideas/ Release Schedule ---------------- From c0f9014a51593b2d58721819f8686f96dce5be71 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 14 Feb 2017 06:12:15 -0800 Subject: [PATCH 008/340] Fix some sphinx warnings (#9) (#82) * Fix some deprecation warnings in Doc/conf.py * Fix an rst error in Misc/NEWS Contributed by Ryan Gonzalez @kirbyfan64 (cherry picked from commit e7ffb99f842ebff97cffa0fc90b18be4e5abecf2) --- Doc/Makefile | 2 +- Doc/conf.py | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index 10c3288c590fd9..9ad7b86579d66c 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -10,7 +10,7 @@ PAPER = SOURCES = DISTVERSION = $(shell $(PYTHON) tools/extensions/patchlevel.py) -ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_paper_size=$(PAPER) \ +ALLSPHINXOPTS = -b $(BUILDER) -d build/doctrees -D latex_elements.papersize=$(PAPER) \ $(SPHINXOPTS) . build/$(BUILDER) $(SOURCES) .PHONY: help build html htmlhelp latex text changes linkcheck \ diff --git a/Doc/conf.py b/Doc/conf.py index b1bb6208bb4b8e..b3f26d5a692163 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -88,11 +88,24 @@ # Options for LaTeX output # ------------------------ +# Get LaTeX to handle Unicode correctly +latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} + +# Additional stuff for the LaTeX preamble. +latex_elements['preamble'] = r''' +\authoraddress{ + \strong{Python Software Foundation}\\ + Email: \email{docs@python.org} +} +\let\Verbatim=\OriginalVerbatim +\let\endVerbatim=\endOriginalVerbatim +''' + # The paper size ('letter' or 'a4'). -latex_paper_size = 'a4' +latex_elements['papersize'] = 'a4' # The font size ('10pt', '11pt' or '12pt'). -latex_font_size = '10pt' +latex_elements['font_size'] = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, document class [howto/manual]). @@ -125,22 +138,9 @@ for fn in os.listdir('howto') if fn.endswith('.rst') and fn != 'index.rst') -# Additional stuff for the LaTeX preamble. -latex_preamble = r''' -\authoraddress{ - \strong{Python Software Foundation}\\ - Email: \email{docs@python.org} -} -\let\Verbatim=\OriginalVerbatim -\let\endVerbatim=\endOriginalVerbatim -''' - # Documents to append as an appendix to all manuals. latex_appendices = ['glossary', 'about', 'license', 'copyright'] -# Get LaTeX to handle Unicode correctly -latex_elements = {'inputenc': r'\usepackage[utf8x]{inputenc}', 'utf8extra': ''} - # Options for Epub output # ----------------------- From 38c8354f3204441f6c6bd22213b449d2d8954fcc Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 14 Feb 2017 08:54:22 -0800 Subject: [PATCH 009/340] bpo-29521 Fix two minor documentation build warnings (#41) (#84) Much of bpo-29521 was fixed in parallel with commit e7ffb99 . This cleans up the rest. Apply parallel change to Doc/make.bat to read "set SPHINXOPTS=-D latex_elements.papersize=" I don't have a Windows system on which to observe the warning, but it should be necessary. The warning: .../workspace/cpython_github/Doc/faq/windows.rst:303: WARNING: unknown option: -t In the Windows FAQ, `How do I keep editors from inserting tabs into my Python source?`, contained a reference to a Python -t option. In Python 2.x, this caused Python to issue warnings about lines with mixed spaces and tabs, but as of Python 3.6 it does nothing. Per discussion at http://bugs.python.org/issue29387, take their wording. Python [3] raises an IndentationError or TabError. Tabnanny is now a module. (cherry picked from commit 3d707be950b387552585451071928e7b39cdfa53) --- Doc/faq/windows.rst | 7 ++++--- Doc/make.bat | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index d7253436beaf61..b9b7b8d359bdf2 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -300,9 +300,10 @@ this respect, and is easily configured to use spaces: Take :menuselection:`Tools --> Options --> Tabs`, and for file type "Default" set "Tab size" and "Indent size" to 4, and select the "Insert spaces" radio button. -If you suspect mixed tabs and spaces are causing problems in leading whitespace, -run Python with the :option:`-t` switch or run ``Tools/Scripts/tabnanny.py`` to -check a directory tree in batch mode. +Python raises :exc:`IndentationError` or :exc:`TabError` if mixed tabs +and spaces are causing problems in leading whitespace. +You may also run the :mod:`tabnanny` module to check a directory tree +in batch mode. How do I check for a keypress without blocking? diff --git a/Doc/make.bat b/Doc/make.bat index 5ab80850a3103b..740f148affa6cf 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -86,7 +86,7 @@ goto end :build if NOT "%PAPER%" == "" ( - set SPHINXOPTS=-D latex_paper_size=%PAPER% %SPHINXOPTS% + set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% ) cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* From 1bfd33f5732ba5f6d15e99d88e45a62a9cc42542 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 15 Feb 2017 18:59:45 +0900 Subject: [PATCH 010/340] Update URL of Mersenne Twister Home Page (#20) (#114) --- Modules/_randommodule.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 95ad4a429a04f0..9ce788289572c7 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -2,7 +2,7 @@ /* ------------------------------------------------------------------ The code in this module was based on a download from: - http://www.math.keio.ac.jp/~matumoto/MT2002/emt19937ar.html + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html It was modified in 2002 by Raymond Hettinger as follows: @@ -60,8 +60,8 @@ Any feedback is very welcome. - http://www.math.keio.ac.jp/matumoto/emt.html - email: matumoto@math.keio.ac.jp + http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) */ /* ---------------------------------------------------------------*/ From bb53a27a5d56a4f33c3fc8eebb486b34808c92b7 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 15 Feb 2017 11:39:37 -0800 Subject: [PATCH 011/340] [cherry-pick for 3.5] bpo-29481: add versionadded 3.5.4 to typing.Deque docs (#109) (cherry picked from commit 7e147f1ddb8233964ff0981e6b64fc12edac99aa) --- Doc/library/typing.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 8da71b64a7922f..93ea4f9422997a 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -561,6 +561,8 @@ The module defines the following classes, functions and decorators: A generic version of :class:`collections.deque`. + .. versionadded:: 3.5.4 + .. class:: List(list, MutableSequence[T]) Generic version of :class:`list`. From de553b8210882823d3df3f1ef6882eba3f8accf3 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 15 Feb 2017 15:14:38 -0800 Subject: [PATCH 012/340] bpo-29521 update Misc/ACKS (#111) (cherry picked from commit 6420088b924a23e5de40be6623d2a80b12f71d97) --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index 3c169d6ef54778..d33ee913f49c41 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -341,6 +341,7 @@ A. Jesse Jiryu Davis Merlijn van Deen John DeGood Ned Deily +Jim DeLaHunt Vincent Delft Arnaud Delobelle Konrad Delong From 5e04dfecec478db13031fa507d6b2e21adbce035 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 16 Feb 2017 10:43:16 +0100 Subject: [PATCH 013/340] Backport35 doc fixes: PR#68 and PR#124 (#125) (#126) * Travis CI: run rstlint.py in the docs job (#68) Currently, http://buildbot.python.org/all/buildslaves/ware-docs buildbot is only run as post-commit. For example, bpo-29521 (PR#41) introduced two warnings, unnotified by the Travis CI docs job. Modify the docs job to run toosl/rstlint.py. Fix also the two minor warnings which causes the buildbot slave to fail. (cherry picked from commit 2b501866ed493758e4c4b29f0ce9b24023d910a1) * Doc/Makefile: set PYTHON to python3 (#124) rstlint.py run by "make check" doesn't support Python 2. "make venv" runs "$(PYTHON) -m venv", whereas Python 2 doens't provide the venv module: it's a module of Python 3 standard library. (cherry picked from commit 91b0e7d0ca7c59df28f6a6fc1e8eb86a3925b76c) (cherry picked from commit b300c660d34d2027d443098ea605a8e0eb51d383) --- Doc/Makefile | 2 +- Doc/faq/windows.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/Makefile b/Doc/Makefile index 9ad7b86579d66c..b0800c15b5c80f 100644 --- a/Doc/Makefile +++ b/Doc/Makefile @@ -4,7 +4,7 @@ # # You can set these variables from the command line. -PYTHON = python +PYTHON = python3 SPHINXBUILD = sphinx-build PAPER = SOURCES = diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index b9b7b8d359bdf2..6ac83e45d2e815 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -300,9 +300,9 @@ this respect, and is easily configured to use spaces: Take :menuselection:`Tools --> Options --> Tabs`, and for file type "Default" set "Tab size" and "Indent size" to 4, and select the "Insert spaces" radio button. -Python raises :exc:`IndentationError` or :exc:`TabError` if mixed tabs +Python raises :exc:`IndentationError` or :exc:`TabError` if mixed tabs and spaces are causing problems in leading whitespace. -You may also run the :mod:`tabnanny` module to check a directory tree +You may also run the :mod:`tabnanny` module to check a directory tree in batch mode. From 760f596b6a4b5514afe35e521621f484aef35413 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 19 Feb 2017 10:03:50 +0530 Subject: [PATCH 014/340] [3.5] bpo-29571: Use correct locale encoding in test_re (#149) (#154) ``local.getlocale(locale.LC_CTYPE)`` and ``locale.getpreferredencoding(False)`` may give different answers in some cases (such as the ``en_IN`` locale). ``re.LOCALE`` uses the latter, so update the test case to match. --- Lib/test/test_re.py | 2 +- Misc/NEWS | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9acd5abbfd7776..407f3468e86671 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1334,7 +1334,7 @@ def test_ascii_and_unicode_flag(self): def test_locale_flag(self): import locale - _, enc = locale.getlocale(locale.LC_CTYPE) + enc = locale.getpreferredencoding(False) # Search non-ASCII letter for i in range(128, 256): try: diff --git a/Misc/NEWS b/Misc/NEWS index fe50135c01615c..c750d5c952e6e9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -87,6 +87,14 @@ Documentation - Issue #29349: Fix Python 2 syntax in code for building the documentation. +Tests +----- + +- Issue #29571: to match the behaviour of the ``re.LOCALE`` flag, + test_re.test_locale_flag now uses ``locale.getpreferredencoding(False)`` to + determine the candidate encoding for the test regex (allowing it to correctly + skip the test when the default locale encoding is a multi-byte encoding) + What's New in Python 3.5.3? =========================== From 24bfe15e83c24bf2c2e2654050da809553789002 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Sun, 19 Feb 2017 14:13:02 +0900 Subject: [PATCH 015/340] [backport to 3.5] bpo-29529: Add .travis.yml to 3.5 branch (#26) * Add .travis.yml to 3.5 branch * Only run CI checks when appropriate files have changed (#74) Closes python/core-workflow#14 * Travis CI: run rstlint.py in the docs job (#68) Currently, http://buildbot.python.org/all/buildslaves/ware-docs buildbot is only run as post-commit. For example, bpo-29521 (PR#41) introduced two warnings, unnotified by the Travis CI docs job. Modify the docs job to run toosl/rstlint.py. Fix also the two minor warnings which causes the buildbot slave to fail. * Use 'make check' instead of 'python3 tools/rstlint.py' (#96) --- .travis.yml | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000000000..dc3a00d1f4b5a3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,104 @@ +language: c +dist: trusty +sudo: false +group: beta + +# To cache doc-building dependencies. +cache: pip + +os: + - linux + # macOS builds are disabled as the machines are under-provisioned on Travis, + # adding up to an extra hour completing a full CI run. + #- osx + +compiler: + - clang + - gcc + +env: + - TESTING=cpython + +matrix: + allow_failures: + - env: + - TESTING=coverage + include: + - os: linux + language: python + python: 3.5 + env: + - TESTING=docs + before_script: + - | + if git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '^Doc/' + then + echo "Docs weren't updated, stopping build process." + exit + fi + cd Doc + make venv PYTHON=python3 + script: + - make html SPHINXBUILD="./venv/bin/python3 -m sphinx" SPHINXOPTS="-q" + - make check + - os: linux + language: c + compiler: clang + env: + - TESTING=coverage + before_script: + - | + if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.(rst|yml)$)|(^Doc)/' + then + echo "Only docs were updated, stopping build process." + exit + fi + ./configure + make -s -j4 + # Need a venv that can parse covered code. + ./python -m venv venv + ./venv/bin/python -m pip install -U coverage + script: + # Skip tests that re-run the entire test suite. + - ./venv/bin/python -m coverage run --pylib -m test -uall -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn + after_script: # Probably should be after_success once test suite updated to run under coverage.py. + # Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files. + - source ./venv/bin/activate + - bash <(curl -s https://codecov.io/bash) + - os: linux + language: cpp + compiler: clang + env: + - TESTING="C++ header compatibility" + before_script: + - ./configure + script: + - echo '#include "Python.h"' > test.cc && $CXX -c test.cc -o /dev/null -I ./Include -I . + +# Travis provides only 2 cores, so don't overdue the parallelism and waste memory. +before_script: + - | + if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.(rst|yml)$)|(^Doc)/' + then + echo "Only docs were updated, stopping build process." + exit + fi + ./configure --with-pydebug + make -j4 + +script: + # `-r -w` implicitly provided through `make buildbottest`. + - make buildbottest TESTOPTS="-j4" + +notifications: + email: false + irc: + channels: + # This is set to a secure variable to prevent forks from notifying the + # IRC channel whenever they fail a build. This can be removed when travis + # implements https://github.com/travis-ci/travis-ci/issues/1094. + # The actual value here is: irc.freenode.net#python-dev + - secure: "s7kAkpcom2yUJ8XqyjFI0obJmhAGrn1xmoivdaPdgBIA++X47TBp1x4pgDsbEsoalef7bEwa4l07KdT4qa+DOd/c4QxaWom7fbN3BuLVsZuVfODnl79+gYq/TAbGfyH+yDs18DXrUfPgwD7C5aW32ugsqAOd4iWzfGJQ5OrOZzqzGjYdYQUEkJFXgxDEIb4aHvxNDWGO3Po9uKISrhb5saQ0l776yLo1Ur7M4oxl8RTbCdgX0vf5TzPg52BgvZpOgt3DHOUYPeiJLKNjAE6ibg0U95sEvMfHX77nz4aFY4/3UI6FFaRla34rZ+mYKrn0TdxOhera1QOgPmM6HzdO4K44FpfK1DS0Xxk9U9/uApq+cG0bU3W+cVUHDBe5+90lpRBAXHeHCgT7TI8gec614aiT8lEr3+yH8OBRYGzkjNK8E2LJZ/SxnVxDe7aLF6AWcoWLfS6/ziAIBFQ5Nc4U72CT8fGVSkl8ywPiRlvixKdvTODMSZo0jMqlfZSNaAPTsNRx4wu5Uis4qekwe32Fz4aB6KGpsuuVjBi+H6v0RKxNJNGY3JKDiEH2TK0UE2auJ5GvLW48aUVFcQMB7euCWYXlSWVRHh3WLU8QXF29Dw4JduRZqUpOdRgMHU79UHRq+mkE0jAS/nBcS6CvsmxCpTSrfVYuMOu32yt18QQoTyU=" + on_success: change + on_failure: always + skip_join: true From f0174c69b7b8bd27ee32d96e890d665da29472af Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Mon, 20 Feb 2017 09:46:24 +0900 Subject: [PATCH 016/340] bpo-29520: doc: fix deprecation warning from 'defindex' template (GH-179) --- Doc/tools/templates/indexcontent.html | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Doc/tools/templates/indexcontent.html b/Doc/tools/templates/indexcontent.html index 1076c1f51b7d19..d795c0a5586bc8 100644 --- a/Doc/tools/templates/indexcontent.html +++ b/Doc/tools/templates/indexcontent.html @@ -1,5 +1,12 @@ -{% extends "defindex.html" %} -{% block tables %} +{% extends "layout.html" %} +{%- block htmltitle -%} +{{ shorttitle }} +{%- endblock -%} +{% block body %} +

{{ docstitle|e }}

+

+ {% trans %}Welcome! This is the documentation for Python {{ release }}.{% endtrans %} +

{% trans %}Parts of the documentation:{% endtrans %}

From 314a86bae2ecc5e22bc874ad8a1bb71eb732dda6 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 19 Feb 2017 18:58:20 -0800 Subject: [PATCH 017/340] Change some mercurial/ hg.python.org references. (#8) (#184) (cherry picked from commit b2ee40ed9c9041dcff9c898aa19aacf9ec60308a) --- Doc/faq/general.rst | 6 +++--- Lib/idlelib/help.html | 2 +- Tools/README | 2 +- Tools/importbench/README | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/faq/general.rst b/Doc/faq/general.rst index f1e33afdabf8a5..8f6a907a8a2fda 100644 --- a/Doc/faq/general.rst +++ b/Doc/faq/general.rst @@ -159,7 +159,7 @@ How do I obtain a copy of the Python source? The latest Python source distribution is always available from python.org, at https://www.python.org/downloads/. The latest development sources can be obtained -via anonymous Mercurial access at https://hg.python.org/cpython. +at https://github.com/python/cpython/. The source distribution is a gzipped tar file containing the complete C source, Sphinx-formatted documentation, Python library modules, example programs, and @@ -222,8 +222,8 @@ releases are announced on the comp.lang.python and comp.lang.python.announce newsgroups and on the Python home page at https://www.python.org/; an RSS feed of news is available. -You can also access the development version of Python through Mercurial. See -https://docs.python.org/devguide/faq.html for details. +You can also access the development version of Python through Git. See +`The Python Developer's Guide `_ for details. How do I submit bug reports and patches for Python? diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index ffc03c4112f073..f10cd345e886c8 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -90,7 +90,7 @@

Navigation

25.5. IDLE

-

Source code: Lib/idlelib/

+

Source code: Lib/idlelib/


IDLE is Python’s Integrated Development and Learning Environment.

IDLE has the following features:

diff --git a/Tools/README b/Tools/README index 0d961de23d6cb8..edbf4fb83321ba 100644 --- a/Tools/README +++ b/Tools/README @@ -45,4 +45,4 @@ unittestgui A Tkinter based GUI test runner for unittest, with test discovery. -(*) A generic benchmark suite is maintained separately at http://hg.python.org/benchmarks/ +(*) A generic benchmark suite is maintained separately at https://github.com/python/performance diff --git a/Tools/importbench/README b/Tools/importbench/README index 81a5544a383b4c..6ba386c2b608d5 100644 --- a/Tools/importbench/README +++ b/Tools/importbench/README @@ -3,4 +3,4 @@ Importbench is a set of micro-benchmarks for various import scenarios. It should not be used as an overall benchmark of import performance, but rather an easy way to measure impact of possible code changes. For a real-world benchmark of import, use the normal_startup benchmark from -hg.python.org/benchmarks. +https://github.com/python/performance From 7c95a94c3ab41e4296e94335d66b2400ad16f052 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 20 Feb 2017 14:33:06 +0800 Subject: [PATCH 018/340] bpo-29347: Fix possibly dereferencing undefined pointers when creating weakref objects (#128) (#188) --- Misc/NEWS | 3 +++ Objects/weakrefobject.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index c750d5c952e6e9..52c87d88c72664 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-29347: Fixed possibly dereferencing undefined pointers + when creating weakref objects. + - bpo-29438: Fixed use-after-free problem in key sharing dict. - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0]. diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index 7e6f36458bc693..892798affe9fe2 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -24,6 +24,8 @@ init_weakref(PyWeakReference *self, PyObject *ob, PyObject *callback) { self->hash = -1; self->wr_object = ob; + self->wr_prev = NULL; + self->wr_next = NULL; Py_XINCREF(callback); self->wr_callback = callback; } From 66fa9d4205e0da672ed19a397069281a4b177af4 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Mon, 20 Feb 2017 20:29:30 +0900 Subject: [PATCH 019/340] bpo-24274: fix comment in dictobject.c (GH-194) --- Objects/dictobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 7299f36b2bf88c..e277ab87e7bfae 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -429,7 +429,7 @@ Christian Tismer. lookdict() is general-purpose, and may return NULL if (and only if) a comparison raises an exception (this was new in Python 2.5). lookdict_unicode() below is specialized to string keys, comparison of which can -never raise an exception; that function can never return NULL. +never raise an exception; that function must not return NULL for string key. lookdict_unicode_nodummy is further specialized for string keys that cannot be the value. For both, when the key isn't found a PyDictEntry* is returned From 0936a00fe035e3e52c30bcbc59668dc0f519ced6 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Mon, 20 Feb 2017 21:50:49 +0000 Subject: [PATCH 020/340] bpo-29602: fix signed zero handling in complex constructor. (#203) (#205) * Fix incorrect handling of signed zeros for complex-related classes. * Add Misc/NEWS entry. (cherry picked from commit 112ec38c15b388fe025ccb85369a584d218b1160) --- Lib/test/test_complex.py | 23 +++++++++++++++++++++++ Misc/NEWS | 4 ++++ Objects/complexobject.c | 6 +++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_complex.py b/Lib/test/test_complex.py index 403ee3bc580f0a..8d551a4fc54c05 100644 --- a/Lib/test/test_complex.py +++ b/Lib/test/test_complex.py @@ -385,6 +385,29 @@ def __complex__(self): self.assertAlmostEqual(complex(complex1(1j)), 2j) self.assertRaises(TypeError, complex, complex2(1j)) + @support.requires_IEEE_754 + def test_constructor_special_numbers(self): + class complex2(complex): + pass + for x in 0.0, -0.0, INF, -INF, NAN: + for y in 0.0, -0.0, INF, -INF, NAN: + with self.subTest(x=x, y=y): + z = complex(x, y) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(x, y) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex(complex2(x, y)) + self.assertIs(type(z), complex) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + z = complex2(complex(x, y)) + self.assertIs(type(z), complex2) + self.assertFloatsAreIdentical(z.real, x) + self.assertFloatsAreIdentical(z.imag, y) + def test_hash(self): for x in range(-30, 30): self.assertEqual(hash(x), hash(complex(x, 0))) diff --git a/Misc/NEWS b/Misc/NEWS index 52c87d88c72664..038233735f6c13 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-29602: Fix incorrect handling of signed zeros in complex constructor for + complex subclasses and for inputs having a __complex__ method. Patch + by Serhiy Storchaka. + - bpo-29347: Fixed possibly dereferencing undefined pointers when creating weakref objects. diff --git a/Objects/complexobject.c b/Objects/complexobject.c index d82c5eb9f1ea44..606c1011f4d5c2 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1014,11 +1014,11 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } cr.real = PyFloat_AsDouble(tmp); - cr.imag = 0.0; /* Shut up compiler warning */ + cr.imag = 0.0; Py_DECREF(tmp); } if (i == NULL) { - ci.real = 0.0; + ci.real = cr.imag; } else if (PyComplex_Check(i)) { ci = ((PyComplexObject*)i)->cval; @@ -1040,7 +1040,7 @@ complex_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (ci_is_complex) { cr.real -= ci.imag; } - if (cr_is_complex) { + if (cr_is_complex && i != NULL) { ci.real += cr.imag; } return complex_subtype_from_doubles(type, cr.real, ci.real); From 9ab8eaf965cc75dfd6dbb195c77f9d2c1f33505f Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Tue, 21 Feb 2017 23:55:49 +0900 Subject: [PATCH 021/340] doc: fix compile error on "shoddy" example extension (GH-217) (cherry picked from commit fb8fe72fc593438f6a0b934c6ff2d9c4aa28673d) --- Doc/includes/setup.py | 1 + Doc/includes/shoddy.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/includes/setup.py b/Doc/includes/setup.py index b853d23b170985..a38a39de3e7c86 100644 --- a/Doc/includes/setup.py +++ b/Doc/includes/setup.py @@ -5,4 +5,5 @@ Extension("noddy2", ["noddy2.c"]), Extension("noddy3", ["noddy3.c"]), Extension("noddy4", ["noddy4.c"]), + Extension("shoddy", ["shoddy.c"]), ]) diff --git a/Doc/includes/shoddy.c b/Doc/includes/shoddy.c index 07a272124ceaba..0c6d412b3c4cda 100644 --- a/Doc/includes/shoddy.c +++ b/Doc/includes/shoddy.c @@ -31,7 +31,7 @@ Shoddy_init(Shoddy *self, PyObject *args, PyObject *kwds) static PyTypeObject ShoddyType = { - PyObject_HEAD_INIT(NULL) + PyVarObject_HEAD_INIT(NULL, 0) "shoddy.Shoddy", /* tp_name */ sizeof(Shoddy), /* tp_basicsize */ 0, /* tp_itemsize */ From 6336f0d156feec0f109a8d01da108cf96e3d9c60 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Wed, 22 Feb 2017 04:55:03 +0300 Subject: [PATCH 022/340] bpo-29554: Improve docs for pstat module and profile. (#88) (#228) Clarify that methods take a string which is interpreted as a regex, not a regex object. Also clarify what the old `-1`, `0`, `1` and `2` options were. (cherry picked from commit 8fb1f6e039cbdeb333d83b7a62f0f37af4ce6e02) --- Doc/library/profile.rst | 7 ++++--- Lib/pstats.py | 13 ++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index 959d9b98a84691..bd67fe486abf77 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -444,9 +444,10 @@ Analysis of the profiler data is done using the :class:`~pstats.Stats` class. significant entries. Initially, the list is taken to be the complete set of profiled functions. Each restriction is either an integer (to select a count of lines), or a decimal fraction between 0.0 and 1.0 inclusive (to - select a percentage of lines), or a regular expression (to pattern match - the standard name that is printed. If several restrictions are provided, - then they are applied sequentially. For example:: + select a percentage of lines), or a string that will interpreted as a + regular expression (to pattern match the standard name that is printed). + If several restrictions are provided, then they are applied sequentially. + For example:: print_stats(.1, 'foo:') diff --git a/Lib/pstats.py b/Lib/pstats.py index d861413d4195f7..2c5bf981b85cf8 100644 --- a/Lib/pstats.py +++ b/Lib/pstats.py @@ -48,11 +48,14 @@ class Stats: printed. The sort_stats() method now processes some additional options (i.e., in - addition to the old -1, 0, 1, or 2). It takes an arbitrary number of - quoted strings to select the sort order. For example sort_stats('time', - 'name') sorts on the major key of 'internal function time', and on the - minor key of 'the name of the function'. Look at the two tables in - sort_stats() and get_sort_arg_defs(self) for more examples. + addition to the old -1, 0, 1, or 2 that are respectively interpreted as + 'stdname', 'calls', 'time', and 'cumulative'). It takes an arbitrary number + of quoted strings to select the sort order. + + For example sort_stats('time', 'name') sorts on the major key of 'internal + function time', and on the minor key of 'the name of the function'. Look at + the two tables in sort_stats() and get_sort_arg_defs(self) for more + examples. All methods return self, so you can string together commands like: Stats('foo', 'goo').strip_dirs().sort_stats('calls').\ From f802facf5605b0b88e3735456442a74055c2431b Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Wed, 22 Feb 2017 08:02:17 +0300 Subject: [PATCH 023/340] Add .codecov.yml (#210) (#229) (cherry picked from commit e9c0e5559bbadb164d7c57b5a47b5544746dcb89) --- .codecov.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .codecov.yml diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 00000000000000..fcf9df6a7a698e --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,35 @@ +codecov: + notify: + require_ci_to_pass: true +comment: off +ignore: + - "Doc/**/*" + - "Misc/*" + - "Mac/**/*" + - "PC/**/*" + - "PCbuild/**/*" + - "Tools/**/*" + - "Grammar/*" +coverage: + precision: 2 + range: + - 70.0 + - 100.0 + round: down + status: + changes: off + project: off + patch: + default: + target: 100% + only_pulls: true + threshold: 0.05 +parsers: + gcov: + branch_detection: + conditional: true + loop: true + macro: false + method: false + javascript: + enable_partials: false From 8fa7e22134ac9626b2188ff877f6aeecd3c9e618 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Wed, 22 Feb 2017 06:19:55 +0000 Subject: [PATCH 024/340] Fixed bpo-29565: Corrected ctypes passing of large structs by value on Windows AMD64. (#168) (#221) Fixed bpo-29565: Corrected ctypes passing of large structs by value. (cherry picked from commit a86339b83fbd0932e0529a3c91935e997a234582) --- Lib/ctypes/test/test_callbacks.py | 11 +++++++++++ Lib/ctypes/test/test_structures.py | 23 +++++++++++++++++++++++ Modules/_ctypes/_ctypes_test.c | 13 +++++++++++++ Modules/_ctypes/libffi_msvc/ffi.c | 10 ++++++++++ 4 files changed, 57 insertions(+) diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index 8eac58f0262caf..f622093df61da5 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -244,6 +244,7 @@ def callback(a, b, c, d, e): def test_callback_large_struct(self): class Check: pass + # This should mirror the structure in Modules/_ctypes/_ctypes_test.c class X(Structure): _fields_ = [ ('first', c_ulong), @@ -255,6 +256,11 @@ def callback(check, s): check.first = s.first check.second = s.second check.third = s.third + # See issue #29565. + # The structure should be passed by value, so + # any changes to it should not be reflected in + # the value passed + s.first = s.second = s.third = 0x0badf00d check = Check() s = X() @@ -275,6 +281,11 @@ def callback(check, s): self.assertEqual(check.first, 0xdeadbeef) self.assertEqual(check.second, 0xcafebabe) self.assertEqual(check.third, 0x0bad1dea) + # See issue #29565. + # Ensure that the original struct is unchanged. + self.assertEqual(s.first, check.first) + self.assertEqual(s.second, check.second) + self.assertEqual(s.third, check.third) ################################################################ diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index c4a651c9666d7c..0b9391a4dbb5a7 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -3,6 +3,7 @@ from ctypes.test import need_symbol from struct import calcsize import _testcapi +import _ctypes_test class SubclassesTest(unittest.TestCase): def test_subclass(self): @@ -394,6 +395,28 @@ class Z(Y): (1, 0, 0, 0, 0, 0)) self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7)) + def test_pass_by_value(self): + # This should mirror the structure in Modules/_ctypes/_ctypes_test.c + class X(Structure): + _fields_ = [ + ('first', c_ulong), + ('second', c_ulong), + ('third', c_ulong), + ] + + s = X() + s.first = 0xdeadbeef + s.second = 0xcafebabe + s.third = 0x0bad1dea + dll = CDLL(_ctypes_test.__file__) + func = dll._testfunc_large_struct_update_value + func.argtypes = (X,) + func.restype = None + func(s) + self.assertEqual(s.first, 0xdeadbeef) + self.assertEqual(s.second, 0xcafebabe) + self.assertEqual(s.third, 0x0bad1dea) + class PointerMemberTestCase(unittest.TestCase): def test(self): diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 3c7f89249a92b4..20e65d2c1aef2b 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -44,6 +44,19 @@ _testfunc_cbk_large_struct(Test in, void (*func)(Test)) func(in); } +/* + * See issue 29565. Update a structure passed by value; + * the caller should not see any change. + */ + +EXPORT(void) +_testfunc_large_struct_update_value(Test in) +{ + in.first = 0x0badf00d; + in.second = 0x0badf00d; + in.third = 0x0badf00d; +} + EXPORT(void)testfunc_array(int values[4]) { printf("testfunc_array %d %d %d %d\n", diff --git a/Modules/_ctypes/libffi_msvc/ffi.c b/Modules/_ctypes/libffi_msvc/ffi.c index 1d82929f530220..91a27dce3f2575 100644 --- a/Modules/_ctypes/libffi_msvc/ffi.c +++ b/Modules/_ctypes/libffi_msvc/ffi.c @@ -239,6 +239,16 @@ ffi_call(/*@dependent@*/ ffi_cif *cif, break; #else case FFI_SYSV: + /* If a single argument takes more than 8 bytes, + then a copy is passed by reference. */ + for (unsigned i = 0; i < cif->nargs; i++) { + size_t z = cif->arg_types[i]->size; + if (z > 8) { + void *temp = alloca(z); + memcpy(temp, avalue[i], z); + avalue[i] = temp; + } + } /*@-usedef@*/ return ffi_call_AMD64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); From 5010a77a4da76d8d3fd861a63a7f1ce8f0e9c520 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 22 Feb 2017 11:46:32 +0200 Subject: [PATCH 025/340] [3.5] bpo-29532: Altering a kwarg dictionary passed to functools.partial() no longer affects a partial object after creation. (#222) --- Lib/test/test_functools.py | 9 +++++++++ Misc/NEWS | 3 +++ Modules/_functoolsmodule.c | 5 ++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 9ccd0cafc489cf..a82ca7ab88c38f 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -80,6 +80,15 @@ def func(a=10, b=20): p(b=7) self.assertEqual(d, {'a':3}) + def test_kwargs_copy(self): + # Issue #29532: Altering a kwarg dictionary passed to a constructor + # should not affect a partial object after creation + d = {'a': 3} + p = self.partial(capture, **d) + self.assertEqual(p(), ((), {'a': 3})) + d['a'] = 5 + self.assertEqual(p(), ((), {'a': 3})) + def test_arg_combinations(self): # exercise special code paths for zero args in either partial # object or the caller diff --git a/Misc/NEWS b/Misc/NEWS index 038233735f6c13..a01d454ab78f7d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,9 @@ Extension Modules Library ------- +- bpo-29532: Altering a kwarg dictionary passed to functools.partial() + no longer affects a partial object after creation. + - Issue #28556: Various updates to typing module: typing.Counter, typing.ChainMap, improved ABC caching, etc. Original PRs by Jelle Zijlstra, Ivan Levkivskyi, Manuel Krebber, and Łukasz Langa. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index be0f5f9e652abc..0471d665e65a58 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -88,10 +88,13 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw) if (kw == NULL) { pto->kw = PyDict_New(); } - else { + else if (Py_REFCNT(kw) == 1) { Py_INCREF(kw); pto->kw = kw; } + else { + pto->kw = PyDict_Copy(kw); + } } else { pto->kw = PyDict_Copy(pkw); From 0246422b974b1a0c50dd30b0e1a1138674ef87a5 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 23 Feb 2017 18:45:57 +0300 Subject: [PATCH 026/340] bpo-28814: Undeprecate inadvertently deprecated inspect functions. (#122) (#244) Nick Coghlan said on bpo-28814: > inspect.getargvalues() and inspect.formatargvalues() were deprecated > in Python 3.5 as part of implementing bpo-20438 > This is incorrect, as these are *frame* introspection related functions, > not callable introspection ones. The documentation and implementation > layout is confusing though, as they're interleaved with the callable > introspection operation This commit undeprecates these functions and adds a note to ignore previous deprecation notices. (cherry picked from commit 0899b9809547ec2894dcf88cf4bba732c5d47d0d) --- Doc/library/inspect.rst | 12 ++++-------- Doc/whatsnew/3.5.rst | 11 ++++++----- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 62a3988ae02ea7..89263e7bec1795 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -875,10 +875,8 @@ Classes and functions are the names of the ``*`` and ``**`` arguments or ``None``. *locals* is the locals dictionary of the given frame. - .. deprecated:: 3.5 - Use :func:`signature` and - :ref:`Signature Object `, which provide a - better introspecting API for callables. + .. note:: + This function was inadvertently marked as deprecated in Python 3.5. .. function:: formatargspec(args[, varargs, varkw, defaults, kwonlyargs, kwonlydefaults, annotations[, formatarg, formatvarargs, formatvarkw, formatvalue, formatreturns, formatannotations]]) @@ -914,10 +912,8 @@ Classes and functions :func:`getargvalues`. The format\* arguments are the corresponding optional formatting functions that are called to turn names and values into strings. - .. deprecated:: 3.5 - Use :func:`signature` and - :ref:`Signature Object `, which provide a - better introspecting API for callables. + .. note:: + This function was inadvertently marked as deprecated in Python 3.5. .. function:: getmro(cls) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst index ab61d7a6d41256..39b6ee59ebdfa5 100644 --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2327,11 +2327,12 @@ The :func:`inspect.getargspec` function is deprecated and scheduled to be removed in Python 3.6. (See :issue:`20438` for details.) The :mod:`inspect` :func:`~inspect.getfullargspec`, -:func:`~inspect.getargvalues`, :func:`~inspect.getcallargs`, -:func:`~inspect.getargvalues`, :func:`~inspect.formatargspec`, and -:func:`~inspect.formatargvalues` functions are deprecated in favor of -the :func:`inspect.signature` API. -(Contributed by Yury Selivanov in :issue:`20438`.) +:func:`~inspect.getcallargs`, and :func:`~inspect.formatargspec` functions are +deprecated in favor of the :func:`inspect.signature` API. (Contributed by Yury +Selivanov in :issue:`20438`.) + +:func:`~inspect.getargvalues` and :func:`~inspect.formatargvalues` functions +were inadvertently marked as deprecated with the release of Python 3.5.0. Use of :const:`re.LOCALE` flag with str patterns or :const:`re.ASCII` is now deprecated. (Contributed by Serhiy Storchaka in :issue:`22407`.) From fa30453568ae71861aa1928373bd76da4f3a33f6 Mon Sep 17 00:00:00 2001 From: Arne de Laat Date: Thu, 23 Feb 2017 17:16:56 +0100 Subject: [PATCH 027/340] bpo-28911: Clarify the behaviour of assert_called_once_with. (#254) (cherry picked from commit 9d56b34af2efc4e266bf3ae62da5cd2e422a42be) --- Doc/library/unittest.mock.rst | 11 ++++++----- Lib/unittest/mock.py | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index 4b9dac402f9619..1169f0b5d3de66 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -275,14 +275,14 @@ the *new_callable* argument to :func:`patch`. .. method:: assert_called_once_with(*args, **kwargs) - Assert that the mock was called exactly once and with the specified - arguments. + Assert that the mock was called exactly once and that that call was + with the specified arguments. >>> mock = Mock(return_value=None) >>> mock('foo', bar='baz') >>> mock.assert_called_once_with('foo', bar='baz') - >>> mock('foo', bar='baz') - >>> mock.assert_called_once_with('foo', bar='baz') + >>> mock('other', bar='values') + >>> mock.assert_called_once_with('other', bar='values') Traceback (most recent call last): ... AssertionError: Expected 'mock' to be called once. Called 2 times. @@ -294,7 +294,8 @@ the *new_callable* argument to :func:`patch`. The assert passes if the mock has *ever* been called, unlike :meth:`assert_called_with` and :meth:`assert_called_once_with` that - only pass if the call is the most recent one. + only pass if the call is the most recent one, and in the case of + :meth:`assert_called_once_with` it must also be the only call. >>> mock = Mock(return_value=None) >>> mock(1, 2, arg='thing') diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 0512cca4e29ba4..9bc40bc2d15403 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -795,8 +795,8 @@ def _error_message(): def assert_called_once_with(_mock_self, *args, **kwargs): - """assert that the mock was called exactly once and with the specified - arguments.""" + """assert that the mock was called exactly once and that that call was + with the specified arguments.""" self = _mock_self if not self.call_count == 1: msg = ("Expected '%s' to be called once. Called %s times." % From e29741466df0cd01a49bf5ec3b1df3e2bad119a7 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 23 Feb 2017 15:02:43 -0800 Subject: [PATCH 028/340] bpo-29624: Adds purge step and layout test after uploading files. (#258) (#263) --- Tools/msi/uploadrelease.bat | 31 ++++++++++++++++++++++--------- Tools/msi/uploadrelease.proj | 32 +++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat index 4e319ce4c98ccb..670836be8c1c8b 100644 --- a/Tools/msi/uploadrelease.bat +++ b/Tools/msi/uploadrelease.bat @@ -9,6 +9,8 @@ set USER= set TARGET= set DRYRUN=false set NOGPG= +set PURGE_OPTION=/p:Purge=true +set NOTEST= :CheckOpts if "%1" EQU "-h" goto Help @@ -19,7 +21,11 @@ if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts -if "%1" EQU "--no-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-purge" (set PURGE_OPTION=) && shift && godo CheckOpts +if "%1" EQU "--skip-test" (set NOTEST=true) && shift && godo CheckOpts +if "%1" EQU "-T" (set NOTEST=true) && shift && godo CheckOpts +if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" @@ -35,7 +41,7 @@ echo Found pscp.exe at %PSCP% if defined NOGPG ( set GPG= - echo Skipping GPG signature generation because of --no-gpg + echo Skipping GPG signature generation because of --skip-gpg ) else ( if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" @@ -45,8 +51,12 @@ if defined NOGPG ( call "%PCBUILD%env.bat" > nul 2> nul pushd "%D%" -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% +if not defined NOTEST ( + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 +) msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false popd @@ -55,9 +65,12 @@ exit /B 0 :Help echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] echo. -echo --host (-o) Specify the upload host (required) -echo --user (-u) Specify the user on the host (required) -echo --target (-t) Specify the target directory on the host -echo --dry-run Display commands and filenames without executing them -echo -h Display this help information +echo --host (-o) Specify the upload host (required) +echo --user (-u) Specify the user on the host (required) +echo --target (-t) Specify the target directory on the host +echo --dry-run Display commands and filenames without executing them +echo --skip-gpg Does not generate GPG signatures before uploading +echo --skip-purge Does not perform CDN purge after uploading +echo --skip-test (-T) Does not perform post-upload tests +echo -h Display this help information echo. diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj index 0d472dea5428a0..305e84fc2d4b28 100644 --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -9,6 +9,7 @@ /srv/www.python.org/ftp/python true false + false @@ -64,7 +65,36 @@ echo. echo." /> - + + + + + + + + + + $(TEMP)\%(Filename)_source + $(TEMP)\%(Filename)_source\%(Filename)%(Extension) + $(TEMP)\%(Filename)_layout + $(OutputPath)\%(Filename)_layoutlog + $(OutputPath)\%(Filename)_layoutlog\%(Filename).log + + + + + + + + + + + + + + + From 66b5092fac4264efdc9c508a7dd425fa9833e147 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Fri, 24 Feb 2017 16:15:17 -0500 Subject: [PATCH 029/340] bpo-25008: Deprecate smtpd and point to aiosmtpd (#274) (#279) --- Doc/library/smtpd.rst | 6 ++++++ Misc/NEWS | 3 +++ 2 files changed, 9 insertions(+) diff --git a/Doc/library/smtpd.rst b/Doc/library/smtpd.rst index a096de006ee72a..4d5a0cebf6ea76 100644 --- a/Doc/library/smtpd.rst +++ b/Doc/library/smtpd.rst @@ -13,6 +13,12 @@ This module offers several classes to implement SMTP (email) servers. +.. seealso:: + + The `aiosmtpd `_ package is a recommended + replacement for this module. It is based on :mod:`asyncio` and provides a + more straightforward API. :mod:`smtpd` should be considered deprecated. + Several server implementations are present; one is a generic do-nothing implementation, which can be overridden, while the other two offer specific mail-sending strategies. diff --git a/Misc/NEWS b/Misc/NEWS index a01d454ab78f7d..e680b90ca8979e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -92,6 +92,9 @@ C API Documentation ------------- +- bpo-25008: Document smtpd.py as effectively deprecated and add a pointer to + aiosmtpd, a third-party asyncio-based replacement. + - Issue #26355: Add canonical header link on each page to corresponding major version of the documentation. Patch by Matthias Bussonnier. From bc33cd4e7a36ed4c309807ca9a911ef955582710 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 24 Feb 2017 16:41:19 -0800 Subject: [PATCH 030/340] [3.5] bpo-28556: Update to typing: treat subscripted generics as proxies (GH-265) (GH-269) (cherry picked from commit abb3b8ad94d699c8560d94ee9bac9c917b382abe) (cherry picked from commit 365cb5bb9069273e6970c9d5d17ee2fe5003e7ac) --- Lib/test/test_typing.py | 35 +++++++++++++++++++++++++++++++++++ Lib/typing.py | 10 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 64d8276658ee7f..f0070ec975791a 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -674,6 +674,41 @@ class C(B[int]): c.bar = 'abc' self.assertEqual(c.__dict__, {'bar': 'abc'}) + def test_subscripted_generics_as_proxies(self): + T = TypeVar('T') + class C(Generic[T]): + x = 'def' + self.assertEqual(C[int].x, 'def') + self.assertEqual(C[C[int]].x, 'def') + C[C[int]].x = 'changed' + self.assertEqual(C.x, 'changed') + self.assertEqual(C[str].x, 'changed') + C[List[str]].z = 'new' + self.assertEqual(C.z, 'new') + self.assertEqual(C[Tuple[int]].z, 'new') + + self.assertEqual(C().x, 'changed') + self.assertEqual(C[Tuple[str]]().z, 'new') + + class D(C[T]): + pass + self.assertEqual(D[int].x, 'changed') + self.assertEqual(D.z, 'new') + D.z = 'from derived z' + D[int].x = 'from derived x' + self.assertEqual(C.x, 'changed') + self.assertEqual(C[int].z, 'new') + self.assertEqual(D.x, 'from derived x') + self.assertEqual(D[str].z, 'from derived z') + + def test_abc_registry_kept(self): + T = TypeVar('T') + class C(Generic[T]): ... + C.register(int) + self.assertIsInstance(1, C) + C[int] + self.assertIsInstance(1, C) + def test_false_subclasses(self): class MyMapping(MutableMapping[str, str]): pass self.assertNotIsInstance({}, MyMapping) diff --git a/Lib/typing.py b/Lib/typing.py index efe358faf20988..9a0f49099a3114 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1158,6 +1158,16 @@ def __copy__(self): self.__parameters__, self.__args__, self.__origin__, self.__extra__, self.__orig_bases__) + def __setattr__(self, attr, value): + # We consider all the subscripted genrics as proxies for original class + if ( + attr.startswith('__') and attr.endswith('__') or + attr.startswith('_abc_') + ): + super(GenericMeta, self).__setattr__(attr, value) + else: + super(GenericMeta, _gorg(self)).__setattr__(attr, value) + # Prevent checks for Generic to crash when defining Generic. Generic = None From 5023686f7ee69e9da07cda4b7da6691f19892111 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 25 Feb 2017 22:33:51 -0800 Subject: [PATCH 031/340] [3.5] bpo-28929: Add to Misc/NEWS (GH-285) mention bpo-28929 in the Documentation section of What's New in Python 3.5.4 release candidate 1 --- Misc/NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Misc/NEWS b/Misc/NEWS index e680b90ca8979e..abd4e53ef449ca 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -92,6 +92,8 @@ C API Documentation ------------- +- bpo-28929: Link the documentation to its source file on GitHub. + - bpo-25008: Document smtpd.py as effectively deprecated and add a pointer to aiosmtpd, a third-party asyncio-based replacement. From 4c784632f7cb5ede6df4b1b20cdfae155069a81b Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 25 Feb 2017 22:35:39 -0800 Subject: [PATCH 032/340] [3.5] Fix small typos in introduction and datastructures of tutorial (GH-272) (GH-299) (cherry picked from commit 5bd5b9d81322d2cb6edd5f3804a347f8b2e65a15) (cherry picked from commit 8c5e190d360b9f1a08c9fff249ae80d9c18007d5) (cherry picked from commit 53c1892dc3de1de612b1cf95dc7bf09f82c1babf) --- Doc/tutorial/datastructures.rst | 59 +++++++++++++++++---------------- Doc/tutorial/introduction.rst | 2 +- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index b39bdf4dfb288b..6140ece046b975 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -22,11 +22,11 @@ objects: Add an item to the end of the list. Equivalent to ``a[len(a):] = [x]``. -.. method:: list.extend(L) +.. method:: list.extend(iterable) :noindex: - Extend the list by appending all the items in the given list. Equivalent to - ``a[len(a):] = L``. + Extend the list by appending all the items from the iterable. Equivalent to + ``a[len(a):] = iterable``. .. method:: list.insert(i, x) @@ -60,11 +60,16 @@ objects: Remove all items from the list. Equivalent to ``del a[:]``. -.. method:: list.index(x) +.. method:: list.index(x[, start[, end]]) :noindex: - Return the index in the list of the first item whose value is *x*. It is an - error if there is no such item. + Return zero-based index in the list of the first item whose value is *x*. + Raises a :exc:`ValueError` if there is no such item. + + The optional arguments *start* and *end* are interpreted as in the slice + notation and are used to limit the search to a particular subsequence of + the list. The returned index is computed relative to the beginning of the full + sequence rather than the *start* argument. .. method:: list.count(x) @@ -94,28 +99,26 @@ objects: An example that uses most of the list methods:: - >>> a = [66.25, 333, 333, 1, 1234.5] - >>> print(a.count(333), a.count(66.25), a.count('x')) - 2 1 0 - >>> a.insert(2, -1) - >>> a.append(333) - >>> a - [66.25, 333, -1, 333, 1, 1234.5, 333] - >>> a.index(333) - 1 - >>> a.remove(333) - >>> a - [66.25, -1, 333, 1, 1234.5, 333] - >>> a.reverse() - >>> a - [333, 1234.5, 1, 333, -1, 66.25] - >>> a.sort() - >>> a - [-1, 1, 66.25, 333, 333, 1234.5] - >>> a.pop() - 1234.5 - >>> a - [-1, 1, 66.25, 333, 333] + >>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana'] + >>> fruits.count('apple') + 2 + >>> fruits.count('tangerine') + 0 + >>> fruits.index('banana') + 3 + >>> fruits.index('banana', 4) # Find next banana starting a position 4 + 6 + >>> fruits.reverse() + >>> fruits + ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange'] + >>> fruits.append('grape') + >>> fruits + ['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape'] + >>> fruits.sort() + >>> fruits + ['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear'] + >>> fruits.pop() + 'pear' You might have noticed that methods like ``insert``, ``remove`` or ``sort`` that only modify the list have no return value printed -- they return the default diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index 214032917b477d..af277cec19bb7f 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -356,7 +356,7 @@ The built-in function :func:`len` returns the length of a string:: Information about string formatting with :meth:`str.format`. :ref:`old-string-formatting` - The old formatting operations invoked when strings and Unicode strings are + The old formatting operations invoked when strings are the left operand of the ``%`` operator are described in more detail here. From 6b585fddc9ad472d8c962aba26cf25809451b2b5 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 26 Feb 2017 16:06:11 +0300 Subject: [PATCH 033/340] Fix unittest.mock._Call: don't ignore name (#307) Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter anymore. Patch written by Jiajun Huang. (cherry picked from commits 84b6fb0eea29b3b28a1a11124526b01ec0c9d17a and dea1536fd3a8424d537794cd53715df0989cbbe1) Conflicts: Misc/NEWS --- Lib/unittest/mock.py | 3 +-- Lib/unittest/test/testmock/testhelpers.py | 5 +++++ Misc/NEWS | 3 +++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 9bc40bc2d15403..99658d47a35610 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1945,9 +1945,8 @@ class _Call(tuple): If the _Call has no name then it will match any name. """ - def __new__(cls, value=(), name=None, parent=None, two=False, + def __new__(cls, value=(), name='', parent=None, two=False, from_kall=True): - name = '' args = () kwargs = {} _len = len(value) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 34776347daa637..d2202a7b4132e9 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -306,6 +306,11 @@ def test_two_args_call(self): other_args = _Call(((1, 2), {'a': 3})) self.assertEqual(args, other_args) + def test_call_with_name(self): + self.assertEqual(_Call((), 'foo')[0], 'foo') + self.assertEqual(_Call((('bar', 'barz'),),)[0], '') + self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '') + class SpecSignatureTest(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS index abd4e53ef449ca..bab13da4342dc4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,9 @@ Extension Modules Library ------- +- Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter + anymore. Patch written by Jiajun Huang. + - bpo-29532: Altering a kwarg dictionary passed to functools.partial() no longer affects a partial object after creation. From 7963bed009c3b1800bfebd0aecad53960edec55c Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 26 Feb 2017 16:07:41 +0300 Subject: [PATCH 034/340] Backport recent .travis.yml changes (#309) Backported changes from master: * b52260d8bf392aa04c48b8c2467a4c034184de86 * 984eef7d6d78e1213d6ea99897343a5059a07c59 * 532519770dea5d353f0b0d718c8881a15c7542df * 91b0e7d0ca7c59df28f6a6fc1e8eb86a3925b76c (cherry picked from commit 05e1a32170dacfa3ffbbd9266c1cb461f96aabdf) --- .travis.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc3a00d1f4b5a3..27b63c6c08b376 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,11 @@ group: beta # To cache doc-building dependencies. cache: pip +branches: + only: + - master + - /^\d\.\d$/ + os: - linux # macOS builds are disabled as the machines are under-provisioned on Travis, @@ -20,6 +25,7 @@ env: - TESTING=cpython matrix: + fast_finish: true allow_failures: - env: - TESTING=coverage @@ -30,17 +36,10 @@ matrix: env: - TESTING=docs before_script: - - | - if git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '^Doc/' - then - echo "Docs weren't updated, stopping build process." - exit - fi - cd Doc - make venv PYTHON=python3 + - cd Doc + - make venv script: - - make html SPHINXBUILD="./venv/bin/python3 -m sphinx" SPHINXOPTS="-q" - - make check + - make check suspicious html PYTHON="./venv/bin/python" SPHINXBUILD="./venv/bin/python -m sphinx" SPHINXOPTS="-q" - os: linux language: c compiler: clang From 63ed9bc94d8df45b16aee9b92f658ebb34aa1012 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 26 Feb 2017 07:40:03 -0800 Subject: [PATCH 035/340] bpo-29648: import.rst: Add reference to create_module() (GH-290) (GH-315) (cherry picked from commit 46ce7599af82a929506baeaaee5c149970440c4c) --- Doc/reference/import.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/import.rst b/Doc/reference/import.rst index 64302b89a84742..a981b873923dab 100644 --- a/Doc/reference/import.rst +++ b/Doc/reference/import.rst @@ -431,7 +431,7 @@ on the module object. If the method returns ``None``, the import machinery will create the new module itself. .. versionadded:: 3.4 - The create_module() method of loaders. + The :meth:`~importlib.abc.Loader.create_module` method of loaders. .. versionchanged:: 3.4 The :meth:`~importlib.abc.Loader.load_module` method was replaced by From 21c697fd1073d6ab59e2ba82ea80bc81b9c4125c Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 26 Feb 2017 07:44:36 -0800 Subject: [PATCH 036/340] bpo-22594: Add a link to the regex module in re documentation (GH-241) (GH-317) (cherry picked from commit ed6795e46f7653e23b862efad240a93453e7df97) --- Doc/library/re.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 1ca621eca6adee..6baac6f53d898c 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -42,6 +42,12 @@ module-level functions and methods on that don't require you to compile a regex object first, but miss some fine-tuning parameters. +.. seealso:: + + The third-party `regex `_ module, + which has an API compatible with the standard library :mod:`re` module, + but offers additional functionality and a more thorough Unicode support. + .. _re-syntax: From b7fb1e25c89a9eb85b95027f4167bc0977687c43 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Mon, 27 Feb 2017 04:35:00 +0900 Subject: [PATCH 037/340] bpo-29110: Fix file object leak in `aifc.open` (GH-311) (cherry picked from commit 03f68b6) (GH-162) (cherry picked from commit 5dc33ee) (GH-293) --- Lib/aifc.py | 37 +++++++++++++++++++++++++------------ Lib/test/test_aifc.py | 18 +++++++++++++++++- Misc/NEWS | 3 +++ 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/Lib/aifc.py b/Lib/aifc.py index 7ebdbeb68c1093..d5764a33d054a7 100644 --- a/Lib/aifc.py +++ b/Lib/aifc.py @@ -294,6 +294,8 @@ class Aifc_read: # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk # _framesize -- size of one frame in the file + _file = None # Set here since __del__ checks it + def initfp(self, file): self._version = 0 self._convert = None @@ -335,9 +337,15 @@ def initfp(self, file): def __init__(self, f): if isinstance(f, str): - f = builtins.open(f, 'rb') - # else, assume it is an open file object already - self.initfp(f) + file_object = builtins.open(f, 'rb') + try: + self.initfp(file_object) + except: + file_object.close() + raise + else: + # assume it is an open file object already + self.initfp(f) def __enter__(self): return self @@ -532,18 +540,23 @@ class Aifc_write: # _datalength -- the size of the audio samples written to the header # _datawritten -- the size of the audio samples actually written + _file = None # Set here since __del__ checks it + def __init__(self, f): if isinstance(f, str): - filename = f - f = builtins.open(f, 'wb') - else: - # else, assume it is an open file object already - filename = '???' - self.initfp(f) - if filename[-5:] == '.aiff': - self._aifc = 0 + file_object = builtins.open(f, 'wb') + try: + self.initfp(file_object) + except: + file_object.close() + raise + + # treat .aiff file extensions as non-compressed audio + if f.endswith('.aiff'): + self._aifc = 0 else: - self._aifc = 1 + # assume it is an open file object already + self.initfp(f) def initfp(self, file): self._file = file diff --git a/Lib/test/test_aifc.py b/Lib/test/test_aifc.py index ab5143787b0d44..eaa24b63a26d68 100644 --- a/Lib/test/test_aifc.py +++ b/Lib/test/test_aifc.py @@ -1,5 +1,6 @@ -from test.support import findfile, TESTFN, unlink +from test.support import check_no_resource_warning, findfile, TESTFN, unlink import unittest +from unittest import mock from test import audiotests from audioop import byteswap import os @@ -150,6 +151,21 @@ def test_skipunknown(self): #This file contains chunk types aifc doesn't recognize. self.f = aifc.open(findfile('Sine-1000Hz-300ms.aif')) + def test_close_opened_files_on_error(self): + non_aifc_file = findfile('pluck-pcm8.wav', subdir='audiodata') + with check_no_resource_warning(self): + with self.assertRaises(aifc.Error): + # Try opening a non-AIFC file, with the expectation that + # `aifc.open` will fail (without raising a ResourceWarning) + self.f = aifc.open(non_aifc_file, 'rb') + + # Aifc_write.initfp() won't raise in normal case. But some errors + # (e.g. MemoryError, KeyboardInterrupt, etc..) can happen. + with mock.patch.object(aifc.Aifc_write, 'initfp', + side_effect=RuntimeError): + with self.assertRaises(RuntimeError): + self.fout = aifc.open(TESTFN, 'wb') + def test_params_added(self): f = self.f = aifc.open(TESTFN, 'wb') f.aiff() diff --git a/Misc/NEWS b/Misc/NEWS index bab13da4342dc4..8a7e1b5cd9c16e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,9 @@ Extension Modules Library ------- +- bpo-29110: Fix file object leak in aifc.open() when file is given as a + filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. + - Issue #28961: Fix unittest.mock._Call helper: don't ignore the name parameter anymore. Patch written by Jiajun Huang. From 8400ae209b5fa3d3bdc39d3876eef13d1ea9a72a Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 27 Feb 2017 11:46:37 +0800 Subject: [PATCH 038/340] bpo-29376: Fix assertion error in threading._DummyThread.is_alive() (GH-329) --- Lib/test/test_threading.py | 3 +++ Lib/threading.py | 4 ++++ Misc/NEWS | 2 ++ 3 files changed, 9 insertions(+) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index b63050982ab694..83a99023d7a8ae 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -170,6 +170,9 @@ def f(mutex): mutex.acquire() self.assertIn(tid, threading._active) self.assertIsInstance(threading._active[tid], threading._DummyThread) + #Issue 29376 + self.assertTrue(threading._active[tid].is_alive()) + self.assertRegex(repr(threading._active[tid]), '_DummyThread') del threading._active[tid] # PyThreadState_SetAsyncExc() is a CPython-only gimmick, not (currently) diff --git a/Lib/threading.py b/Lib/threading.py index 06b7b9b4fac598..c40d3307b2f265 100644 --- a/Lib/threading.py +++ b/Lib/threading.py @@ -1215,6 +1215,10 @@ def __init__(self): def _stop(self): pass + def is_alive(self): + assert not self._is_stopped and self._started.is_set() + return True + def join(self, timeout=None): assert False, "cannot join a dummy thread" diff --git a/Misc/NEWS b/Misc/NEWS index 8a7e1b5cd9c16e..635f413dc74be8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,8 @@ Extension Modules Library ------- +- bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). + - bpo-29110: Fix file object leak in aifc.open() when file is given as a filesystem path and is not in valid AIFF format. Patch by Anthony Zhang. From b945e0784f8b64f9dba41c47844cadf483168a0f Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 27 Feb 2017 06:01:59 -0800 Subject: [PATCH 039/340] Asyncio documentation: remove `self` from method signatures (GH-334) (GH-336) (cherry picked from commit 091b84f23a2ff57e8320ebf6fdf889af39096ab9) --- Doc/library/asyncio-protocol.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index c0342f7f2f3ddc..e0d2b0f0b6e781 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -33,7 +33,7 @@ BaseTransport Base class for transports. - .. method:: close(self) + .. method:: close() Close the transport. If the transport has a buffer for outgoing data, buffered data will be flushed asynchronously. No more data @@ -41,7 +41,7 @@ BaseTransport protocol's :meth:`connection_lost` method will be called with :const:`None` as its argument. - .. method:: is_closing(self) + .. method:: is_closing() Return ``True`` if the transport is closing or is closed. @@ -248,7 +248,7 @@ BaseSubprocessTransport if it hasn't returned, similarly to the :attr:`subprocess.Popen.returncode` attribute. - .. method:: kill(self) + .. method:: kill() Kill the subprocess, as in :meth:`subprocess.Popen.kill`. From bc144f0abff2b36595171377ee847c0266596ab2 Mon Sep 17 00:00:00 2001 From: Martijn Pieters Date: Mon, 27 Feb 2017 16:07:27 +0000 Subject: [PATCH 040/340] bpo-28598: Support __rmod__ for RHS subclasses of str in % string formatting operations (#94) --- Lib/test/test_unicode.py | 9 +++++++++ Misc/NEWS | 3 +++ Python/ceval.c | 12 +++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py index 3136ea1a1bad3e..9dbded2d99c530 100644 --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -1424,6 +1424,15 @@ def test_formatting_huge_precision(self): with self.assertRaises(ValueError): result = format_string % 2.34 + def test_issue28598_strsubclass_rhs(self): + # A subclass of str with an __rmod__ method should be able to hook + # into the % operator + class SubclassedStr(str): + def __rmod__(self, other): + return 'Success, self.__rmod__({!r}) was called'.format(other) + self.assertEqual('lhs %% %r' % SubclassedStr('rhs'), + "Success, self.__rmod__('lhs %% %r') was called") + @support.cpython_only def test_formatting_huge_precision_c_limits(self): from _testcapi import INT_MAX diff --git a/Misc/NEWS b/Misc/NEWS index 635f413dc74be8..fd25a5f325077e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- Issue #28598: Support __rmod__ for subclasses of str being called before + str.__mod__. Patch by Martijn Pieters. + - bpo-29602: Fix incorrect handling of signed zeros in complex constructor for complex subclasses and for inputs having a __complex__ method. Patch by Serhiy Storchaka. diff --git a/Python/ceval.c b/Python/ceval.c index 7b405188d38c66..d3239089284c48 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1545,9 +1545,15 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(BINARY_MODULO) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *res = PyUnicode_CheckExact(dividend) ? - PyUnicode_Format(dividend, divisor) : - PyNumber_Remainder(dividend, divisor); + PyObject *res; + if (PyUnicode_CheckExact(dividend) && ( + !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { + /* fast path; string formatting, but not if the RHS is a str subclass + (see issue28598) */ + res = PyUnicode_Format(dividend, divisor); + } else { + res = PyNumber_Remainder(dividend, divisor); + } Py_DECREF(divisor); Py_DECREF(dividend); SET_TOP(res); From 0dadf56737f591c83d18db5e445960d39448583e Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Mon, 27 Feb 2017 21:25:29 +0300 Subject: [PATCH 041/340] bpo-29655: Fixed possible reference leaks in `import *`. (#301) (#349) Patch by Matthias Bussonnier. (cherry picked from commit 160edb43571311a3785785c1dfa784afc52d87be) --- Python/ceval.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Python/ceval.c b/Python/ceval.c index d3239089284c48..62badebca6502d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2832,13 +2832,16 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) TARGET(IMPORT_STAR) { PyObject *from = POP(), *locals; int err; - if (PyFrame_FastToLocalsWithError(f) < 0) + if (PyFrame_FastToLocalsWithError(f) < 0) { + Py_DECREF(from); goto error; + } locals = f->f_locals; if (locals == NULL) { PyErr_SetString(PyExc_SystemError, "no locals found during 'import *'"); + Py_DECREF(from); goto error; } READ_TIMESTAMP(intr0); From df11ce6460fb13c251a7af9b12cd44cfe6ce7520 Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Wed, 1 Mar 2017 06:13:38 -0500 Subject: [PATCH 042/340] Disable mention-bot for maintenance branches (GH-369) --- .mention-bot | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .mention-bot diff --git a/.mention-bot b/.mention-bot new file mode 100644 index 00000000000000..cb53b993fb1e8a --- /dev/null +++ b/.mention-bot @@ -0,0 +1,3 @@ +{ + "findPotentialReviewers": false +} From 564ace834f23587937b325e3545abe3f17fdbd2a Mon Sep 17 00:00:00 2001 From: Donald Stufft Date: Thu, 2 Mar 2017 12:32:30 -0500 Subject: [PATCH 043/340] bpo-29697: Don't use OpenSSL <1.0.2 fallback on 1.1+ (GH-398) --- Modules/_ssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index a79c3a888666eb..5f7693c2d886f3 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2418,12 +2418,12 @@ _ssl__SSLContext_impl(PyTypeObject *type, int proto_version) #endif -#ifndef OPENSSL_NO_ECDH +#if !defined(OPENSSL_NO_ECDH) && !defined(OPENSSL_VERSION_1_1) /* Allow automatic ECDH curve selection (on OpenSSL 1.0.2+), or use prime256v1 by default. This is Apache mod_ssl's initialization policy, so we should be safe. OpenSSL 1.1 has it enabled by default. */ -#if defined(SSL_CTX_set_ecdh_auto) && !defined(OPENSSL_VERSION_1_1) +#if defined(SSL_CTX_set_ecdh_auto) SSL_CTX_set_ecdh_auto(self->ctx, 1); #else { From 8b73b6198bc0753c5ce6e8f91eb7bddc2bd42a73 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 2 Mar 2017 21:40:57 -0500 Subject: [PATCH 044/340] bpo-29703: asyncio: Fix creating new event loops in child processes. (#411) --- Lib/asyncio/events.py | 8 +++++++- Lib/asyncio/test_utils.py | 5 ++++- Lib/test/test_asyncio/test_events.py | 22 ++++++++++++++++++++++ Misc/NEWS | 3 +++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 28a45fc3cc5aee..7b30b4c84ad9a7 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -11,6 +11,7 @@ import functools import inspect +import os import reprlib import socket import subprocess @@ -611,6 +612,9 @@ def new_event_loop(self): # A TLS for the running event loop, used by _get_running_loop. class _RunningLoop(threading.local): _loop = None + _pid = None + + _running_loop = _RunningLoop() @@ -620,7 +624,8 @@ def _get_running_loop(): This is a low-level function intended to be used by event loops. This function is thread-specific. """ - return _running_loop._loop + if _running_loop._pid == os.getpid(): + return _running_loop._loop def _set_running_loop(loop): @@ -629,6 +634,7 @@ def _set_running_loop(loop): This is a low-level function intended to be used by event loops. This function is thread-specific. """ + _running_loop._pid = os.getpid() _running_loop._loop = loop diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index 9d32822fa9e451..fe90b9c29897f4 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -449,12 +449,15 @@ def new_test_loop(self, gen=None): self.set_event_loop(loop) return loop + def unpatch_get_running_loop(self): + events._get_running_loop = self._get_running_loop + def setUp(self): self._get_running_loop = events._get_running_loop events._get_running_loop = lambda: None def tearDown(self): - events._get_running_loop = self._get_running_loop + self.unpatch_get_running_loop() events.set_event_loop(None) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 28d92a9f4e3eac..802763bd11ff61 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -1,6 +1,7 @@ """Tests for events.py.""" import collections.abc +import concurrent.futures import functools import gc import io @@ -57,6 +58,15 @@ def osx_tiger(): return version < (10, 5) +def _test_get_event_loop_new_process__sub_proc(): + async def doit(): + return 'hello' + + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) + return loop.run_until_complete(doit()) + + ONLYCERT = data_file('ssl_cert.pem') ONLYKEY = data_file('ssl_key.pem') SIGNED_CERTFILE = data_file('keycert3.pem') @@ -2181,6 +2191,18 @@ def tearDown(self): asyncio.set_child_watcher(None) super().tearDown() + def test_get_event_loop_new_process(self): + async def main(): + pool = concurrent.futures.ProcessPoolExecutor() + return await self.loop.run_in_executor( + pool, _test_get_event_loop_new_process__sub_proc) + + self.unpatch_get_running_loop() + + self.assertEqual( + self.loop.run_until_complete(main()), + 'hello') + if hasattr(selectors, 'KqueueSelector'): class KqueueEventLoopTests(UnixEventLoopTestsMixin, SubprocessTestsMixin, diff --git a/Misc/NEWS b/Misc/NEWS index fd25a5f325077e..32741ce1e7d958 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -35,6 +35,9 @@ Extension Modules Library ------- +- bpo-29703: Fix asyncio to support instantiation of new event loops + in child processes. + - bpo-29376: Fix assertion error in threading._DummyThread.is_alive(). - bpo-29110: Fix file object leak in aifc.open() when file is given as a From 80fbacc9369c07daeea6a50a61d214820bb29874 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Thu, 2 Mar 2017 23:57:33 -0500 Subject: [PATCH 045/340] asyncio: Optimize _get_running_loop() to call getpid() only when there's a loop --- Lib/asyncio/events.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/events.py b/Lib/asyncio/events.py index 7b30b4c84ad9a7..e85634e588f5a5 100644 --- a/Lib/asyncio/events.py +++ b/Lib/asyncio/events.py @@ -624,8 +624,9 @@ def _get_running_loop(): This is a low-level function intended to be used by event loops. This function is thread-specific. """ - if _running_loop._pid == os.getpid(): - return _running_loop._loop + running_loop = _running_loop._loop + if running_loop is not None and _running_loop._pid == os.getpid(): + return running_loop def _set_running_loop(loop): From 8c851fa3d3044d5bc53e9f931129f5987ece401d Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 2 Mar 2017 21:50:46 -0800 Subject: [PATCH 046/340] bpo-29026: Clarify documentation of time.time (GH-34) (GH-418) (cherry picked from commit 23557d59b819f57800ddef0b1373acef8e024670) --- Doc/library/time.rst | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/Doc/library/time.rst b/Doc/library/time.rst index e6626f262df48a..92e7ce0f6631a8 100644 --- a/Doc/library/time.rst +++ b/Doc/library/time.rst @@ -17,11 +17,23 @@ semantics of these functions varies among platforms. An explanation of some terminology and conventions is in order. +.. _epoch: + .. index:: single: epoch -* The :dfn:`epoch` is the point where the time starts. On January 1st of that - year, at 0 hours, the "time since the epoch" is zero. For Unix, the epoch is - 1970. To find out what the epoch is, look at ``gmtime(0)``. +* The :dfn:`epoch` is the point where the time starts, and is platform + dependent. For Unix, the epoch is January 1, 1970, 00:00:00 (UTC). + To find out what the epoch is on a given platform, look at + ``time.gmtime(0)``. + +.. _leap seconds: https://en.wikipedia.org/wiki/Leap_second + +.. index:: seconds since the epoch + +* The term :dfn:`seconds since the epoch` refers to the total number + of elapsed seconds since the epoch, typically excluding + `leap seconds`_. Leap seconds are excluded from this total on all + POSIX-compliant platforms. .. index:: single: Year 2038 @@ -463,7 +475,7 @@ The module defines the following functions and data items: (2) The range really is ``0`` to ``61``; value ``60`` is valid in - timestamps representing leap seconds and value ``61`` is supported + timestamps representing `leap seconds`_ and value ``61`` is supported for historical reasons. (3) @@ -572,12 +584,28 @@ The module defines the following functions and data items: .. function:: time() - Return the time in seconds since the epoch as a floating point number. + Return the time in seconds since the epoch_ as a floating point + number. The specific date of the epoch and the handling of + `leap seconds`_ is platform dependent. + On Windows and most Unix systems, the epoch is January 1, 1970, + 00:00:00 (UTC) and leap seconds are not counted towards the time + in seconds since the epoch. This is commonly referred to as + `Unix time `_. + To find out what the epoch is on a given platform, look at + ``gmtime(0)``. + Note that even though the time is always returned as a floating point number, not all systems provide time with a better precision than 1 second. While this function normally returns non-decreasing values, it can return a - lower value than a previous call if the system clock has been set back between - the two calls. + lower value than a previous call if the system clock has been set back + between the two calls. + + The number returned by :func:`.time` may be converted into a more common + time format (i.e. year, month, day, hour, etc...) in UTC by passing it to + :func:`gmtime` function or in local time by passing it to the + :func:`localtime` function. In both cases a + :class:`struct_time` object is returned, from which the components + of the calendar date may be accessed as attributes. .. data:: timezone From 0ad7b628edb95b29b630902842c500de5582e869 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 2 Mar 2017 21:56:28 -0800 Subject: [PATCH 047/340] getpass: update docstrings (GH-49) (GH-420) (cherry picked from commit baf7bb30a02aabde260143136bdf5b3738a1d409) --- Lib/getpass.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/getpass.py b/Lib/getpass.py index be511211585a48..36e17e4cb6965d 100644 --- a/Lib/getpass.py +++ b/Lib/getpass.py @@ -7,7 +7,6 @@ echoing of the password contents while reading. On Windows, the msvcrt module will be used. -On the Mac EasyDialogs.AskPassword is used, if available. """ From d0620bcd4eb8b7bb39d7aedc3e434585959c3177 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Fri, 3 Mar 2017 18:07:01 +0300 Subject: [PATCH 048/340] Add Python version since deprecation in base64 methods. (#33) (#430) Allow developers to not have to either test on N Python versions or looked through multiple versions of the docs to know whether they can easily update. (cherry picked from commit c643a967dd7d33ccefa5b61b38caf40b448057ce) --- Doc/library/base64.rst | 17 +++++++++++++---- Lib/base64.py | 6 ++++-- Lib/test/test_base64.py | 8 ++++++++ 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst index 080d9d77ec984e..ceecf17cba23e3 100644 --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -237,14 +237,18 @@ The legacy interface: .. function:: decodebytes(s) - decodestring(s) Decode the :term:`bytes-like object` *s*, which must contain one or more lines of base64 encoded data, and return the decoded :class:`bytes`. - ``decodestring`` is a deprecated alias. .. versionadded:: 3.1 +.. function:: decodestring(s) + + Deprecated alias of :func:`decodebytes`. + + .. deprecated:: 3.1 + .. function:: encode(input, output) @@ -257,14 +261,19 @@ The legacy interface: .. function:: encodebytes(s) - encodestring(s) Encode the :term:`bytes-like object` *s*, which can contain arbitrary binary data, and return :class:`bytes` containing the base64-encoded data, with newlines (``b'\n'``) inserted after every 76 bytes of output, and ensuring that there is a trailing newline, as per :rfc:`2045` (MIME). - ``encodestring`` is a deprecated alias. + .. versionadded:: 3.1 + +.. function:: encodestring(s) + + Deprecated alias of :func:`encodebytes`. + + .. deprecated:: 3.1 An example usage of the module: diff --git a/Lib/base64.py b/Lib/base64.py index adaec1de61bf42..0dc64cffa1d24a 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -542,7 +542,8 @@ def encodebytes(s): def encodestring(s): """Legacy alias of encodebytes().""" import warnings - warnings.warn("encodestring() is a deprecated alias, use encodebytes()", + warnings.warn("encodestring() is a deprecated alias since 3.1, " + "use encodebytes()", DeprecationWarning, 2) return encodebytes(s) @@ -555,7 +556,8 @@ def decodebytes(s): def decodestring(s): """Legacy alias of decodebytes().""" import warnings - warnings.warn("decodestring() is a deprecated alias, use decodebytes()", + warnings.warn("decodestring() is a deprecated alias since Python 3.1, " + "use decodebytes()", DeprecationWarning, 2) return decodebytes(s) diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 4f86aaa0c0eb49..47547396b8cb54 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -18,6 +18,14 @@ def check_type_errors(self, f): int_data = memoryview(b"1234").cast('I') self.assertRaises(TypeError, f, int_data) + def test_encodestring_warns(self): + with self.assertWarns(DeprecationWarning): + base64.encodestring(b"www.python.org") + + def test_decodestring_warns(self): + with self.assertWarns(DeprecationWarning): + base64.decodestring(b"d3d3LnB5dGhvbi5vcmc=\n") + def test_encodebytes(self): eq = self.assertEqual eq(base64.encodebytes(b"www.python.org"), b"d3d3LnB5dGhvbi5vcmc=\n") From f7f024a721d53978d03129e8eb5111d4f74534a9 Mon Sep 17 00:00:00 2001 From: "Seth M. Larson" Date: Thu, 2 Mar 2017 22:21:18 -0600 Subject: [PATCH 049/340] bpo-29704: Fix asyncio.SubprocessStreamProtocol closing (#405) --- Lib/asyncio/subprocess.py | 17 +++++++++++++++-- Lib/test/test_asyncio/test_subprocess.py | 24 ++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/subprocess.py b/Lib/asyncio/subprocess.py index b2f5304f772121..4c85466859f8f0 100644 --- a/Lib/asyncio/subprocess.py +++ b/Lib/asyncio/subprocess.py @@ -24,6 +24,8 @@ def __init__(self, limit, loop): self._limit = limit self.stdin = self.stdout = self.stderr = None self._transport = None + self._process_exited = False + self._pipe_fds = [] def __repr__(self): info = [self.__class__.__name__] @@ -43,12 +45,14 @@ def connection_made(self, transport): self.stdout = streams.StreamReader(limit=self._limit, loop=self._loop) self.stdout.set_transport(stdout_transport) + self._pipe_fds.append(1) stderr_transport = transport.get_pipe_transport(2) if stderr_transport is not None: self.stderr = streams.StreamReader(limit=self._limit, loop=self._loop) self.stderr.set_transport(stderr_transport) + self._pipe_fds.append(2) stdin_transport = transport.get_pipe_transport(0) if stdin_transport is not None: @@ -86,9 +90,18 @@ def pipe_connection_lost(self, fd, exc): else: reader.set_exception(exc) + if fd in self._pipe_fds: + self._pipe_fds.remove(fd) + self._maybe_close_transport() + def process_exited(self): - self._transport.close() - self._transport = None + self._process_exited = True + self._maybe_close_transport() + + def _maybe_close_transport(self): + if len(self._pipe_fds) == 0 and self._process_exited: + self._transport.close() + self._transport = None class Process: diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py index bba688bb5a53c7..2e14a8a9735535 100644 --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -459,6 +459,30 @@ def test_popen_error(self): self.loop.run_until_complete(create) self.assertEqual(warns, []) + def test_read_stdout_after_process_exit(self): + @asyncio.coroutine + def execute(): + code = '\n'.join(['import sys', + 'for _ in range(64):', + ' sys.stdout.write("x" * 4096)', + 'sys.stdout.flush()', + 'sys.exit(1)']) + + fut = asyncio.create_subprocess_exec( + sys.executable, '-c', code, + stdout=asyncio.subprocess.PIPE, + loop=self.loop) + + process = yield from fut + while True: + data = yield from process.stdout.read(65536) + if data: + yield from asyncio.sleep(0.3, loop=self.loop) + else: + break + + self.loop.run_until_complete(execute()) + if sys.platform != 'win32': # Unix diff --git a/Misc/NEWS b/Misc/NEWS index 32741ce1e7d958..b17ad90a01398a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -35,6 +35,9 @@ Extension Modules Library ------- +- bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes before + all pipes are closed. + - bpo-29703: Fix asyncio to support instantiation of new event loops in child processes. From 6e965d9e78b278f2f720a932e7b149cb7d88bd72 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 3 Mar 2017 13:23:55 -0800 Subject: [PATCH 050/340] bpo-29709: Improve Boolean Operations documentation (#433) (#436) (cherry picked from commit 8eb531d9db0861e14222445fcaebe1a373bba170) --- Doc/library/stdtypes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 71cb7f2643576e..6b23b3eb610657 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -108,11 +108,11 @@ Notes: (1) This is a short-circuit operator, so it only evaluates the second - argument if the first one is :const:`False`. + argument if the first one is false. (2) This is a short-circuit operator, so it only evaluates the second - argument if the first one is :const:`True`. + argument if the first one is true. (3) ``not`` has a lower priority than non-Boolean operators, so ``not a == b`` is From dd2000cbe475da48fdc94e8f05618e9f460077fd Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 3 Mar 2017 16:07:37 -0600 Subject: [PATCH 051/340] bpo-29572: Update Windows build to OpenSSL 1.0.2k (GH-443) --- Misc/NEWS | 5 +++++ PCbuild/get_externals.bat | 2 +- PCbuild/python.props | 2 +- PCbuild/readme.txt | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index b17ad90a01398a..47e3d05a1bef71 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -127,6 +127,11 @@ Tests determine the candidate encoding for the test regex (allowing it to correctly skip the test when the default locale encoding is a multi-byte encoding) +Build +----- + +- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. + What's New in Python 3.5.3? =========================== diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 1c3cdee2c4bd84..dfaf5496a2b614 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -54,7 +54,7 @@ echo.Fetching external libraries... set libraries= set libraries=%libraries% bzip2-1.0.6 if NOT "%IncludeSSL%"=="false" set libraries=%libraries% nasm-2.11.06 -if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2j +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2k set libraries=%libraries% sqlite-3.8.11.0 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.4.2 if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.4.2 diff --git a/PCbuild/python.props b/PCbuild/python.props index 1553731d1fece3..0a6fd2a6513826 100644 --- a/PCbuild/python.props +++ b/PCbuild/python.props @@ -46,7 +46,7 @@ $(ExternalsDir)sqlite-3.8.11.0\ $(ExternalsDir)bzip2-1.0.6\ $(ExternalsDir)xz-5.0.5\ - $(ExternalsDir)openssl-1.0.2j\ + $(ExternalsDir)openssl-1.0.2k\ $(opensslDir)include32 $(opensslDir)include64 $(ExternalsDir)\nasm-2.11.06\ diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 24620128ec98da..68579256f28b84 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -169,7 +169,7 @@ _lzma Homepage: http://tukaani.org/xz/ _ssl - Python wrapper for version 1.0.2j of the OpenSSL secure sockets + Python wrapper for version 1.0.2k of the OpenSSL secure sockets library, which is built by ssl.vcxproj Homepage: http://www.openssl.org/ From 4d0630d9d5ff4919caa463a64887f32d671eaab8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Mar 2017 14:47:22 -0800 Subject: [PATCH 052/340] bpo-26213: Document _UNPACK bytecodes and BUILD_MAP changes (GH-441) (cherry picked from commit 0705f66eb369aa6a6cdb699e24ff61e1ab2e0c56) --- Doc/library/dis.rst | 55 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index f86725b6016b9b..186aab40f636f9 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -765,8 +765,59 @@ the more significant byte last. .. opcode:: BUILD_MAP (count) - Pushes a new dictionary object onto the stack. The dictionary is pre-sized - to hold *count* entries. + Pushes a new dictionary object onto the stack. Pops ``2 * count`` items + so that the dictionary holds *count* entries: + ``{..., TOS3: TOS2, TOS1: TOS}``. + + .. versionchanged:: 3.5 + The dictionary is created from stack items instead of creating an + empty dictionary pre-sized to hold *count* items. + + +.. opcode:: BUILD_TUPLE_UNPACK (count) + + Pops *count* iterables from the stack, joins them in a single tuple, + and pushes the result. Implements iterable unpacking in tuple + displays ``(*x, *y, *z)``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_LIST_UNPACK (count) + + This is similar to :opcode:`BUILD_TUPLE_UNPACK`, but pushes a list + instead of tuple. Implements iterable unpacking in list + displays ``[*x, *y, *z]``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_SET_UNPACK (count) + + This is similar to :opcode:`BUILD_TUPLE_UNPACK`, but pushes a set + instead of tuple. Implements iterable unpacking in set + displays ``{*x, *y, *z}``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_MAP_UNPACK (count) + + Pops *count* mappings from the stack, merges them into a single dictionary, + and pushes the result. Implements dictionary unpacking in dictionary + displays ``{**x, **y, **z}``. + + .. versionadded:: 3.5 + + +.. opcode:: BUILD_MAP_UNPACK_WITH_CALL (oparg) + + This is similar to :opcode:`BUILD_MAP_UNPACK`, + but is used for ``f(**x, **y, **z)`` call syntax. The lowest byte of + *oparg* is the count of mappings, the relative position of the + corresponding callable ``f`` is encoded in the second byte of *oparg*. + + .. versionadded:: 3.5 .. opcode:: LOAD_ATTR (namei) From cf445f10560483d38485204cf46ff1d0adcb4192 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 3 Mar 2017 21:32:23 -0800 Subject: [PATCH 053/340] bpo-27593: Updates Windows build to use information from git (#262) (#449) * bpo-27593: Updates Windows build to use information from git --- PCbuild/build.bat | 8 ++++---- PCbuild/pythoncore.vcxproj | 23 ++++++++++++----------- Tools/msi/buildrelease.bat | 4 ++-- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 9e63a84bde4570..1dbe888972f4c5 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -105,9 +105,9 @@ if "%platf%"=="x64" ( ) ) -if not exist "%HG%" where hg > "%TEMP%\hg.loc" 2> nul && set /P HG= < "%TEMP%\hg.loc" & del "%TEMP%\hg.loc" -if exist "%HG%" set HGProperty=/p:HG="%HG%" -if not exist "%HG%" echo Cannot find Mercurial on PATH & set HGProperty= +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" +if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= rem Setup the environment call "%dir%env.bat" %vs_platf% >nul @@ -145,7 +145,7 @@ msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ /p:Configuration=%conf% /p:Platform=%platf%^ /p:IncludeExternals=%IncludeExternals%^ /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ - /p:UseTestMarker=%UseTestMarker% %HGProperty%^ + /p:UseTestMarker=%UseTestMarker% %GITProperty%^ %1 %2 %3 %4 %5 %6 %7 %8 %9 @echo off diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 970344fd123308..ed16e73ac51861 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -400,23 +400,24 @@ - hg - <_HG>$(HG) - <_HG Condition="$(HG.Contains(` `))">"$(HG)" + git + <_GIT>$(GIT) + <_GIT Condition="$(GIT.Contains(` `))">"$(GIT)" - + - - - + + + - $([System.IO.File]::ReadAllText('$(IntDir)hgbranch.txt').Trim()) - $([System.IO.File]::ReadAllText('$(IntDir)hgversion.txt').Trim()) - $([System.IO.File]::ReadAllText('$(IntDir)hgtag.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim()) + $([System.IO.File]::ReadAllText('$(IntDir)gittag.txt').Trim()) + - HGVERSION="$(HgVersion)";HGTAG="$(HgTag)";HGBRANCH="$(HgBranch)";%(PreprocessorDefinitions) + GITVERSION="$(GitVersion)";GITTAG="$(GitTag)";GITBRANCH="$(GitBranch)";%(PreprocessorDefinitions) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index f296e613ac19f6..706febf2534f71 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -64,8 +64,8 @@ if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) -if not exist "%HG%" where hg > "%TEMP%\hg.loc" 2> nul && set /P HG= < "%TEMP%\hg.loc" & del "%TEMP%\hg.loc" -if not exist "%HG%" echo Cannot find Mercurial on PATH && exit /B 1 +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 call "%D%get_externals.bat" From 2df52acce2471f6ee27cdcd5f525538abbc13313 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Fri, 3 Mar 2017 21:58:48 -0800 Subject: [PATCH 054/340] Fixes git command (#451) (#453) --- PCbuild/pythoncore.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index ed16e73ac51861..b7e0f3cec534d4 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -408,7 +408,7 @@ - + $([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim()) $([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim()) From a2edd3ae4074952ce77d9319da2dbb2a47300c27 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Sat, 4 Mar 2017 01:34:19 -0500 Subject: [PATCH 055/340] [3.5] bpo-27593: Get SCM build info from git instead of hg. (#446) (#454) (#455) * bpo-27593: Get SCM build info from git instead of hg. (#446) sys.version and the platform module python_build(), python_branch(), and python_revision() functions now use git information rather than hg when building from a repo. Based on original patches by Brett Cannon and Steve Dower. (cherry picked from commit 5c4b0d063aba0a68c325073f5f312a2c9f40d178) (cherry picked from commit 95c50e5aed9e5683676e18349dd94b11901a66b3) --- Include/pylifecycle.h | 4 ++-- Lib/platform.py | 4 +++- Lib/test/test_platform.py | 12 +++++----- Makefile.pre.in | 12 +++++----- Misc/NEWS | 5 ---- Modules/getbuildinfo.c | 46 ++++++++++++++++++------------------- Python/sysmodule.c | 6 ++--- configure | 48 +++++++++++++++++++-------------------- configure.ac | 26 ++++++++++----------- 9 files changed, 80 insertions(+), 83 deletions(-) diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h index ccdebe26a4887b..1c5f7a63743fb4 100644 --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -69,8 +69,8 @@ PyAPI_FUNC(const char *) Py_GetCopyright(void); PyAPI_FUNC(const char *) Py_GetCompiler(void); PyAPI_FUNC(const char *) Py_GetBuildInfo(void); #ifndef Py_LIMITED_API -PyAPI_FUNC(const char *) _Py_hgidentifier(void); -PyAPI_FUNC(const char *) _Py_hgversion(void); +PyAPI_FUNC(const char *) _Py_gitidentifier(void); +PyAPI_FUNC(const char *) _Py_gitversion(void); #endif /* Internal -- various one-time initializations */ diff --git a/Lib/platform.py b/Lib/platform.py index 3e726a7856ff98..d3ed5bf4c50758 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1199,7 +1199,9 @@ def _sys_version(sys_version=None): elif buildtime: builddate = builddate + ' ' + buildtime - if hasattr(sys, '_mercurial'): + if hasattr(sys, '_git'): + _, branch, revision = sys._git + elif hasattr(sys, '_mercurial'): _, branch, revision = sys._mercurial elif hasattr(sys, 'subversion'): # sys.subversion was added in Python 2.5 diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 18de110ecb4601..e16b9fa08ca3ed 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -66,12 +66,12 @@ def test_processor(self): def setUp(self): self.save_version = sys.version - self.save_mercurial = sys._mercurial + self.save_git = sys._git self.save_platform = sys.platform def tearDown(self): sys.version = self.save_version - sys._mercurial = self.save_mercurial + sys._git = self.save_git sys.platform = self.save_platform def test_sys_version(self): @@ -101,7 +101,7 @@ def test_sys_version(self): ('CPython', '2.4.3', '', '', 'truncation', '', 'GCC')), ): # branch and revision are not "parsed", but fetched - # from sys._mercurial. Ignore them + # from sys._git. Ignore them (name, version, branch, revision, buildno, builddate, compiler) \ = platform._sys_version(input) self.assertEqual( @@ -148,10 +148,10 @@ def test_sys_version(self): sys_versions.items(): sys.version = version_tag if subversion is None: - if hasattr(sys, "_mercurial"): - del sys._mercurial + if hasattr(sys, "_git"): + del sys._git else: - sys._mercurial = subversion + sys._git = subversion if sys_platform is not None: sys.platform = sys_platform self.assertEqual(platform.python_implementation(), info[0]) diff --git a/Makefile.pre.in b/Makefile.pre.in index dc0a40e237d2f1..e1436c3bfdca91 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -41,9 +41,9 @@ RANLIB= @RANLIB@ READELF= @READELF@ SOABI= @SOABI@ LDVERSION= @LDVERSION@ -HGVERSION= @HGVERSION@ -HGTAG= @HGTAG@ -HGBRANCH= @HGBRANCH@ +GITVERSION= @GITVERSION@ +GITTAG= @GITTAG@ +GITBRANCH= @GITBRANCH@ PGO_PROF_GEN_FLAG=@PGO_PROF_GEN_FLAG@ PGO_PROF_USE_FLAG=@PGO_PROF_USE_FLAG@ LLVM_PROF_MERGER=@LLVM_PROF_MERGER@ @@ -739,9 +739,9 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ $(MODOBJS) \ $(srcdir)/Modules/getbuildinfo.c $(CC) -c $(PY_CORE_CFLAGS) \ - -DHGVERSION="\"`LC_ALL=C $(HGVERSION)`\"" \ - -DHGTAG="\"`LC_ALL=C $(HGTAG)`\"" \ - -DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \ + -DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \ + -DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \ + -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ -o $@ $(srcdir)/Modules/getbuildinfo.c Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile diff --git a/Misc/NEWS b/Misc/NEWS index 47e3d05a1bef71..b17ad90a01398a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -127,11 +127,6 @@ Tests determine the candidate encoding for the test regex (allowing it to correctly skip the test when the default locale encoding is a multi-byte encoding) -Build ------ - -- bpo-29572: Update Windows build and OS X installers to use OpenSSL 1.0.2k. - What's New in Python 3.5.3? =========================== diff --git a/Modules/getbuildinfo.c b/Modules/getbuildinfo.c index 0971a64fccbadc..5f941a26e1d54c 100644 --- a/Modules/getbuildinfo.c +++ b/Modules/getbuildinfo.c @@ -21,47 +21,47 @@ #endif /* XXX Only unix build process has been tested */ -#ifndef HGVERSION -#define HGVERSION "" +#ifndef GITVERSION +#define GITVERSION "" #endif -#ifndef HGTAG -#define HGTAG "" +#ifndef GITTAG +#define GITTAG "" #endif -#ifndef HGBRANCH -#define HGBRANCH "" +#ifndef GITBRANCH +#define GITBRANCH "" #endif const char * Py_GetBuildInfo(void) { - static char buildinfo[50 + sizeof(HGVERSION) + - ((sizeof(HGTAG) > sizeof(HGBRANCH)) ? - sizeof(HGTAG) : sizeof(HGBRANCH))]; - const char *revision = _Py_hgversion(); + static char buildinfo[50 + sizeof(GITVERSION) + + ((sizeof(GITTAG) > sizeof(GITBRANCH)) ? + sizeof(GITTAG) : sizeof(GITBRANCH))]; + const char *revision = _Py_gitversion(); const char *sep = *revision ? ":" : ""; - const char *hgid = _Py_hgidentifier(); - if (!(*hgid)) - hgid = "default"; + const char *gitid = _Py_gitidentifier(); + if (!(*gitid)) + gitid = "default"; PyOS_snprintf(buildinfo, sizeof(buildinfo), - "%s%s%s, %.20s, %.9s", hgid, sep, revision, + "%s%s%s, %.20s, %.9s", gitid, sep, revision, DATE, TIME); return buildinfo; } const char * -_Py_hgversion(void) +_Py_gitversion(void) { - return HGVERSION; + return GITVERSION; } const char * -_Py_hgidentifier(void) +_Py_gitidentifier(void) { - const char *hgtag, *hgid; - hgtag = HGTAG; - if ((*hgtag) && strcmp(hgtag, "tip") != 0) - hgid = hgtag; + const char *gittag, *gitid; + gittag = GITTAG; + if ((*gittag) && strcmp(gittag, "undefined") != 0) + gitid = gittag; else - hgid = HGBRANCH; - return hgid; + gitid = GITBRANCH; + return gitid; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1dc7d7cf6beb6c..fc769ad1d8c1d2 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1816,9 +1816,9 @@ _PySys_Init(void) PyUnicode_FromString(Py_GetVersion())); SET_SYS_FROM_STRING("hexversion", PyLong_FromLong(PY_VERSION_HEX)); - SET_SYS_FROM_STRING("_mercurial", - Py_BuildValue("(szz)", "CPython", _Py_hgidentifier(), - _Py_hgversion())); + SET_SYS_FROM_STRING("_git", + Py_BuildValue("(szz)", "CPython", _Py_gitidentifier(), + _Py_gitversion())); SET_SYS_FROM_STRING("dont_write_bytecode", PyBool_FromLong(Py_DontWriteBytecodeFlag)); SET_SYS_FROM_STRING("api_version", diff --git a/configure b/configure index 1f84647ce1913a..640cad7c4aa45a 100755 --- a/configure +++ b/configure @@ -757,10 +757,10 @@ build_os build_vendor build_cpu build -HAS_HG -HGBRANCH -HGTAG -HGVERSION +HAS_GIT +GITBRANCH +GITTAG +GITVERSION BASECPPFLAGS target_alias host_alias @@ -2839,17 +2839,17 @@ fi -if test -e $srcdir/.hg/dirstate +if test -e $srcdir/.git/HEAD then -# Extract the first word of "hg", so it can be a program name with args. -set dummy hg; ac_word=$2 +# Extract the first word of "git", so it can be a program name with args. +set dummy git; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_HAS_HG+:} false; then : +if ${ac_cv_prog_HAS_GIT+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$HAS_HG"; then - ac_cv_prog_HAS_HG="$HAS_HG" # Let the user override the test. + if test -n "$HAS_GIT"; then + ac_cv_prog_HAS_GIT="$HAS_GIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2858,7 +2858,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_HAS_HG="found" + ac_cv_prog_HAS_GIT="found" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2866,13 +2866,13 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_prog_HAS_HG" && ac_cv_prog_HAS_HG="not-found" + test -z "$ac_cv_prog_HAS_GIT" && ac_cv_prog_HAS_GIT="not-found" fi fi -HAS_HG=$ac_cv_prog_HAS_HG -if test -n "$HAS_HG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_HG" >&5 -$as_echo "$HAS_HG" >&6; } +HAS_GIT=$ac_cv_prog_HAS_GIT +if test -n "$HAS_GIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAS_GIT" >&5 +$as_echo "$HAS_GIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -2880,17 +2880,17 @@ fi else -HAS_HG=no-repository +HAS_GIT=no-repository fi -if test $HAS_HG = found +if test $HAS_GIT = found then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" + GITVERSION="git -C \$(srcdir) rev-parse HEAD" + GITTAG="git -C \$(srcdir) name-rev --tags --name-only HEAD" + GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else - HGVERSION="" - HGTAG="" - HGBRANCH="" + GITVERSION="" + GITTAG="" + GITBRANCH="" fi diff --git a/configure.ac b/configure.ac index 49d1a37e5ac2bc..4682341723f038 100644 --- a/configure.ac +++ b/configure.ac @@ -25,25 +25,25 @@ else BASECPPFLAGS="" fi -AC_SUBST(HGVERSION) -AC_SUBST(HGTAG) -AC_SUBST(HGBRANCH) +AC_SUBST(GITVERSION) +AC_SUBST(GITTAG) +AC_SUBST(GITBRANCH) -if test -e $srcdir/.hg/dirstate +if test -e $srcdir/.git/HEAD then -AC_CHECK_PROG(HAS_HG, hg, found, not-found) +AC_CHECK_PROG(HAS_GIT, git, found, not-found) else -HAS_HG=no-repository +HAS_GIT=no-repository fi -if test $HAS_HG = found +if test $HAS_GIT = found then - HGVERSION="hg id -i \$(srcdir)" - HGTAG="hg id -t \$(srcdir)" - HGBRANCH="hg id -b \$(srcdir)" + GITVERSION="git -C \$(srcdir) rev-parse HEAD" + GITTAG="git -C \$(srcdir) name-rev --tags --name-only HEAD" + GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else - HGVERSION="" - HGTAG="" - HGBRANCH="" + GITVERSION="" + GITTAG="" + GITBRANCH="" fi AC_CONFIG_SRCDIR([Include/object.h]) From 5789e415e82f91563f62ae08b47f1a264048a72b Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 4 Mar 2017 15:40:36 -0800 Subject: [PATCH 056/340] Correct spelling "instanciate" (GH-465) (GH-468) (cherry picked from commit 6abaed0ddaa1dd9be727ede09f6cd801c467c2ec) --- Doc/library/asyncio-subprocess.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst index dc93a74c6dee12..16ba9a3cd6c7f2 100644 --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -80,7 +80,7 @@ Run subprocesses asynchronously using the :mod:`subprocess` module. however, where :class:`~subprocess.Popen` takes a single argument which is list of strings, :func:`subprocess_exec` takes multiple string arguments. - The *protocol_factory* must instanciate a subclass of the + The *protocol_factory* must instantiate a subclass of the :class:`asyncio.SubprocessProtocol` class. Other parameters: @@ -123,7 +123,7 @@ Run subprocesses asynchronously using the :mod:`subprocess` module. using the platform's "shell" syntax. This is similar to the standard library :class:`subprocess.Popen` class called with ``shell=True``. - The *protocol_factory* must instanciate a subclass of the + The *protocol_factory* must instantiate a subclass of the :class:`asyncio.SubprocessProtocol` class. See :meth:`~AbstractEventLoop.subprocess_exec` for more details about From 171b674c8bf63153482e7e23e97c57c8b9182466 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 4 Mar 2017 16:44:30 -0800 Subject: [PATCH 057/340] distutils docs: Fix a typo (GH-470) (#472) (cherry picked from commit 2a7bddaab7d6e1f7b243cdbb4fa6f6c8e266b18d) --- Doc/distutils/examples.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/distutils/examples.rst b/Doc/distutils/examples.rst index 1f5be9cdb29a97..4e2761d8a7d046 100644 --- a/Doc/distutils/examples.rst +++ b/Doc/distutils/examples.rst @@ -321,7 +321,7 @@ You can read back this static file, by using the >>> metadata.description 'Easily download, build, install, upgrade, and uninstall Python packages' -Notice that the class can also be instanciated with a metadata file path to +Notice that the class can also be instantiated with a metadata file path to loads its values:: >>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info' From c6e199f2e9a2514c3fd220aaa4bd23fa1d6da8c9 Mon Sep 17 00:00:00 2001 From: Petr Motejlek Date: Sun, 5 Mar 2017 17:14:26 +0100 Subject: [PATCH 058/340] bpo-29615: backport to 3.5 (#479) --- Lib/test/test_xmlrpc.py | 90 ++++++++++++++++++++++++++++++++++++++++- Lib/xmlrpc/server.py | 43 +++++++++++--------- Misc/NEWS | 4 ++ 3 files changed, 117 insertions(+), 20 deletions(-) diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 02d9f5c650c6f3..7e023c16733196 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -295,6 +295,94 @@ def run_server(): self.assertEqual(p.method(), 5) self.assertEqual(p.method(), 5) + +class SimpleXMLRPCDispatcherTestCase(unittest.TestCase): + class DispatchExc(Exception): + """Raised inside the dispatched functions when checking for + chained exceptions""" + + def test_call_registered_func(self): + """Calls explicitly registered function""" + # Makes sure any exception raised inside the function has no other + # exception chained to it + + exp_params = 1, 2, 3 + + def dispatched_func(*params): + raise self.DispatchExc(params) + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + dispatcher.register_function(dispatched_func) + with self.assertRaises(self.DispatchExc) as exc_ctx: + dispatcher._dispatch('dispatched_func', exp_params) + self.assertEqual(exc_ctx.exception.args, (exp_params,)) + self.assertIsNone(exc_ctx.exception.__cause__) + self.assertIsNone(exc_ctx.exception.__context__) + + def test_call_instance_func(self): + """Calls a registered instance attribute as a function""" + # Makes sure any exception raised inside the function has no other + # exception chained to it + + exp_params = 1, 2, 3 + + class DispatchedClass: + def dispatched_func(self, *params): + raise SimpleXMLRPCDispatcherTestCase.DispatchExc(params) + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + dispatcher.register_instance(DispatchedClass()) + with self.assertRaises(self.DispatchExc) as exc_ctx: + dispatcher._dispatch('dispatched_func', exp_params) + self.assertEqual(exc_ctx.exception.args, (exp_params,)) + self.assertIsNone(exc_ctx.exception.__cause__) + self.assertIsNone(exc_ctx.exception.__context__) + + def test_call_dispatch_func(self): + """Calls the registered instance's `_dispatch` function""" + # Makes sure any exception raised inside the function has no other + # exception chained to it + + exp_method = 'method' + exp_params = 1, 2, 3 + + class TestInstance: + def _dispatch(self, method, params): + raise SimpleXMLRPCDispatcherTestCase.DispatchExc( + method, params) + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + dispatcher.register_instance(TestInstance()) + with self.assertRaises(self.DispatchExc) as exc_ctx: + dispatcher._dispatch(exp_method, exp_params) + self.assertEqual(exc_ctx.exception.args, (exp_method, exp_params)) + self.assertIsNone(exc_ctx.exception.__cause__) + self.assertIsNone(exc_ctx.exception.__context__) + + def test_registered_func_is_none(self): + """Calls explicitly registered function which is None""" + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + dispatcher.register_function(None, name='method') + with self.assertRaises(Exception, expected_regex='method'): + dispatcher._dispatch('method', ('param',)) + + def test_instance_has_no_func(self): + """Attempts to call nonexistent function on a registered instance""" + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + dispatcher.register_instance(object()) + with self.assertRaises(Exception, expected_regex='method'): + dispatcher._dispatch('method', ('param',)) + + def test_cannot_locate_func(self): + """Calls a function that the dispatcher cannot locate""" + + dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() + with self.assertRaises(Exception, expected_regex='method'): + dispatcher._dispatch('method', ('param',)) + + class HelperTestCase(unittest.TestCase): def test_escape(self): self.assertEqual(xmlrpclib.escape("a&b"), "a&b") @@ -1265,7 +1353,7 @@ def test_main(): KeepaliveServerTestCase1, KeepaliveServerTestCase2, GzipServerTestCase, GzipUtilTestCase, MultiPathServerTestCase, ServerProxyTestCase, FailingServerTestCase, - CGIHandlerTestCase) + CGIHandlerTestCase, SimpleXMLRPCDispatcherTestCase) if __name__ == "__main__": diff --git a/Lib/xmlrpc/server.py b/Lib/xmlrpc/server.py index 781769323272c7..276394dfbf33d4 100644 --- a/Lib/xmlrpc/server.py +++ b/Lib/xmlrpc/server.py @@ -386,31 +386,36 @@ def _dispatch(self, method, params): not be called. """ - func = None try: - # check to see if a matching function has been registered + # call the matching registered function func = self.funcs[method] except KeyError: - if self.instance is not None: - # check for a _dispatch method - if hasattr(self.instance, '_dispatch'): - return self.instance._dispatch(method, params) - else: - # call instance method directly - try: - func = resolve_dotted_attribute( - self.instance, - method, - self.allow_dotted_names - ) - except AttributeError: - pass - - if func is not None: - return func(*params) + pass else: + if func is not None: + return func(*params) raise Exception('method "%s" is not supported' % method) + if self.instance is not None: + if hasattr(self.instance, '_dispatch'): + # call the `_dispatch` method on the instance + return self.instance._dispatch(method, params) + + # call the instance's method directly + try: + func = resolve_dotted_attribute( + self.instance, + method, + self.allow_dotted_names + ) + except AttributeError: + pass + else: + if func is not None: + return func(*params) + + raise Exception('method "%s" is not supported' % method) + class SimpleXMLRPCRequestHandler(BaseHTTPRequestHandler): """Simple XML-RPC request handler class. diff --git a/Misc/NEWS b/Misc/NEWS index b17ad90a01398a..03f8286f080ba6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -35,6 +35,10 @@ Extension Modules Library ------- +- bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other + exception) to exception(s) raised in the dispatched methods. + Patch by Petr Motejlek. + - bpo-29704: asyncio.subprocess.SubprocessStreamProtocol no longer closes before all pipes are closed. From 997cc69a6832be4818491e0462896d9572bf71b0 Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Sun, 5 Mar 2017 20:19:42 +0100 Subject: [PATCH 059/340] Backport fix for spurious refleak failures (#482) --- Lib/test/regrtest.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index c1d85f6a18482a..12909ec4778319 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -1480,9 +1480,14 @@ def dash_R_cleanup(fs, ps, pic, zdc, abcs): sys._clear_type_cache() # Clear ABC registries, restoring previously saved ABC registries. - for abc in [getattr(collections.abc, a) for a in collections.abc.__all__]: - if not isabstract(abc): - continue + abs_classes = [getattr(collections.abc, a) for a in collections.abc.__all__] + abs_classes = filter(isabstract, abs_classes) + if 'typing' in sys.modules: + t = sys.modules['typing'] + # these classes require special treatment because they do not appear + # in direct subclasses on collections.abc classes + abs_classes = list(abs_classes) + [t.ChainMap, t.Counter, t.DefaultDict] + for abc in abs_classes: for obj in abc.__subclasses__() + [abc]: obj._abc_registry = abcs.get(obj, WeakSet()).copy() obj._abc_cache.clear() From b8b3b9b97c82bb0ac718c446b66fd516eb9ad18b Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Sun, 5 Mar 2017 19:58:10 -0800 Subject: [PATCH 060/340] Fixes the upload script to purge the CDN correctly and display success output. (#466) (#496) --- Tools/msi/uploadrelease.proj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj index 305e84fc2d4b28..75840f2f851ecd 100644 --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -8,6 +8,7 @@ $(TARGET) /srv/www.python.org/ftp/python true + true false false @@ -91,6 +92,7 @@ echo." /> + From 6b7bc45e33ec953c542788420adc305ec026fa40 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 6 Mar 2017 09:31:00 -0800 Subject: [PATCH 061/340] bpo-29557: Remove ambiguous line in binhex docs (GH-90) (GH-474) "appears to not work in all cases" does not inspire confidence in this module. I can find no context for what bug this was referencing so it should be removed. (cherry picked from commit 6de2b7817fa9403e81dc38f13f3690f0bbf3d064) --- Doc/library/binhex.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/Doc/library/binhex.rst b/Doc/library/binhex.rst index 359ab23b2f9787..2966e0dbfbcfe8 100644 --- a/Doc/library/binhex.rst +++ b/Doc/library/binhex.rst @@ -55,5 +55,3 @@ the source for details. If you code or decode textfiles on non-Macintosh platforms they will still use the old Macintosh newline convention (carriage-return as end of line). -As of this writing, :func:`hexbin` appears to not work in all cases. - From bef209d449afcdc391b108d197a95b15902197d9 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Tue, 7 Mar 2017 17:18:33 +0900 Subject: [PATCH 062/340] PCbuild: Add -q option to svn export (GH-538) Without this option, AppVeyor log is too unreadable. (cherry picked from commit 8886d5f39286dffa7d9337857b151e7fb4af23fd) --- PCbuild/get_externals.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index dfaf5496a2b614..9cd13065c7abb9 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -66,7 +66,7 @@ for %%e in (%libraries%) do ( echo.%%e already exists, skipping. ) else ( echo.Fetching %%e... - svn export %SVNROOT%%%e + svn export -q %SVNROOT%%%e ) ) From 93602e3af70d3b9f98ae2da654b16b3382b68d50 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Wed, 8 Mar 2017 16:41:01 +1000 Subject: [PATCH 063/340] [3.5] bpo-29537: Tolerate legacy invalid bytecode (#169) bpo-27286 fixed a problem where BUILD_MAP_UNPACK_WITH_CALL could be emitted with an incorrect oparg value, causing the eval loop to access the wrong stack entry when attempting to read the function name. The associated magic number change caused significant problems when attempting to upgrade to 3.5.3 for anyone that relies on pre-cached bytecode remaining valid across maintenance releases. This patch restores the ability to import legacy bytecode generated by 3.5.0, 3.5.1 or 3.5.2, and modifies the eval loop to avoid any harmful consequences from the potentially malformed legacy bytecode. Original import patch by Petr Viktorin, eval loop patch by Serhiy Storchaka, and tests and integration by Nick Coghlan. --- Lib/importlib/_bootstrap_external.py | 28 +- Lib/importlib/util.py | 2 +- Lib/pkgutil.py | 5 +- Lib/pydoc.py | 7 +- Lib/test/test_extcall.py | 6 +- .../test_importlib/source/test_file_loader.py | 104 + Lib/test/test_unpack_ex.py | 2 +- Misc/NEWS | 6 + Modules/zipimport.c | 11 +- Python/ceval.c | 85 +- Python/import.c | 10 +- Python/importlib_external.h | 5145 +++++++++-------- Python/pythonrun.c | 19 +- 13 files changed, 2823 insertions(+), 2607 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index e54d6916e89306..506bb33598a325 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -230,7 +230,7 @@ def _write_atomic(path, data, mode=0o666): # Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations) # Python 3.5b2 3340 (fix dictionary display evaluation order #11205) # Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400) -# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) +# Python 3.5.3 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -242,6 +242,28 @@ def _write_atomic(path, data, mode=0o666): MAGIC_NUMBER = (3351).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c +# Issue #29537: handle issue27286 bytecode incompatibility +# +# The magic number bump in Python 3.5.3 for issue27286 turned out to create +# significant backwards compatibility problems for redistributors and +# other folks that rely on the bytecode format remaining stable within a +# given maintenance release series. See http://bugs.python.org/issue29514 +# for more discussion of the problems that the original change caused. +# +# The _BACKCOMPAT_MAGIC_NUMBER below and any other changes marked with +# "Issue #29537" comments allow Python 3.5.4+ to load bytecode files with both +# the original 3.5.0 magic number and those with the updated magic number used +# since 3.5.3. +# +# This is expected to be a one-off change used solely to restore legacy +# bytecode compatibility within the 3.5.x series, so it avoids any changes +# that would prompt a rebuild of C extension modules. +# +if _RAW_MAGIC_NUMBER != 168627479: + _msg = 'Magic number mismatch (the issue27286 workaround is for 3.5 only)' + raise SystemError(_msg) +_BACKCOMPAT_MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n' + _PYCACHE = '__pycache__' _OPT = 'opt-' @@ -446,7 +468,9 @@ def _validate_bytecode_header(data, source_stats=None, name=None, path=None): magic = data[:4] raw_timestamp = data[4:8] raw_size = data[8:12] - if magic != MAGIC_NUMBER: + if (magic != MAGIC_NUMBER + # Issue #29537: handle issue27286 bytecode incompatibility + and magic != _BACKCOMPAT_MAGIC_NUMBER): message = 'bad magic number in {!r}: {!r}'.format(name, magic) _verbose_message('{}', message) raise ImportError(message, **exc_details) diff --git a/Lib/importlib/util.py b/Lib/importlib/util.py index e1fa07a6645ea3..a15cf009dbc4f3 100644 --- a/Lib/importlib/util.py +++ b/Lib/importlib/util.py @@ -4,7 +4,7 @@ from ._bootstrap import _resolve_name from ._bootstrap import spec_from_loader from ._bootstrap import _find_spec -from ._bootstrap_external import MAGIC_NUMBER +from ._bootstrap_external import MAGIC_NUMBER, _BACKCOMPAT_MAGIC_NUMBER from ._bootstrap_external import cache_from_source from ._bootstrap_external import decode_source from ._bootstrap_external import source_from_cache diff --git a/Lib/pkgutil.py b/Lib/pkgutil.py index 81d418da56e7e4..9d1879a20c08d8 100644 --- a/Lib/pkgutil.py +++ b/Lib/pkgutil.py @@ -37,7 +37,10 @@ def read_code(stream): import marshal magic = stream.read(4) - if magic != importlib.util.MAGIC_NUMBER: + if (magic != importlib.util.MAGIC_NUMBER + # Issue #29537: handle issue27286 bytecode incompatibility + # See Lib/importlib/_bootstrap_external.py + and magic != importlib.util._BACKCOMPAT_MAGIC_NUMBER): return None stream.read(8) # Skip timestamp and size diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 0d0d0abec1ba7e..729efba1878e93 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -289,7 +289,12 @@ def importfile(path): """Import a Python source file or compiled file given its path.""" magic = importlib.util.MAGIC_NUMBER with open(path, 'rb') as file: - is_bytecode = magic == file.read(len(magic)) + first_bytes = file.read(len(magic)) + is_bytecode = first_bytes in (magic, + # Issue #29537: handle issue27286 + # bytecode incompatibility + # See Lib/importlib/_bootstrap_external.py + importlib.util._BACKCOMPAT_MAGIC_NUMBER) filename = os.path.basename(path) name, ext = os.path.splitext(filename) if is_bytecode: diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index 9cb0d38669be58..94501de061980a 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -52,15 +52,15 @@ >>> f(1, 2, **{'a': -1, 'b': 5}, **{'a': 4, 'c': 6}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: function got multiple values for keyword argument 'a' >>> f(1, 2, **{'a': -1, 'b': 5}, a=4, c=6) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: function got multiple values for keyword argument 'a' >>> f(1, 2, a=3, **{'a': 4}, **{'a': 5}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'a' + TypeError: function got multiple values for keyword argument 'a' >>> f(1, 2, 3, *[4, 5], **{'a':6, 'b':7}) (1, 2, 3, 4, 5) {'a': 6, 'b': 7} >>> f(1, 2, 3, x=4, y=5, *(6, 7), **{'a':8, 'b': 9}) diff --git a/Lib/test/test_importlib/source/test_file_loader.py b/Lib/test/test_importlib/source/test_file_loader.py index 73f4c620706ba6..6d5a886d532056 100644 --- a/Lib/test/test_importlib/source/test_file_loader.py +++ b/Lib/test/test_importlib/source/test_file_loader.py @@ -603,5 +603,109 @@ class SourcelessLoaderBadBytecodeTestPEP302(SourcelessLoaderBadBytecodeTest, util=importlib_util) +########################################################################### +# Issue #29537: Test backwards compatibility with legacy 3.5.0/1/2 bytecode +########################################################################### + +class LegacyBytecodeTest: + + def _test_legacy_magic(self, test, *, del_source=False): + # Replace the default magic number with one copied from a pyc file + # generated by Python 3.5.2 + with util.create_modules('_temp') as mapping: + bc_path = self.manipulate_bytecode('_temp', mapping, + lambda bc: b'\x16\r\r\n' + bc[4:]) + test('_temp', mapping, bc_path) + +LegacyBytecodeTestPEP451 = BadBytecodeTestPEP451 +LegacyBytecodeTestPEP302 = BadBytecodeTestPEP302 + +# SourceLoader via both PEP 451 and 302 hooks + +class SourceLoaderLegacyBytecodeTest(LegacyBytecodeTest): + + @classmethod + def setUpClass(cls): + cls.loader = cls.machinery.SourceFileLoader + + @util.writes_bytecode_files + def test_legacy_magic(self): + # The magic number from 3.5.0/1/2 should be accepted as is + def test(name, mapping, bytecode_path): + self.import_(mapping[name], name) + with open(bytecode_path, 'rb') as bytecode_file: + self.assertEqual(bytecode_file.read(4), + self.util._BACKCOMPAT_MAGIC_NUMBER) + + self._test_legacy_magic(test) + + +class SourceLoaderLegacyBytecodeTestPEP451( + SourceLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP451): + pass + + +(Frozen_SourceLegacyBytecodePEP451, + Source_SourceLegacyBytecodePEP451 + ) = util.test_both(SourceLoaderLegacyBytecodeTestPEP451, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + + +class SourceLoaderLegacyBytecodeTestPEP302( + SourceLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP302): + pass + + +(Frozen_SourceLegacyBytecodePEP302, + Source_SourceLegacyBytecodePEP302 + ) = util.test_both(SourceLoaderLegacyBytecodeTestPEP302, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + +# SourcelessLoader via both PEP 451 and 302 hooks + +class SourcelessLoaderLegacyBytecodeTest(LegacyBytecodeTest): + + @classmethod + def setUpClass(cls): + cls.loader = cls.machinery.SourcelessFileLoader + + + @util.writes_bytecode_files + def test_legacy_magic(self): + # The magic number from 3.5.0/1/2 should be accepted as is + def test(name, mapping, bytecode_path): + self.import_(bytecode_path, name) + with open(bytecode_path, 'rb') as bytecode_file: + self.assertEqual(bytecode_file.read(4), + self.util._BACKCOMPAT_MAGIC_NUMBER) + + self._test_legacy_magic(test) + +class SourcelessLoaderLegacyBytecodeTestPEP451( + SourcelessLoaderLegacyBytecodeTest, LegacyBytecodeTestPEP451): + pass + +(Frozen_SourcelessLegacyBytecodePEP451, + Source_SourcelessLegacyBytecodePEP451 + ) = util.test_both(SourcelessLoaderLegacyBytecodeTestPEP451, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + + +class SourcelessLoaderLegacyBytecodeTestPEP302(SourcelessLoaderLegacyBytecodeTest, + LegacyBytecodeTestPEP302): + pass + + +(Frozen_SourcelessLegacyBytecodePEP302, + Source_SourcelessLegacyBytecodePEP302 + ) = util.test_both(SourcelessLoaderLegacyBytecodeTestPEP302, importlib=importlib, + machinery=machinery, abc=importlib_abc, + util=importlib_util) + +# End of Issue #29537 legacy bytecode compatibility tests + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_unpack_ex.py b/Lib/test/test_unpack_ex.py index 74346b42054f8e..43cf6385f07bd4 100644 --- a/Lib/test/test_unpack_ex.py +++ b/Lib/test/test_unpack_ex.py @@ -251,7 +251,7 @@ >>> f(x=5, **{'x': 3}, **{'x': 2}) Traceback (most recent call last): ... - TypeError: f() got multiple values for keyword argument 'x' + TypeError: function got multiple values for keyword argument 'x' >>> f(**{1: 3}, **{1: 5}) Traceback (most recent call last): diff --git a/Misc/NEWS b/Misc/NEWS index 03f8286f080ba6..82f9f9a1f58b07 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,12 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- Issue #29537: Restore runtime compatibility with bytecode files generated by + CPython 3.5.0 and 3.5.1, and adjust the eval loop to avoid the problems that + could be caused by the malformed variant of the BUILD_MAP_UNPACK_WITH_CALL + opcode that they may contain. Patch by Petr Viktorin, Serhiy Storchaka, + and Nick Coghlan. + - Issue #28598: Support __rmod__ for subclasses of str being called before str.__mod__. Patch by Martijn Pieters. diff --git a/Modules/zipimport.c b/Modules/zipimport.c index 7473a8fe877875..a693fbbf6e280e 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -1263,6 +1263,11 @@ eq_mtime(time_t t1, time_t t2) return d <= 1; } +/* Issue #29537: handle issue27286 bytecode incompatibility + * See Lib/importlib/_bootstrap_external.py for general discussion + */ +extern PY_UINT32_T _Py_BACKCOMPAT_MAGIC_NUMBER; + /* Given the contents of a .py[co] file in a buffer, unmarshal the data and return the code object. Return None if it the magic word doesn't match (we do this instead of raising an exception as we fall back @@ -1274,6 +1279,7 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) PyObject *code; unsigned char *buf = (unsigned char *)PyBytes_AsString(data); Py_ssize_t size = PyBytes_Size(data); + PY_UINT32_T magic; if (size < 12) { PyErr_SetString(ZipImportError, @@ -1281,7 +1287,10 @@ unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) return NULL; } - if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) { + magic = get_uint32(buf); + if (magic != (unsigned int)PyImport_GetMagicNumber() + /* Issue #29537: handle issue27286 bytecode incompatibility */ + && magic != _Py_BACKCOMPAT_MAGIC_NUMBER) { if (Py_VerboseFlag) { PySys_FormatStderr("# %R has bad magic\n", pathname); diff --git a/Python/ceval.c b/Python/ceval.c index 62badebca6502d..9ae8653f7e4e84 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2672,14 +2672,22 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (PyErr_ExceptionMatches(PyExc_AttributeError) || !PyMapping_Check(arg)) { int function_location = (oparg>>8) & 0xff; - PyObject *func = ( - PEEK(function_location + num_maps)); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - arg->ob_type->tp_name); + if (function_location == 1) { + PyObject *func = ( + PEEK(function_location + num_maps)); + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + arg->ob_type->tp_name); + } + else { + PyErr_Format(PyExc_TypeError, + "argument after ** " + "must be a mapping, not %.200s", + arg->ob_type->tp_name); + } } Py_DECREF(sum); goto error; @@ -2689,21 +2697,34 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) Py_ssize_t idx = 0; PyObject *key; int function_location = (oparg>>8) & 0xff; - PyObject *func = PEEK(function_location + num_maps); Py_hash_t hash; _PySet_NextEntry(intersection, &idx, &key, &hash); - if (!PyUnicode_Check(key)) { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s keywords must be strings", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func)); - } else { - PyErr_Format(PyExc_TypeError, - "%.200s%.200s got multiple " - "values for keyword argument '%U'", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - key); + if (function_location == 1) { + PyObject *func = PEEK(function_location + num_maps); + if (!PyUnicode_Check(key)) { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s keywords must be strings", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func)); + } else { + PyErr_Format(PyExc_TypeError, + "%.200s%.200s got multiple " + "values for keyword argument '%U'", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + key); + } + } + else { + if (!PyUnicode_Check(key)) { + PyErr_SetString(PyExc_TypeError, + "keywords must be strings"); + } else { + PyErr_Format(PyExc_TypeError, + "function got multiple " + "values for keyword argument '%U'", + key); + } } Py_DECREF(intersection); Py_DECREF(sum); @@ -2716,13 +2737,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (PyErr_ExceptionMatches(PyExc_AttributeError)) { if (with_call) { int function_location = (oparg>>8) & 0xff; - PyObject *func = PEEK(function_location + num_maps); - PyErr_Format(PyExc_TypeError, - "%.200s%.200s argument after ** " - "must be a mapping, not %.200s", - PyEval_GetFuncName(func), - PyEval_GetFuncDesc(func), - arg->ob_type->tp_name); + if (function_location == 1) { + PyObject *func = PEEK(function_location + num_maps); + PyErr_Format(PyExc_TypeError, + "%.200s%.200s argument after ** " + "must be a mapping, not %.200s", + PyEval_GetFuncName(func), + PyEval_GetFuncDesc(func), + arg->ob_type->tp_name); + } + else { + PyErr_Format(PyExc_TypeError, + "argument after ** " + "must be a mapping, not %.200s", + arg->ob_type->tp_name); + } } else { PyErr_Format(PyExc_TypeError, diff --git a/Python/import.c b/Python/import.c index 3579273ae0fefe..ea8bc00a73a782 100644 --- a/Python/import.c +++ b/Python/import.c @@ -483,9 +483,17 @@ PyImport_Cleanup(void) #undef STORE_MODULE_WEAKREF } +/* Issue #29537: handle issue27286 bytecode incompatibility + * + * In order to avoid forcing recompilation of all extension modules, we export + * the legacy 3.5.0 magic number here rather than putting it in a header file. + * + * See Lib/importlib/_bootstrap_external.py for general discussion + */ +PY_UINT32_T _Py_BACKCOMPAT_MAGIC_NUMBER = 168627478; +PY_UINT32_T _Py_BACKCOMPAT_HALF_MAGIC = 3350; /* Helper for pythonrun.c -- return magic number and tag. */ - long PyImport_GetMagicNumber(void) { diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 5ee843a4638a24..f337c8b5b9096a 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -1,8 +1,8 @@ /* Auto-generated by Programs/_freeze_importlib.c */ const unsigned char _Py_M__importlib_external[] = { 99,0,0,0,0,0,0,0,0,0,0,0,0,7,0,0, - 0,64,0,0,0,115,244,2,0,0,100,0,0,90,0,0, - 100,96,0,90,1,0,100,97,0,90,2,0,101,2,0,101, + 0,64,0,0,0,115,40,3,0,0,100,0,0,90,0,0, + 100,99,0,90,1,0,100,100,0,90,2,0,101,2,0,101, 1,0,23,90,3,0,100,4,0,100,5,0,132,0,0,90, 4,0,100,6,0,100,7,0,132,0,0,90,5,0,100,8, 0,100,9,0,132,0,0,90,6,0,100,10,0,100,11,0, @@ -14,2592 +14,2605 @@ const unsigned char _Py_M__importlib_external[] = { 0,101,14,0,101,13,0,106,15,0,131,1,0,90,16,0, 100,25,0,106,17,0,100,26,0,100,27,0,131,2,0,100, 28,0,23,90,18,0,101,19,0,106,20,0,101,18,0,100, - 27,0,131,2,0,90,21,0,100,29,0,90,22,0,100,30, - 0,90,23,0,100,31,0,103,1,0,90,24,0,100,32,0, - 103,1,0,90,25,0,101,25,0,4,90,26,0,90,27,0, - 100,33,0,100,34,0,100,33,0,100,35,0,100,36,0,132, - 1,1,90,28,0,100,37,0,100,38,0,132,0,0,90,29, - 0,100,39,0,100,40,0,132,0,0,90,30,0,100,41,0, - 100,42,0,132,0,0,90,31,0,100,43,0,100,44,0,132, - 0,0,90,32,0,100,45,0,100,46,0,100,47,0,100,48, - 0,132,0,1,90,33,0,100,49,0,100,50,0,132,0,0, - 90,34,0,100,51,0,100,52,0,132,0,0,90,35,0,100, - 33,0,100,33,0,100,33,0,100,53,0,100,54,0,132,3, - 0,90,36,0,100,33,0,100,33,0,100,33,0,100,55,0, - 100,56,0,132,3,0,90,37,0,100,57,0,100,57,0,100, - 58,0,100,59,0,132,2,0,90,38,0,100,60,0,100,61, - 0,132,0,0,90,39,0,101,40,0,131,0,0,90,41,0, - 100,33,0,100,62,0,100,33,0,100,63,0,101,41,0,100, - 64,0,100,65,0,132,1,2,90,42,0,71,100,66,0,100, - 67,0,132,0,0,100,67,0,131,2,0,90,43,0,71,100, - 68,0,100,69,0,132,0,0,100,69,0,131,2,0,90,44, - 0,71,100,70,0,100,71,0,132,0,0,100,71,0,101,44, - 0,131,3,0,90,45,0,71,100,72,0,100,73,0,132,0, - 0,100,73,0,131,2,0,90,46,0,71,100,74,0,100,75, - 0,132,0,0,100,75,0,101,46,0,101,45,0,131,4,0, - 90,47,0,71,100,76,0,100,77,0,132,0,0,100,77,0, - 101,46,0,101,44,0,131,4,0,90,48,0,103,0,0,90, - 49,0,71,100,78,0,100,79,0,132,0,0,100,79,0,101, - 46,0,101,44,0,131,4,0,90,50,0,71,100,80,0,100, - 81,0,132,0,0,100,81,0,131,2,0,90,51,0,71,100, - 82,0,100,83,0,132,0,0,100,83,0,131,2,0,90,52, - 0,71,100,84,0,100,85,0,132,0,0,100,85,0,131,2, - 0,90,53,0,71,100,86,0,100,87,0,132,0,0,100,87, - 0,131,2,0,90,54,0,100,33,0,100,88,0,100,89,0, - 132,1,0,90,55,0,100,90,0,100,91,0,132,0,0,90, - 56,0,100,92,0,100,93,0,132,0,0,90,57,0,100,94, - 0,100,95,0,132,0,0,90,58,0,100,33,0,83,41,98, - 97,94,1,0,0,67,111,114,101,32,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,32,111,102,32,112,97,116,104, - 45,98,97,115,101,100,32,105,109,112,111,114,116,46,10,10, - 84,104,105,115,32,109,111,100,117,108,101,32,105,115,32,78, - 79,84,32,109,101,97,110,116,32,116,111,32,98,101,32,100, - 105,114,101,99,116,108,121,32,105,109,112,111,114,116,101,100, - 33,32,73,116,32,104,97,115,32,98,101,101,110,32,100,101, - 115,105,103,110,101,100,32,115,117,99,104,10,116,104,97,116, - 32,105,116,32,99,97,110,32,98,101,32,98,111,111,116,115, - 116,114,97,112,112,101,100,32,105,110,116,111,32,80,121,116, - 104,111,110,32,97,115,32,116,104,101,32,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,32,111,102,32,105,109,112, - 111,114,116,46,32,65,115,10,115,117,99,104,32,105,116,32, - 114,101,113,117,105,114,101,115,32,116,104,101,32,105,110,106, - 101,99,116,105,111,110,32,111,102,32,115,112,101,99,105,102, - 105,99,32,109,111,100,117,108,101,115,32,97,110,100,32,97, - 116,116,114,105,98,117,116,101,115,32,105,110,32,111,114,100, - 101,114,32,116,111,10,119,111,114,107,46,32,79,110,101,32, - 115,104,111,117,108,100,32,117,115,101,32,105,109,112,111,114, - 116,108,105,98,32,97,115,32,116,104,101,32,112,117,98,108, - 105,99,45,102,97,99,105,110,103,32,118,101,114,115,105,111, - 110,32,111,102,32,116,104,105,115,32,109,111,100,117,108,101, - 46,10,10,218,3,119,105,110,218,6,99,121,103,119,105,110, - 218,6,100,97,114,119,105,110,99,0,0,0,0,0,0,0, - 0,1,0,0,0,3,0,0,0,3,0,0,0,115,88,0, - 0,0,116,0,0,106,1,0,106,2,0,116,3,0,131,1, - 0,114,72,0,116,0,0,106,1,0,106,2,0,116,4,0, - 131,1,0,114,45,0,100,1,0,137,0,0,110,6,0,100, - 2,0,137,0,0,135,0,0,102,1,0,100,3,0,100,4, - 0,134,0,0,125,0,0,110,12,0,100,5,0,100,4,0, - 132,0,0,125,0,0,124,0,0,83,41,6,78,90,12,80, - 89,84,72,79,78,67,65,83,69,79,75,115,12,0,0,0, - 80,89,84,72,79,78,67,65,83,69,79,75,99,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,19,0,0, - 0,115,13,0,0,0,136,0,0,116,0,0,106,1,0,107, - 6,0,83,41,1,122,53,84,114,117,101,32,105,102,32,102, + 27,0,131,2,0,90,21,0,101,21,0,100,29,0,107,3, + 0,114,236,0,100,30,0,90,22,0,101,23,0,101,22,0, + 131,1,0,130,1,0,100,31,0,106,17,0,100,26,0,100, + 27,0,131,2,0,100,28,0,23,90,24,0,100,32,0,90, + 25,0,100,33,0,90,26,0,100,34,0,103,1,0,90,27, + 0,100,35,0,103,1,0,90,28,0,101,28,0,4,90,29, + 0,90,30,0,100,36,0,100,37,0,100,36,0,100,38,0, + 100,39,0,132,1,1,90,31,0,100,40,0,100,41,0,132, + 0,0,90,32,0,100,42,0,100,43,0,132,0,0,90,33, + 0,100,44,0,100,45,0,132,0,0,90,34,0,100,46,0, + 100,47,0,132,0,0,90,35,0,100,48,0,100,49,0,100, + 50,0,100,51,0,132,0,1,90,36,0,100,52,0,100,53, + 0,132,0,0,90,37,0,100,54,0,100,55,0,132,0,0, + 90,38,0,100,36,0,100,36,0,100,36,0,100,56,0,100, + 57,0,132,3,0,90,39,0,100,36,0,100,36,0,100,36, + 0,100,58,0,100,59,0,132,3,0,90,40,0,100,60,0, + 100,60,0,100,61,0,100,62,0,132,2,0,90,41,0,100, + 63,0,100,64,0,132,0,0,90,42,0,101,43,0,131,0, + 0,90,44,0,100,36,0,100,65,0,100,36,0,100,66,0, + 101,44,0,100,67,0,100,68,0,132,1,2,90,45,0,71, + 100,69,0,100,70,0,132,0,0,100,70,0,131,2,0,90, + 46,0,71,100,71,0,100,72,0,132,0,0,100,72,0,131, + 2,0,90,47,0,71,100,73,0,100,74,0,132,0,0,100, + 74,0,101,47,0,131,3,0,90,48,0,71,100,75,0,100, + 76,0,132,0,0,100,76,0,131,2,0,90,49,0,71,100, + 77,0,100,78,0,132,0,0,100,78,0,101,49,0,101,48, + 0,131,4,0,90,50,0,71,100,79,0,100,80,0,132,0, + 0,100,80,0,101,49,0,101,47,0,131,4,0,90,51,0, + 103,0,0,90,52,0,71,100,81,0,100,82,0,132,0,0, + 100,82,0,101,49,0,101,47,0,131,4,0,90,53,0,71, + 100,83,0,100,84,0,132,0,0,100,84,0,131,2,0,90, + 54,0,71,100,85,0,100,86,0,132,0,0,100,86,0,131, + 2,0,90,55,0,71,100,87,0,100,88,0,132,0,0,100, + 88,0,131,2,0,90,56,0,71,100,89,0,100,90,0,132, + 0,0,100,90,0,131,2,0,90,57,0,100,36,0,100,91, + 0,100,92,0,132,1,0,90,58,0,100,93,0,100,94,0, + 132,0,0,90,59,0,100,95,0,100,96,0,132,0,0,90, + 60,0,100,97,0,100,98,0,132,0,0,90,61,0,100,36, + 0,83,41,101,97,94,1,0,0,67,111,114,101,32,105,109, + 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, + 112,97,116,104,45,98,97,115,101,100,32,105,109,112,111,114, + 116,46,10,10,84,104,105,115,32,109,111,100,117,108,101,32, + 105,115,32,78,79,84,32,109,101,97,110,116,32,116,111,32, + 98,101,32,100,105,114,101,99,116,108,121,32,105,109,112,111, + 114,116,101,100,33,32,73,116,32,104,97,115,32,98,101,101, + 110,32,100,101,115,105,103,110,101,100,32,115,117,99,104,10, + 116,104,97,116,32,105,116,32,99,97,110,32,98,101,32,98, + 111,111,116,115,116,114,97,112,112,101,100,32,105,110,116,111, + 32,80,121,116,104,111,110,32,97,115,32,116,104,101,32,105, + 109,112,108,101,109,101,110,116,97,116,105,111,110,32,111,102, + 32,105,109,112,111,114,116,46,32,65,115,10,115,117,99,104, + 32,105,116,32,114,101,113,117,105,114,101,115,32,116,104,101, + 32,105,110,106,101,99,116,105,111,110,32,111,102,32,115,112, + 101,99,105,102,105,99,32,109,111,100,117,108,101,115,32,97, + 110,100,32,97,116,116,114,105,98,117,116,101,115,32,105,110, + 32,111,114,100,101,114,32,116,111,10,119,111,114,107,46,32, + 79,110,101,32,115,104,111,117,108,100,32,117,115,101,32,105, + 109,112,111,114,116,108,105,98,32,97,115,32,116,104,101,32, + 112,117,98,108,105,99,45,102,97,99,105,110,103,32,118,101, + 114,115,105,111,110,32,111,102,32,116,104,105,115,32,109,111, + 100,117,108,101,46,10,10,218,3,119,105,110,218,6,99,121, + 103,119,105,110,218,6,100,97,114,119,105,110,99,0,0,0, + 0,0,0,0,0,1,0,0,0,3,0,0,0,3,0,0, + 0,115,88,0,0,0,116,0,0,106,1,0,106,2,0,116, + 3,0,131,1,0,114,72,0,116,0,0,106,1,0,106,2, + 0,116,4,0,131,1,0,114,45,0,100,1,0,137,0,0, + 110,6,0,100,2,0,137,0,0,135,0,0,102,1,0,100, + 3,0,100,4,0,134,0,0,125,0,0,110,12,0,100,5, + 0,100,4,0,132,0,0,125,0,0,124,0,0,83,41,6, + 78,90,12,80,89,84,72,79,78,67,65,83,69,79,75,115, + 12,0,0,0,80,89,84,72,79,78,67,65,83,69,79,75, + 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, + 0,19,0,0,0,115,13,0,0,0,136,0,0,116,0,0, + 106,1,0,107,6,0,83,41,1,122,53,84,114,117,101,32, + 105,102,32,102,105,108,101,110,97,109,101,115,32,109,117,115, + 116,32,98,101,32,99,104,101,99,107,101,100,32,99,97,115, + 101,45,105,110,115,101,110,115,105,116,105,118,101,108,121,46, + 41,2,218,3,95,111,115,90,7,101,110,118,105,114,111,110, + 169,0,41,1,218,3,107,101,121,114,4,0,0,0,250,38, + 60,102,114,111,122,101,110,32,105,109,112,111,114,116,108,105, + 98,46,95,98,111,111,116,115,116,114,97,112,95,101,120,116, + 101,114,110,97,108,62,218,11,95,114,101,108,97,120,95,99, + 97,115,101,37,0,0,0,115,2,0,0,0,0,2,122,37, + 95,109,97,107,101,95,114,101,108,97,120,95,99,97,115,101, + 46,60,108,111,99,97,108,115,62,46,95,114,101,108,97,120, + 95,99,97,115,101,99,0,0,0,0,0,0,0,0,0,0, + 0,0,1,0,0,0,83,0,0,0,115,4,0,0,0,100, + 1,0,83,41,2,122,53,84,114,117,101,32,105,102,32,102, 105,108,101,110,97,109,101,115,32,109,117,115,116,32,98,101, 32,99,104,101,99,107,101,100,32,99,97,115,101,45,105,110, - 115,101,110,115,105,116,105,118,101,108,121,46,41,2,218,3, - 95,111,115,90,7,101,110,118,105,114,111,110,169,0,41,1, - 218,3,107,101,121,114,4,0,0,0,250,38,60,102,114,111, - 122,101,110,32,105,109,112,111,114,116,108,105,98,46,95,98, - 111,111,116,115,116,114,97,112,95,101,120,116,101,114,110,97, - 108,62,218,11,95,114,101,108,97,120,95,99,97,115,101,37, - 0,0,0,115,2,0,0,0,0,2,122,37,95,109,97,107, - 101,95,114,101,108,97,120,95,99,97,115,101,46,60,108,111, - 99,97,108,115,62,46,95,114,101,108,97,120,95,99,97,115, - 101,99,0,0,0,0,0,0,0,0,0,0,0,0,1,0, - 0,0,83,0,0,0,115,4,0,0,0,100,1,0,83,41, - 2,122,53,84,114,117,101,32,105,102,32,102,105,108,101,110, - 97,109,101,115,32,109,117,115,116,32,98,101,32,99,104,101, - 99,107,101,100,32,99,97,115,101,45,105,110,115,101,110,115, - 105,116,105,118,101,108,121,46,70,114,4,0,0,0,114,4, + 115,101,110,115,105,116,105,118,101,108,121,46,70,114,4,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,114,7,0,0,0,41,0,0,0,115, + 2,0,0,0,0,2,41,5,218,3,115,121,115,218,8,112, + 108,97,116,102,111,114,109,218,10,115,116,97,114,116,115,119, + 105,116,104,218,27,95,67,65,83,69,95,73,78,83,69,78, + 83,73,84,73,86,69,95,80,76,65,84,70,79,82,77,83, + 218,35,95,67,65,83,69,95,73,78,83,69,78,83,73,84, + 73,86,69,95,80,76,65,84,70,79,82,77,83,95,83,84, + 82,95,75,69,89,41,1,114,7,0,0,0,114,4,0,0, + 0,41,1,114,5,0,0,0,114,6,0,0,0,218,16,95, + 109,97,107,101,95,114,101,108,97,120,95,99,97,115,101,30, + 0,0,0,115,14,0,0,0,0,1,18,1,18,1,9,2, + 6,2,21,4,12,3,114,13,0,0,0,99,1,0,0,0, + 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, + 115,26,0,0,0,116,0,0,124,0,0,131,1,0,100,1, + 0,64,106,1,0,100,2,0,100,3,0,131,2,0,83,41, + 4,122,42,67,111,110,118,101,114,116,32,97,32,51,50,45, + 98,105,116,32,105,110,116,101,103,101,114,32,116,111,32,108, + 105,116,116,108,101,45,101,110,100,105,97,110,46,108,3,0, + 0,0,255,127,255,127,3,0,233,4,0,0,0,218,6,108, + 105,116,116,108,101,41,2,218,3,105,110,116,218,8,116,111, + 95,98,121,116,101,115,41,1,218,1,120,114,4,0,0,0, + 114,4,0,0,0,114,6,0,0,0,218,7,95,119,95,108, + 111,110,103,47,0,0,0,115,2,0,0,0,0,2,114,19, + 0,0,0,99,1,0,0,0,0,0,0,0,1,0,0,0, + 3,0,0,0,67,0,0,0,115,16,0,0,0,116,0,0, + 106,1,0,124,0,0,100,1,0,131,2,0,83,41,2,122, + 47,67,111,110,118,101,114,116,32,52,32,98,121,116,101,115, + 32,105,110,32,108,105,116,116,108,101,45,101,110,100,105,97, + 110,32,116,111,32,97,110,32,105,110,116,101,103,101,114,46, + 114,15,0,0,0,41,2,114,16,0,0,0,218,10,102,114, + 111,109,95,98,121,116,101,115,41,1,90,9,105,110,116,95, + 98,121,116,101,115,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,218,7,95,114,95,108,111,110,103,52,0,0, + 0,115,2,0,0,0,0,2,114,21,0,0,0,99,0,0, + 0,0,0,0,0,0,1,0,0,0,3,0,0,0,71,0, + 0,0,115,26,0,0,0,116,0,0,106,1,0,100,1,0, + 100,2,0,132,0,0,124,0,0,68,131,1,0,131,1,0, + 83,41,3,122,31,82,101,112,108,97,99,101,109,101,110,116, + 32,102,111,114,32,111,115,46,112,97,116,104,46,106,111,105, + 110,40,41,46,99,1,0,0,0,0,0,0,0,2,0,0, + 0,4,0,0,0,83,0,0,0,115,37,0,0,0,103,0, + 0,124,0,0,93,27,0,125,1,0,124,1,0,114,6,0, + 124,1,0,106,0,0,116,1,0,131,1,0,145,2,0,113, + 6,0,83,114,4,0,0,0,41,2,218,6,114,115,116,114, + 105,112,218,15,112,97,116,104,95,115,101,112,97,114,97,116, + 111,114,115,41,2,218,2,46,48,218,4,112,97,114,116,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,250,10, + 60,108,105,115,116,99,111,109,112,62,59,0,0,0,115,2, + 0,0,0,9,1,122,30,95,112,97,116,104,95,106,111,105, + 110,46,60,108,111,99,97,108,115,62,46,60,108,105,115,116, + 99,111,109,112,62,41,2,218,8,112,97,116,104,95,115,101, + 112,218,4,106,111,105,110,41,1,218,10,112,97,116,104,95, + 112,97,114,116,115,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,218,10,95,112,97,116,104,95,106,111,105,110, + 57,0,0,0,115,4,0,0,0,0,2,15,1,114,30,0, + 0,0,99,1,0,0,0,0,0,0,0,5,0,0,0,5, + 0,0,0,67,0,0,0,115,134,0,0,0,116,0,0,116, + 1,0,131,1,0,100,1,0,107,2,0,114,52,0,124,0, + 0,106,2,0,116,3,0,131,1,0,92,3,0,125,1,0, + 125,2,0,125,3,0,124,1,0,124,3,0,102,2,0,83, + 120,69,0,116,4,0,124,0,0,131,1,0,68,93,55,0, + 125,4,0,124,4,0,116,1,0,107,6,0,114,65,0,124, + 0,0,106,5,0,124,4,0,100,2,0,100,1,0,131,1, + 1,92,2,0,125,1,0,125,3,0,124,1,0,124,3,0, + 102,2,0,83,113,65,0,87,100,3,0,124,0,0,102,2, + 0,83,41,4,122,32,82,101,112,108,97,99,101,109,101,110, + 116,32,102,111,114,32,111,115,46,112,97,116,104,46,115,112, + 108,105,116,40,41,46,233,1,0,0,0,90,8,109,97,120, + 115,112,108,105,116,218,0,41,6,218,3,108,101,110,114,23, + 0,0,0,218,10,114,112,97,114,116,105,116,105,111,110,114, + 27,0,0,0,218,8,114,101,118,101,114,115,101,100,218,6, + 114,115,112,108,105,116,41,5,218,4,112,97,116,104,90,5, + 102,114,111,110,116,218,1,95,218,4,116,97,105,108,114,18, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,7,0,0,0,41,0,0,0,115,2,0,0,0, - 0,2,41,5,218,3,115,121,115,218,8,112,108,97,116,102, - 111,114,109,218,10,115,116,97,114,116,115,119,105,116,104,218, - 27,95,67,65,83,69,95,73,78,83,69,78,83,73,84,73, - 86,69,95,80,76,65,84,70,79,82,77,83,218,35,95,67, - 65,83,69,95,73,78,83,69,78,83,73,84,73,86,69,95, - 80,76,65,84,70,79,82,77,83,95,83,84,82,95,75,69, - 89,41,1,114,7,0,0,0,114,4,0,0,0,41,1,114, - 5,0,0,0,114,6,0,0,0,218,16,95,109,97,107,101, - 95,114,101,108,97,120,95,99,97,115,101,30,0,0,0,115, - 14,0,0,0,0,1,18,1,18,1,9,2,6,2,21,4, - 12,3,114,13,0,0,0,99,1,0,0,0,0,0,0,0, - 1,0,0,0,3,0,0,0,67,0,0,0,115,26,0,0, - 0,116,0,0,124,0,0,131,1,0,100,1,0,64,106,1, - 0,100,2,0,100,3,0,131,2,0,83,41,4,122,42,67, - 111,110,118,101,114,116,32,97,32,51,50,45,98,105,116,32, - 105,110,116,101,103,101,114,32,116,111,32,108,105,116,116,108, - 101,45,101,110,100,105,97,110,46,108,3,0,0,0,255,127, - 255,127,3,0,233,4,0,0,0,218,6,108,105,116,116,108, - 101,41,2,218,3,105,110,116,218,8,116,111,95,98,121,116, - 101,115,41,1,218,1,120,114,4,0,0,0,114,4,0,0, - 0,114,6,0,0,0,218,7,95,119,95,108,111,110,103,47, - 0,0,0,115,2,0,0,0,0,2,114,19,0,0,0,99, - 1,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0, - 67,0,0,0,115,16,0,0,0,116,0,0,106,1,0,124, - 0,0,100,1,0,131,2,0,83,41,2,122,47,67,111,110, - 118,101,114,116,32,52,32,98,121,116,101,115,32,105,110,32, - 108,105,116,116,108,101,45,101,110,100,105,97,110,32,116,111, - 32,97,110,32,105,110,116,101,103,101,114,46,114,15,0,0, - 0,41,2,114,16,0,0,0,218,10,102,114,111,109,95,98, - 121,116,101,115,41,1,90,9,105,110,116,95,98,121,116,101, - 115,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,7,95,114,95,108,111,110,103,52,0,0,0,115,2,0, - 0,0,0,2,114,21,0,0,0,99,0,0,0,0,0,0, - 0,0,1,0,0,0,3,0,0,0,71,0,0,0,115,26, - 0,0,0,116,0,0,106,1,0,100,1,0,100,2,0,132, - 0,0,124,0,0,68,131,1,0,131,1,0,83,41,3,122, - 31,82,101,112,108,97,99,101,109,101,110,116,32,102,111,114, - 32,111,115,46,112,97,116,104,46,106,111,105,110,40,41,46, - 99,1,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,83,0,0,0,115,37,0,0,0,103,0,0,124,0,0, - 93,27,0,125,1,0,124,1,0,114,6,0,124,1,0,106, - 0,0,116,1,0,131,1,0,145,2,0,113,6,0,83,114, - 4,0,0,0,41,2,218,6,114,115,116,114,105,112,218,15, - 112,97,116,104,95,115,101,112,97,114,97,116,111,114,115,41, - 2,218,2,46,48,218,4,112,97,114,116,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,250,10,60,108,105,115, - 116,99,111,109,112,62,59,0,0,0,115,2,0,0,0,9, - 1,122,30,95,112,97,116,104,95,106,111,105,110,46,60,108, - 111,99,97,108,115,62,46,60,108,105,115,116,99,111,109,112, - 62,41,2,218,8,112,97,116,104,95,115,101,112,218,4,106, - 111,105,110,41,1,218,10,112,97,116,104,95,112,97,114,116, - 115,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,10,95,112,97,116,104,95,106,111,105,110,57,0,0,0, - 115,4,0,0,0,0,2,15,1,114,30,0,0,0,99,1, - 0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,67, - 0,0,0,115,134,0,0,0,116,0,0,116,1,0,131,1, - 0,100,1,0,107,2,0,114,52,0,124,0,0,106,2,0, - 116,3,0,131,1,0,92,3,0,125,1,0,125,2,0,125, - 3,0,124,1,0,124,3,0,102,2,0,83,120,69,0,116, - 4,0,124,0,0,131,1,0,68,93,55,0,125,4,0,124, - 4,0,116,1,0,107,6,0,114,65,0,124,0,0,106,5, - 0,124,4,0,100,2,0,100,1,0,131,1,1,92,2,0, - 125,1,0,125,3,0,124,1,0,124,3,0,102,2,0,83, - 113,65,0,87,100,3,0,124,0,0,102,2,0,83,41,4, - 122,32,82,101,112,108,97,99,101,109,101,110,116,32,102,111, - 114,32,111,115,46,112,97,116,104,46,115,112,108,105,116,40, - 41,46,233,1,0,0,0,90,8,109,97,120,115,112,108,105, - 116,218,0,41,6,218,3,108,101,110,114,23,0,0,0,218, - 10,114,112,97,114,116,105,116,105,111,110,114,27,0,0,0, - 218,8,114,101,118,101,114,115,101,100,218,6,114,115,112,108, - 105,116,41,5,218,4,112,97,116,104,90,5,102,114,111,110, - 116,218,1,95,218,4,116,97,105,108,114,18,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,6,0,0,0,218,11, - 95,112,97,116,104,95,115,112,108,105,116,63,0,0,0,115, - 16,0,0,0,0,2,18,1,24,1,10,1,19,1,12,1, - 27,1,14,1,114,40,0,0,0,99,1,0,0,0,0,0, - 0,0,1,0,0,0,2,0,0,0,67,0,0,0,115,13, - 0,0,0,116,0,0,106,1,0,124,0,0,131,1,0,83, - 41,1,122,126,83,116,97,116,32,116,104,101,32,112,97,116, - 104,46,10,10,32,32,32,32,77,97,100,101,32,97,32,115, - 101,112,97,114,97,116,101,32,102,117,110,99,116,105,111,110, - 32,116,111,32,109,97,107,101,32,105,116,32,101,97,115,105, - 101,114,32,116,111,32,111,118,101,114,114,105,100,101,32,105, - 110,32,101,120,112,101,114,105,109,101,110,116,115,10,32,32, - 32,32,40,101,46,103,46,32,99,97,99,104,101,32,115,116, - 97,116,32,114,101,115,117,108,116,115,41,46,10,10,32,32, - 32,32,41,2,114,3,0,0,0,90,4,115,116,97,116,41, - 1,114,37,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,218,10,95,112,97,116,104,95,115,116,97, - 116,75,0,0,0,115,2,0,0,0,0,7,114,41,0,0, - 0,99,2,0,0,0,0,0,0,0,3,0,0,0,11,0, - 0,0,67,0,0,0,115,58,0,0,0,121,16,0,116,0, - 0,124,0,0,131,1,0,125,2,0,87,110,22,0,4,116, - 1,0,107,10,0,114,40,0,1,1,1,100,1,0,83,89, - 110,1,0,88,124,2,0,106,2,0,100,2,0,64,124,1, - 0,107,2,0,83,41,3,122,49,84,101,115,116,32,119,104, - 101,116,104,101,114,32,116,104,101,32,112,97,116,104,32,105, - 115,32,116,104,101,32,115,112,101,99,105,102,105,101,100,32, - 109,111,100,101,32,116,121,112,101,46,70,105,0,240,0,0, - 41,3,114,41,0,0,0,218,7,79,83,69,114,114,111,114, - 218,7,115,116,95,109,111,100,101,41,3,114,37,0,0,0, - 218,4,109,111,100,101,90,9,115,116,97,116,95,105,110,102, - 111,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,18,95,112,97,116,104,95,105,115,95,109,111,100,101,95, - 116,121,112,101,85,0,0,0,115,10,0,0,0,0,2,3, - 1,16,1,13,1,9,1,114,45,0,0,0,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,13,0,0,0,116,0,0,124,0,0,100,1,0,131, - 2,0,83,41,2,122,31,82,101,112,108,97,99,101,109,101, + 0,0,218,11,95,112,97,116,104,95,115,112,108,105,116,63, + 0,0,0,115,16,0,0,0,0,2,18,1,24,1,10,1, + 19,1,12,1,27,1,14,1,114,40,0,0,0,99,1,0, + 0,0,0,0,0,0,1,0,0,0,2,0,0,0,67,0, + 0,0,115,13,0,0,0,116,0,0,106,1,0,124,0,0, + 131,1,0,83,41,1,122,126,83,116,97,116,32,116,104,101, + 32,112,97,116,104,46,10,10,32,32,32,32,77,97,100,101, + 32,97,32,115,101,112,97,114,97,116,101,32,102,117,110,99, + 116,105,111,110,32,116,111,32,109,97,107,101,32,105,116,32, + 101,97,115,105,101,114,32,116,111,32,111,118,101,114,114,105, + 100,101,32,105,110,32,101,120,112,101,114,105,109,101,110,116, + 115,10,32,32,32,32,40,101,46,103,46,32,99,97,99,104, + 101,32,115,116,97,116,32,114,101,115,117,108,116,115,41,46, + 10,10,32,32,32,32,41,2,114,3,0,0,0,90,4,115, + 116,97,116,41,1,114,37,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,218,10,95,112,97,116,104, + 95,115,116,97,116,75,0,0,0,115,2,0,0,0,0,7, + 114,41,0,0,0,99,2,0,0,0,0,0,0,0,3,0, + 0,0,11,0,0,0,67,0,0,0,115,58,0,0,0,121, + 16,0,116,0,0,124,0,0,131,1,0,125,2,0,87,110, + 22,0,4,116,1,0,107,10,0,114,40,0,1,1,1,100, + 1,0,83,89,110,1,0,88,124,2,0,106,2,0,100,2, + 0,64,124,1,0,107,2,0,83,41,3,122,49,84,101,115, + 116,32,119,104,101,116,104,101,114,32,116,104,101,32,112,97, + 116,104,32,105,115,32,116,104,101,32,115,112,101,99,105,102, + 105,101,100,32,109,111,100,101,32,116,121,112,101,46,70,105, + 0,240,0,0,41,3,114,41,0,0,0,218,7,79,83,69, + 114,114,111,114,218,7,115,116,95,109,111,100,101,41,3,114, + 37,0,0,0,218,4,109,111,100,101,90,9,115,116,97,116, + 95,105,110,102,111,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,218,18,95,112,97,116,104,95,105,115,95,109, + 111,100,101,95,116,121,112,101,85,0,0,0,115,10,0,0, + 0,0,2,3,1,16,1,13,1,9,1,114,45,0,0,0, + 99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0, + 0,67,0,0,0,115,13,0,0,0,116,0,0,124,0,0, + 100,1,0,131,2,0,83,41,2,122,31,82,101,112,108,97, + 99,101,109,101,110,116,32,102,111,114,32,111,115,46,112,97, + 116,104,46,105,115,102,105,108,101,46,105,0,128,0,0,41, + 1,114,45,0,0,0,41,1,114,37,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,218,12,95,112, + 97,116,104,95,105,115,102,105,108,101,94,0,0,0,115,2, + 0,0,0,0,2,114,46,0,0,0,99,1,0,0,0,0, + 0,0,0,1,0,0,0,3,0,0,0,67,0,0,0,115, + 31,0,0,0,124,0,0,115,18,0,116,0,0,106,1,0, + 131,0,0,125,0,0,116,2,0,124,0,0,100,1,0,131, + 2,0,83,41,2,122,30,82,101,112,108,97,99,101,109,101, 110,116,32,102,111,114,32,111,115,46,112,97,116,104,46,105, - 115,102,105,108,101,46,105,0,128,0,0,41,1,114,45,0, - 0,0,41,1,114,37,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,12,95,112,97,116,104,95, - 105,115,102,105,108,101,94,0,0,0,115,2,0,0,0,0, - 2,114,46,0,0,0,99,1,0,0,0,0,0,0,0,1, - 0,0,0,3,0,0,0,67,0,0,0,115,31,0,0,0, - 124,0,0,115,18,0,116,0,0,106,1,0,131,0,0,125, - 0,0,116,2,0,124,0,0,100,1,0,131,2,0,83,41, - 2,122,30,82,101,112,108,97,99,101,109,101,110,116,32,102, - 111,114,32,111,115,46,112,97,116,104,46,105,115,100,105,114, - 46,105,0,64,0,0,41,3,114,3,0,0,0,218,6,103, - 101,116,99,119,100,114,45,0,0,0,41,1,114,37,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,11,95,112,97,116,104,95,105,115,100,105,114,99,0,0, - 0,115,6,0,0,0,0,2,6,1,12,1,114,48,0,0, - 0,105,182,1,0,0,99,3,0,0,0,0,0,0,0,6, - 0,0,0,17,0,0,0,67,0,0,0,115,193,0,0,0, - 100,1,0,106,0,0,124,0,0,116,1,0,124,0,0,131, - 1,0,131,2,0,125,3,0,116,2,0,106,3,0,124,3, - 0,116,2,0,106,4,0,116,2,0,106,5,0,66,116,2, - 0,106,6,0,66,124,2,0,100,2,0,64,131,3,0,125, - 4,0,121,61,0,116,7,0,106,8,0,124,4,0,100,3, - 0,131,2,0,143,20,0,125,5,0,124,5,0,106,9,0, - 124,1,0,131,1,0,1,87,100,4,0,81,82,88,116,2, - 0,106,10,0,124,3,0,124,0,0,131,2,0,1,87,110, - 59,0,4,116,11,0,107,10,0,114,188,0,1,1,1,121, - 17,0,116,2,0,106,12,0,124,3,0,131,1,0,1,87, - 110,18,0,4,116,11,0,107,10,0,114,180,0,1,1,1, - 89,110,1,0,88,130,0,0,89,110,1,0,88,100,4,0, - 83,41,5,122,162,66,101,115,116,45,101,102,102,111,114,116, - 32,102,117,110,99,116,105,111,110,32,116,111,32,119,114,105, - 116,101,32,100,97,116,97,32,116,111,32,97,32,112,97,116, - 104,32,97,116,111,109,105,99,97,108,108,121,46,10,32,32, - 32,32,66,101,32,112,114,101,112,97,114,101,100,32,116,111, - 32,104,97,110,100,108,101,32,97,32,70,105,108,101,69,120, - 105,115,116,115,69,114,114,111,114,32,105,102,32,99,111,110, - 99,117,114,114,101,110,116,32,119,114,105,116,105,110,103,32, - 111,102,32,116,104,101,10,32,32,32,32,116,101,109,112,111, - 114,97,114,121,32,102,105,108,101,32,105,115,32,97,116,116, - 101,109,112,116,101,100,46,122,5,123,125,46,123,125,105,182, - 1,0,0,90,2,119,98,78,41,13,218,6,102,111,114,109, - 97,116,218,2,105,100,114,3,0,0,0,90,4,111,112,101, - 110,90,6,79,95,69,88,67,76,90,7,79,95,67,82,69, - 65,84,90,8,79,95,87,82,79,78,76,89,218,3,95,105, - 111,218,6,70,105,108,101,73,79,218,5,119,114,105,116,101, - 218,7,114,101,112,108,97,99,101,114,42,0,0,0,90,6, - 117,110,108,105,110,107,41,6,114,37,0,0,0,218,4,100, - 97,116,97,114,44,0,0,0,90,8,112,97,116,104,95,116, - 109,112,90,2,102,100,218,4,102,105,108,101,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,218,13,95,119,114, - 105,116,101,95,97,116,111,109,105,99,106,0,0,0,115,26, - 0,0,0,0,5,24,1,9,1,33,1,3,3,21,1,20, - 1,20,1,13,1,3,1,17,1,13,1,5,1,114,57,0, - 0,0,105,23,13,0,0,233,2,0,0,0,114,15,0,0, - 0,115,2,0,0,0,13,10,90,11,95,95,112,121,99,97, - 99,104,101,95,95,122,4,111,112,116,45,122,3,46,112,121, - 122,4,46,112,121,99,78,218,12,111,112,116,105,109,105,122, - 97,116,105,111,110,99,2,0,0,0,1,0,0,0,11,0, - 0,0,6,0,0,0,67,0,0,0,115,87,1,0,0,124, - 1,0,100,1,0,107,9,0,114,76,0,116,0,0,106,1, - 0,100,2,0,116,2,0,131,2,0,1,124,2,0,100,1, - 0,107,9,0,114,58,0,100,3,0,125,3,0,116,3,0, - 124,3,0,131,1,0,130,1,0,124,1,0,114,70,0,100, - 4,0,110,3,0,100,5,0,125,2,0,116,4,0,124,0, - 0,131,1,0,92,2,0,125,4,0,125,5,0,124,5,0, - 106,5,0,100,6,0,131,1,0,92,3,0,125,6,0,125, - 7,0,125,8,0,116,6,0,106,7,0,106,8,0,125,9, - 0,124,9,0,100,1,0,107,8,0,114,154,0,116,9,0, - 100,7,0,131,1,0,130,1,0,100,4,0,106,10,0,124, - 6,0,114,172,0,124,6,0,110,3,0,124,8,0,124,7, - 0,124,9,0,103,3,0,131,1,0,125,10,0,124,2,0, - 100,1,0,107,8,0,114,241,0,116,6,0,106,11,0,106, - 12,0,100,8,0,107,2,0,114,229,0,100,4,0,125,2, - 0,110,12,0,116,6,0,106,11,0,106,12,0,125,2,0, - 116,13,0,124,2,0,131,1,0,125,2,0,124,2,0,100, - 4,0,107,3,0,114,63,1,124,2,0,106,14,0,131,0, - 0,115,42,1,116,15,0,100,9,0,106,16,0,124,2,0, - 131,1,0,131,1,0,130,1,0,100,10,0,106,16,0,124, - 10,0,116,17,0,124,2,0,131,3,0,125,10,0,116,18, - 0,124,4,0,116,19,0,124,10,0,116,20,0,100,8,0, - 25,23,131,3,0,83,41,11,97,254,2,0,0,71,105,118, - 101,110,32,116,104,101,32,112,97,116,104,32,116,111,32,97, - 32,46,112,121,32,102,105,108,101,44,32,114,101,116,117,114, - 110,32,116,104,101,32,112,97,116,104,32,116,111,32,105,116, - 115,32,46,112,121,99,32,102,105,108,101,46,10,10,32,32, - 32,32,84,104,101,32,46,112,121,32,102,105,108,101,32,100, - 111,101,115,32,110,111,116,32,110,101,101,100,32,116,111,32, - 101,120,105,115,116,59,32,116,104,105,115,32,115,105,109,112, - 108,121,32,114,101,116,117,114,110,115,32,116,104,101,32,112, - 97,116,104,32,116,111,32,116,104,101,10,32,32,32,32,46, - 112,121,99,32,102,105,108,101,32,99,97,108,99,117,108,97, - 116,101,100,32,97,115,32,105,102,32,116,104,101,32,46,112, - 121,32,102,105,108,101,32,119,101,114,101,32,105,109,112,111, - 114,116,101,100,46,10,10,32,32,32,32,84,104,101,32,39, - 111,112,116,105,109,105,122,97,116,105,111,110,39,32,112,97, - 114,97,109,101,116,101,114,32,99,111,110,116,114,111,108,115, - 32,116,104,101,32,112,114,101,115,117,109,101,100,32,111,112, - 116,105,109,105,122,97,116,105,111,110,32,108,101,118,101,108, - 32,111,102,10,32,32,32,32,116,104,101,32,98,121,116,101, - 99,111,100,101,32,102,105,108,101,46,32,73,102,32,39,111, - 112,116,105,109,105,122,97,116,105,111,110,39,32,105,115,32, - 110,111,116,32,78,111,110,101,44,32,116,104,101,32,115,116, - 114,105,110,103,32,114,101,112,114,101,115,101,110,116,97,116, - 105,111,110,10,32,32,32,32,111,102,32,116,104,101,32,97, - 114,103,117,109,101,110,116,32,105,115,32,116,97,107,101,110, - 32,97,110,100,32,118,101,114,105,102,105,101,100,32,116,111, - 32,98,101,32,97,108,112,104,97,110,117,109,101,114,105,99, - 32,40,101,108,115,101,32,86,97,108,117,101,69,114,114,111, - 114,10,32,32,32,32,105,115,32,114,97,105,115,101,100,41, - 46,10,10,32,32,32,32,84,104,101,32,100,101,98,117,103, - 95,111,118,101,114,114,105,100,101,32,112,97,114,97,109,101, - 116,101,114,32,105,115,32,100,101,112,114,101,99,97,116,101, - 100,46,32,73,102,32,100,101,98,117,103,95,111,118,101,114, - 114,105,100,101,32,105,115,32,110,111,116,32,78,111,110,101, - 44,10,32,32,32,32,97,32,84,114,117,101,32,118,97,108, - 117,101,32,105,115,32,116,104,101,32,115,97,109,101,32,97, - 115,32,115,101,116,116,105,110,103,32,39,111,112,116,105,109, - 105,122,97,116,105,111,110,39,32,116,111,32,116,104,101,32, - 101,109,112,116,121,32,115,116,114,105,110,103,10,32,32,32, - 32,119,104,105,108,101,32,97,32,70,97,108,115,101,32,118, - 97,108,117,101,32,105,115,32,101,113,117,105,118,97,108,101, - 110,116,32,116,111,32,115,101,116,116,105,110,103,32,39,111, - 112,116,105,109,105,122,97,116,105,111,110,39,32,116,111,32, - 39,49,39,46,10,10,32,32,32,32,73,102,32,115,121,115, - 46,105,109,112,108,101,109,101,110,116,97,116,105,111,110,46, - 99,97,99,104,101,95,116,97,103,32,105,115,32,78,111,110, - 101,32,116,104,101,110,32,78,111,116,73,109,112,108,101,109, - 101,110,116,101,100,69,114,114,111,114,32,105,115,32,114,97, - 105,115,101,100,46,10,10,32,32,32,32,78,122,70,116,104, - 101,32,100,101,98,117,103,95,111,118,101,114,114,105,100,101, - 32,112,97,114,97,109,101,116,101,114,32,105,115,32,100,101, - 112,114,101,99,97,116,101,100,59,32,117,115,101,32,39,111, - 112,116,105,109,105,122,97,116,105,111,110,39,32,105,110,115, - 116,101,97,100,122,50,100,101,98,117,103,95,111,118,101,114, - 114,105,100,101,32,111,114,32,111,112,116,105,109,105,122,97, - 116,105,111,110,32,109,117,115,116,32,98,101,32,115,101,116, - 32,116,111,32,78,111,110,101,114,32,0,0,0,114,31,0, - 0,0,218,1,46,122,36,115,121,115,46,105,109,112,108,101, - 109,101,110,116,97,116,105,111,110,46,99,97,99,104,101,95, - 116,97,103,32,105,115,32,78,111,110,101,233,0,0,0,0, - 122,24,123,33,114,125,32,105,115,32,110,111,116,32,97,108, - 112,104,97,110,117,109,101,114,105,99,122,7,123,125,46,123, - 125,123,125,41,21,218,9,95,119,97,114,110,105,110,103,115, - 218,4,119,97,114,110,218,18,68,101,112,114,101,99,97,116, - 105,111,110,87,97,114,110,105,110,103,218,9,84,121,112,101, - 69,114,114,111,114,114,40,0,0,0,114,34,0,0,0,114, - 8,0,0,0,218,14,105,109,112,108,101,109,101,110,116,97, - 116,105,111,110,218,9,99,97,99,104,101,95,116,97,103,218, - 19,78,111,116,73,109,112,108,101,109,101,110,116,101,100,69, - 114,114,111,114,114,28,0,0,0,218,5,102,108,97,103,115, - 218,8,111,112,116,105,109,105,122,101,218,3,115,116,114,218, - 7,105,115,97,108,110,117,109,218,10,86,97,108,117,101,69, - 114,114,111,114,114,49,0,0,0,218,4,95,79,80,84,114, - 30,0,0,0,218,8,95,80,89,67,65,67,72,69,218,17, - 66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,69, - 83,41,11,114,37,0,0,0,90,14,100,101,98,117,103,95, - 111,118,101,114,114,105,100,101,114,59,0,0,0,218,7,109, - 101,115,115,97,103,101,218,4,104,101,97,100,114,39,0,0, - 0,90,4,98,97,115,101,218,3,115,101,112,218,4,114,101, - 115,116,90,3,116,97,103,90,15,97,108,109,111,115,116,95, - 102,105,108,101,110,97,109,101,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,218,17,99,97,99,104,101,95,102, - 114,111,109,95,115,111,117,114,99,101,254,0,0,0,115,46, - 0,0,0,0,18,12,1,9,1,7,1,12,1,6,1,12, - 1,18,1,18,1,24,1,12,1,12,1,12,1,36,1,12, - 1,18,1,9,2,12,1,12,1,12,1,12,1,21,1,21, - 1,114,81,0,0,0,99,1,0,0,0,0,0,0,0,8, - 0,0,0,5,0,0,0,67,0,0,0,115,62,1,0,0, - 116,0,0,106,1,0,106,2,0,100,1,0,107,8,0,114, - 30,0,116,3,0,100,2,0,131,1,0,130,1,0,116,4, - 0,124,0,0,131,1,0,92,2,0,125,1,0,125,2,0, - 116,4,0,124,1,0,131,1,0,92,2,0,125,1,0,125, - 3,0,124,3,0,116,5,0,107,3,0,114,102,0,116,6, - 0,100,3,0,106,7,0,116,5,0,124,0,0,131,2,0, - 131,1,0,130,1,0,124,2,0,106,8,0,100,4,0,131, - 1,0,125,4,0,124,4,0,100,11,0,107,7,0,114,153, - 0,116,6,0,100,7,0,106,7,0,124,2,0,131,1,0, - 131,1,0,130,1,0,110,125,0,124,4,0,100,6,0,107, - 2,0,114,22,1,124,2,0,106,9,0,100,4,0,100,5, - 0,131,2,0,100,12,0,25,125,5,0,124,5,0,106,10, - 0,116,11,0,131,1,0,115,223,0,116,6,0,100,8,0, - 106,7,0,116,11,0,131,1,0,131,1,0,130,1,0,124, - 5,0,116,12,0,116,11,0,131,1,0,100,1,0,133,2, - 0,25,125,6,0,124,6,0,106,13,0,131,0,0,115,22, - 1,116,6,0,100,9,0,106,7,0,124,5,0,131,1,0, - 131,1,0,130,1,0,124,2,0,106,14,0,100,4,0,131, - 1,0,100,10,0,25,125,7,0,116,15,0,124,1,0,124, - 7,0,116,16,0,100,10,0,25,23,131,2,0,83,41,13, - 97,110,1,0,0,71,105,118,101,110,32,116,104,101,32,112, - 97,116,104,32,116,111,32,97,32,46,112,121,99,46,32,102, - 105,108,101,44,32,114,101,116,117,114,110,32,116,104,101,32, - 112,97,116,104,32,116,111,32,105,116,115,32,46,112,121,32, - 102,105,108,101,46,10,10,32,32,32,32,84,104,101,32,46, - 112,121,99,32,102,105,108,101,32,100,111,101,115,32,110,111, - 116,32,110,101,101,100,32,116,111,32,101,120,105,115,116,59, - 32,116,104,105,115,32,115,105,109,112,108,121,32,114,101,116, - 117,114,110,115,32,116,104,101,32,112,97,116,104,32,116,111, - 10,32,32,32,32,116,104,101,32,46,112,121,32,102,105,108, - 101,32,99,97,108,99,117,108,97,116,101,100,32,116,111,32, - 99,111,114,114,101,115,112,111,110,100,32,116,111,32,116,104, - 101,32,46,112,121,99,32,102,105,108,101,46,32,32,73,102, - 32,112,97,116,104,32,100,111,101,115,10,32,32,32,32,110, - 111,116,32,99,111,110,102,111,114,109,32,116,111,32,80,69, - 80,32,51,49,52,55,47,52,56,56,32,102,111,114,109,97, - 116,44,32,86,97,108,117,101,69,114,114,111,114,32,119,105, - 108,108,32,98,101,32,114,97,105,115,101,100,46,32,73,102, - 10,32,32,32,32,115,121,115,46,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,46,99,97,99,104,101,95,116,97, - 103,32,105,115,32,78,111,110,101,32,116,104,101,110,32,78, - 111,116,73,109,112,108,101,109,101,110,116,101,100,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,122,36,115,121,115,46,105,109,112,108,101,109, - 101,110,116,97,116,105,111,110,46,99,97,99,104,101,95,116, - 97,103,32,105,115,32,78,111,110,101,122,37,123,125,32,110, - 111,116,32,98,111,116,116,111,109,45,108,101,118,101,108,32, - 100,105,114,101,99,116,111,114,121,32,105,110,32,123,33,114, - 125,114,60,0,0,0,114,58,0,0,0,233,3,0,0,0, - 122,33,101,120,112,101,99,116,101,100,32,111,110,108,121,32, - 50,32,111,114,32,51,32,100,111,116,115,32,105,110,32,123, - 33,114,125,122,57,111,112,116,105,109,105,122,97,116,105,111, - 110,32,112,111,114,116,105,111,110,32,111,102,32,102,105,108, - 101,110,97,109,101,32,100,111,101,115,32,110,111,116,32,115, - 116,97,114,116,32,119,105,116,104,32,123,33,114,125,122,52, - 111,112,116,105,109,105,122,97,116,105,111,110,32,108,101,118, - 101,108,32,123,33,114,125,32,105,115,32,110,111,116,32,97, - 110,32,97,108,112,104,97,110,117,109,101,114,105,99,32,118, - 97,108,117,101,114,61,0,0,0,62,2,0,0,0,114,58, - 0,0,0,114,82,0,0,0,233,254,255,255,255,41,17,114, - 8,0,0,0,114,66,0,0,0,114,67,0,0,0,114,68, - 0,0,0,114,40,0,0,0,114,75,0,0,0,114,73,0, - 0,0,114,49,0,0,0,218,5,99,111,117,110,116,114,36, - 0,0,0,114,10,0,0,0,114,74,0,0,0,114,33,0, - 0,0,114,72,0,0,0,218,9,112,97,114,116,105,116,105, - 111,110,114,30,0,0,0,218,15,83,79,85,82,67,69,95, - 83,85,70,70,73,88,69,83,41,8,114,37,0,0,0,114, - 78,0,0,0,90,16,112,121,99,97,99,104,101,95,102,105, - 108,101,110,97,109,101,90,7,112,121,99,97,99,104,101,90, - 9,100,111,116,95,99,111,117,110,116,114,59,0,0,0,90, - 9,111,112,116,95,108,101,118,101,108,90,13,98,97,115,101, + 115,100,105,114,46,105,0,64,0,0,41,3,114,3,0,0, + 0,218,6,103,101,116,99,119,100,114,45,0,0,0,41,1, + 114,37,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,218,11,95,112,97,116,104,95,105,115,100,105, + 114,99,0,0,0,115,6,0,0,0,0,2,6,1,12,1, + 114,48,0,0,0,105,182,1,0,0,99,3,0,0,0,0, + 0,0,0,6,0,0,0,17,0,0,0,67,0,0,0,115, + 193,0,0,0,100,1,0,106,0,0,124,0,0,116,1,0, + 124,0,0,131,1,0,131,2,0,125,3,0,116,2,0,106, + 3,0,124,3,0,116,2,0,106,4,0,116,2,0,106,5, + 0,66,116,2,0,106,6,0,66,124,2,0,100,2,0,64, + 131,3,0,125,4,0,121,61,0,116,7,0,106,8,0,124, + 4,0,100,3,0,131,2,0,143,20,0,125,5,0,124,5, + 0,106,9,0,124,1,0,131,1,0,1,87,100,4,0,81, + 82,88,116,2,0,106,10,0,124,3,0,124,0,0,131,2, + 0,1,87,110,59,0,4,116,11,0,107,10,0,114,188,0, + 1,1,1,121,17,0,116,2,0,106,12,0,124,3,0,131, + 1,0,1,87,110,18,0,4,116,11,0,107,10,0,114,180, + 0,1,1,1,89,110,1,0,88,130,0,0,89,110,1,0, + 88,100,4,0,83,41,5,122,162,66,101,115,116,45,101,102, + 102,111,114,116,32,102,117,110,99,116,105,111,110,32,116,111, + 32,119,114,105,116,101,32,100,97,116,97,32,116,111,32,97, + 32,112,97,116,104,32,97,116,111,109,105,99,97,108,108,121, + 46,10,32,32,32,32,66,101,32,112,114,101,112,97,114,101, + 100,32,116,111,32,104,97,110,100,108,101,32,97,32,70,105, + 108,101,69,120,105,115,116,115,69,114,114,111,114,32,105,102, + 32,99,111,110,99,117,114,114,101,110,116,32,119,114,105,116, + 105,110,103,32,111,102,32,116,104,101,10,32,32,32,32,116, + 101,109,112,111,114,97,114,121,32,102,105,108,101,32,105,115, + 32,97,116,116,101,109,112,116,101,100,46,122,5,123,125,46, + 123,125,105,182,1,0,0,90,2,119,98,78,41,13,218,6, + 102,111,114,109,97,116,218,2,105,100,114,3,0,0,0,90, + 4,111,112,101,110,90,6,79,95,69,88,67,76,90,7,79, + 95,67,82,69,65,84,90,8,79,95,87,82,79,78,76,89, + 218,3,95,105,111,218,6,70,105,108,101,73,79,218,5,119, + 114,105,116,101,218,7,114,101,112,108,97,99,101,114,42,0, + 0,0,90,6,117,110,108,105,110,107,41,6,114,37,0,0, + 0,218,4,100,97,116,97,114,44,0,0,0,90,8,112,97, + 116,104,95,116,109,112,90,2,102,100,218,4,102,105,108,101, + 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, + 13,95,119,114,105,116,101,95,97,116,111,109,105,99,106,0, + 0,0,115,26,0,0,0,0,5,24,1,9,1,33,1,3, + 3,21,1,20,1,20,1,13,1,3,1,17,1,13,1,5, + 1,114,57,0,0,0,105,23,13,0,0,233,2,0,0,0, + 114,15,0,0,0,115,2,0,0,0,13,10,105,23,13,13, + 10,122,65,77,97,103,105,99,32,110,117,109,98,101,114,32, + 109,105,115,109,97,116,99,104,32,40,116,104,101,32,105,115, + 115,117,101,50,55,50,56,54,32,119,111,114,107,97,114,111, + 117,110,100,32,105,115,32,102,111,114,32,51,46,53,32,111, + 110,108,121,41,105,22,13,0,0,90,11,95,95,112,121,99, + 97,99,104,101,95,95,122,4,111,112,116,45,122,3,46,112, + 121,122,4,46,112,121,99,78,218,12,111,112,116,105,109,105, + 122,97,116,105,111,110,99,2,0,0,0,1,0,0,0,11, + 0,0,0,6,0,0,0,67,0,0,0,115,87,1,0,0, + 124,1,0,100,1,0,107,9,0,114,76,0,116,0,0,106, + 1,0,100,2,0,116,2,0,131,2,0,1,124,2,0,100, + 1,0,107,9,0,114,58,0,100,3,0,125,3,0,116,3, + 0,124,3,0,131,1,0,130,1,0,124,1,0,114,70,0, + 100,4,0,110,3,0,100,5,0,125,2,0,116,4,0,124, + 0,0,131,1,0,92,2,0,125,4,0,125,5,0,124,5, + 0,106,5,0,100,6,0,131,1,0,92,3,0,125,6,0, + 125,7,0,125,8,0,116,6,0,106,7,0,106,8,0,125, + 9,0,124,9,0,100,1,0,107,8,0,114,154,0,116,9, + 0,100,7,0,131,1,0,130,1,0,100,4,0,106,10,0, + 124,6,0,114,172,0,124,6,0,110,3,0,124,8,0,124, + 7,0,124,9,0,103,3,0,131,1,0,125,10,0,124,2, + 0,100,1,0,107,8,0,114,241,0,116,6,0,106,11,0, + 106,12,0,100,8,0,107,2,0,114,229,0,100,4,0,125, + 2,0,110,12,0,116,6,0,106,11,0,106,12,0,125,2, + 0,116,13,0,124,2,0,131,1,0,125,2,0,124,2,0, + 100,4,0,107,3,0,114,63,1,124,2,0,106,14,0,131, + 0,0,115,42,1,116,15,0,100,9,0,106,16,0,124,2, + 0,131,1,0,131,1,0,130,1,0,100,10,0,106,16,0, + 124,10,0,116,17,0,124,2,0,131,3,0,125,10,0,116, + 18,0,124,4,0,116,19,0,124,10,0,116,20,0,100,8, + 0,25,23,131,3,0,83,41,11,97,254,2,0,0,71,105, + 118,101,110,32,116,104,101,32,112,97,116,104,32,116,111,32, + 97,32,46,112,121,32,102,105,108,101,44,32,114,101,116,117, + 114,110,32,116,104,101,32,112,97,116,104,32,116,111,32,105, + 116,115,32,46,112,121,99,32,102,105,108,101,46,10,10,32, + 32,32,32,84,104,101,32,46,112,121,32,102,105,108,101,32, + 100,111,101,115,32,110,111,116,32,110,101,101,100,32,116,111, + 32,101,120,105,115,116,59,32,116,104,105,115,32,115,105,109, + 112,108,121,32,114,101,116,117,114,110,115,32,116,104,101,32, + 112,97,116,104,32,116,111,32,116,104,101,10,32,32,32,32, + 46,112,121,99,32,102,105,108,101,32,99,97,108,99,117,108, + 97,116,101,100,32,97,115,32,105,102,32,116,104,101,32,46, + 112,121,32,102,105,108,101,32,119,101,114,101,32,105,109,112, + 111,114,116,101,100,46,10,10,32,32,32,32,84,104,101,32, + 39,111,112,116,105,109,105,122,97,116,105,111,110,39,32,112, + 97,114,97,109,101,116,101,114,32,99,111,110,116,114,111,108, + 115,32,116,104,101,32,112,114,101,115,117,109,101,100,32,111, + 112,116,105,109,105,122,97,116,105,111,110,32,108,101,118,101, + 108,32,111,102,10,32,32,32,32,116,104,101,32,98,121,116, + 101,99,111,100,101,32,102,105,108,101,46,32,73,102,32,39, + 111,112,116,105,109,105,122,97,116,105,111,110,39,32,105,115, + 32,110,111,116,32,78,111,110,101,44,32,116,104,101,32,115, + 116,114,105,110,103,32,114,101,112,114,101,115,101,110,116,97, + 116,105,111,110,10,32,32,32,32,111,102,32,116,104,101,32, + 97,114,103,117,109,101,110,116,32,105,115,32,116,97,107,101, + 110,32,97,110,100,32,118,101,114,105,102,105,101,100,32,116, + 111,32,98,101,32,97,108,112,104,97,110,117,109,101,114,105, + 99,32,40,101,108,115,101,32,86,97,108,117,101,69,114,114, + 111,114,10,32,32,32,32,105,115,32,114,97,105,115,101,100, + 41,46,10,10,32,32,32,32,84,104,101,32,100,101,98,117, + 103,95,111,118,101,114,114,105,100,101,32,112,97,114,97,109, + 101,116,101,114,32,105,115,32,100,101,112,114,101,99,97,116, + 101,100,46,32,73,102,32,100,101,98,117,103,95,111,118,101, + 114,114,105,100,101,32,105,115,32,110,111,116,32,78,111,110, + 101,44,10,32,32,32,32,97,32,84,114,117,101,32,118,97, + 108,117,101,32,105,115,32,116,104,101,32,115,97,109,101,32, + 97,115,32,115,101,116,116,105,110,103,32,39,111,112,116,105, + 109,105,122,97,116,105,111,110,39,32,116,111,32,116,104,101, + 32,101,109,112,116,121,32,115,116,114,105,110,103,10,32,32, + 32,32,119,104,105,108,101,32,97,32,70,97,108,115,101,32, + 118,97,108,117,101,32,105,115,32,101,113,117,105,118,97,108, + 101,110,116,32,116,111,32,115,101,116,116,105,110,103,32,39, + 111,112,116,105,109,105,122,97,116,105,111,110,39,32,116,111, + 32,39,49,39,46,10,10,32,32,32,32,73,102,32,115,121, + 115,46,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 46,99,97,99,104,101,95,116,97,103,32,105,115,32,78,111, + 110,101,32,116,104,101,110,32,78,111,116,73,109,112,108,101, + 109,101,110,116,101,100,69,114,114,111,114,32,105,115,32,114, + 97,105,115,101,100,46,10,10,32,32,32,32,78,122,70,116, + 104,101,32,100,101,98,117,103,95,111,118,101,114,114,105,100, + 101,32,112,97,114,97,109,101,116,101,114,32,105,115,32,100, + 101,112,114,101,99,97,116,101,100,59,32,117,115,101,32,39, + 111,112,116,105,109,105,122,97,116,105,111,110,39,32,105,110, + 115,116,101,97,100,122,50,100,101,98,117,103,95,111,118,101, + 114,114,105,100,101,32,111,114,32,111,112,116,105,109,105,122, + 97,116,105,111,110,32,109,117,115,116,32,98,101,32,115,101, + 116,32,116,111,32,78,111,110,101,114,32,0,0,0,114,31, + 0,0,0,218,1,46,122,36,115,121,115,46,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,46,99,97,99,104,101, + 95,116,97,103,32,105,115,32,78,111,110,101,233,0,0,0, + 0,122,24,123,33,114,125,32,105,115,32,110,111,116,32,97, + 108,112,104,97,110,117,109,101,114,105,99,122,7,123,125,46, + 123,125,123,125,41,21,218,9,95,119,97,114,110,105,110,103, + 115,218,4,119,97,114,110,218,18,68,101,112,114,101,99,97, + 116,105,111,110,87,97,114,110,105,110,103,218,9,84,121,112, + 101,69,114,114,111,114,114,40,0,0,0,114,34,0,0,0, + 114,8,0,0,0,218,14,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,218,9,99,97,99,104,101,95,116,97,103, + 218,19,78,111,116,73,109,112,108,101,109,101,110,116,101,100, + 69,114,114,111,114,114,28,0,0,0,218,5,102,108,97,103, + 115,218,8,111,112,116,105,109,105,122,101,218,3,115,116,114, + 218,7,105,115,97,108,110,117,109,218,10,86,97,108,117,101, + 69,114,114,111,114,114,49,0,0,0,218,4,95,79,80,84, + 114,30,0,0,0,218,8,95,80,89,67,65,67,72,69,218, + 17,66,89,84,69,67,79,68,69,95,83,85,70,70,73,88, + 69,83,41,11,114,37,0,0,0,90,14,100,101,98,117,103, + 95,111,118,101,114,114,105,100,101,114,59,0,0,0,218,7, + 109,101,115,115,97,103,101,218,4,104,101,97,100,114,39,0, + 0,0,90,4,98,97,115,101,218,3,115,101,112,218,4,114, + 101,115,116,90,3,116,97,103,90,15,97,108,109,111,115,116, 95,102,105,108,101,110,97,109,101,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,17,115,111,117,114,99,101, - 95,102,114,111,109,95,99,97,99,104,101,42,1,0,0,115, - 44,0,0,0,0,9,18,1,12,1,18,1,18,1,12,1, - 9,1,15,1,15,1,12,1,9,1,15,1,12,1,22,1, - 15,1,9,1,12,1,22,1,12,1,9,1,12,1,19,1, - 114,87,0,0,0,99,1,0,0,0,0,0,0,0,5,0, - 0,0,12,0,0,0,67,0,0,0,115,164,0,0,0,116, - 0,0,124,0,0,131,1,0,100,1,0,107,2,0,114,22, - 0,100,2,0,83,124,0,0,106,1,0,100,3,0,131,1, - 0,92,3,0,125,1,0,125,2,0,125,3,0,124,1,0, - 12,115,81,0,124,3,0,106,2,0,131,0,0,100,7,0, - 100,8,0,133,2,0,25,100,6,0,107,3,0,114,85,0, - 124,0,0,83,121,16,0,116,3,0,124,0,0,131,1,0, - 125,4,0,87,110,40,0,4,116,4,0,116,5,0,102,2, - 0,107,10,0,114,143,0,1,1,1,124,0,0,100,2,0, - 100,9,0,133,2,0,25,125,4,0,89,110,1,0,88,116, - 6,0,124,4,0,131,1,0,114,160,0,124,4,0,83,124, - 0,0,83,41,10,122,188,67,111,110,118,101,114,116,32,97, - 32,98,121,116,101,99,111,100,101,32,102,105,108,101,32,112, - 97,116,104,32,116,111,32,97,32,115,111,117,114,99,101,32, - 112,97,116,104,32,40,105,102,32,112,111,115,115,105,98,108, - 101,41,46,10,10,32,32,32,32,84,104,105,115,32,102,117, - 110,99,116,105,111,110,32,101,120,105,115,116,115,32,112,117, - 114,101,108,121,32,102,111,114,32,98,97,99,107,119,97,114, - 100,115,45,99,111,109,112,97,116,105,98,105,108,105,116,121, - 32,102,111,114,10,32,32,32,32,80,121,73,109,112,111,114, - 116,95,69,120,101,99,67,111,100,101,77,111,100,117,108,101, - 87,105,116,104,70,105,108,101,110,97,109,101,115,40,41,32, - 105,110,32,116,104,101,32,67,32,65,80,73,46,10,10,32, - 32,32,32,114,61,0,0,0,78,114,60,0,0,0,114,82, - 0,0,0,114,31,0,0,0,90,2,112,121,233,253,255,255, - 255,233,255,255,255,255,114,89,0,0,0,41,7,114,33,0, - 0,0,114,34,0,0,0,218,5,108,111,119,101,114,114,87, - 0,0,0,114,68,0,0,0,114,73,0,0,0,114,46,0, - 0,0,41,5,218,13,98,121,116,101,99,111,100,101,95,112, - 97,116,104,114,80,0,0,0,114,38,0,0,0,90,9,101, - 120,116,101,110,115,105,111,110,218,11,115,111,117,114,99,101, - 95,112,97,116,104,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,218,15,95,103,101,116,95,115,111,117,114,99, - 101,102,105,108,101,75,1,0,0,115,20,0,0,0,0,7, - 18,1,4,1,24,1,35,1,4,1,3,1,16,1,19,1, - 21,1,114,93,0,0,0,99,1,0,0,0,0,0,0,0, - 1,0,0,0,11,0,0,0,67,0,0,0,115,92,0,0, - 0,124,0,0,106,0,0,116,1,0,116,2,0,131,1,0, - 131,1,0,114,59,0,121,14,0,116,3,0,124,0,0,131, - 1,0,83,87,113,88,0,4,116,4,0,107,10,0,114,55, - 0,1,1,1,89,113,88,0,88,110,29,0,124,0,0,106, - 0,0,116,1,0,116,5,0,131,1,0,131,1,0,114,84, - 0,124,0,0,83,100,0,0,83,100,0,0,83,41,1,78, - 41,6,218,8,101,110,100,115,119,105,116,104,218,5,116,117, - 112,108,101,114,86,0,0,0,114,81,0,0,0,114,68,0, - 0,0,114,76,0,0,0,41,1,218,8,102,105,108,101,110, - 97,109,101,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,11,95,103,101,116,95,99,97,99,104,101,100,94, - 1,0,0,115,16,0,0,0,0,1,21,1,3,1,14,1, - 13,1,8,1,21,1,4,2,114,97,0,0,0,99,1,0, - 0,0,0,0,0,0,2,0,0,0,11,0,0,0,67,0, - 0,0,115,60,0,0,0,121,19,0,116,0,0,124,0,0, - 131,1,0,106,1,0,125,1,0,87,110,24,0,4,116,2, - 0,107,10,0,114,45,0,1,1,1,100,1,0,125,1,0, - 89,110,1,0,88,124,1,0,100,2,0,79,125,1,0,124, - 1,0,83,41,3,122,51,67,97,108,99,117,108,97,116,101, - 32,116,104,101,32,109,111,100,101,32,112,101,114,109,105,115, - 115,105,111,110,115,32,102,111,114,32,97,32,98,121,116,101, - 99,111,100,101,32,102,105,108,101,46,105,182,1,0,0,233, - 128,0,0,0,41,3,114,41,0,0,0,114,43,0,0,0, - 114,42,0,0,0,41,2,114,37,0,0,0,114,44,0,0, + 0,0,0,114,6,0,0,0,218,17,99,97,99,104,101,95, + 102,114,111,109,95,115,111,117,114,99,101,20,1,0,0,115, + 46,0,0,0,0,18,12,1,9,1,7,1,12,1,6,1, + 12,1,18,1,18,1,24,1,12,1,12,1,12,1,36,1, + 12,1,18,1,9,2,12,1,12,1,12,1,12,1,21,1, + 21,1,114,81,0,0,0,99,1,0,0,0,0,0,0,0, + 8,0,0,0,5,0,0,0,67,0,0,0,115,62,1,0, + 0,116,0,0,106,1,0,106,2,0,100,1,0,107,8,0, + 114,30,0,116,3,0,100,2,0,131,1,0,130,1,0,116, + 4,0,124,0,0,131,1,0,92,2,0,125,1,0,125,2, + 0,116,4,0,124,1,0,131,1,0,92,2,0,125,1,0, + 125,3,0,124,3,0,116,5,0,107,3,0,114,102,0,116, + 6,0,100,3,0,106,7,0,116,5,0,124,0,0,131,2, + 0,131,1,0,130,1,0,124,2,0,106,8,0,100,4,0, + 131,1,0,125,4,0,124,4,0,100,11,0,107,7,0,114, + 153,0,116,6,0,100,7,0,106,7,0,124,2,0,131,1, + 0,131,1,0,130,1,0,110,125,0,124,4,0,100,6,0, + 107,2,0,114,22,1,124,2,0,106,9,0,100,4,0,100, + 5,0,131,2,0,100,12,0,25,125,5,0,124,5,0,106, + 10,0,116,11,0,131,1,0,115,223,0,116,6,0,100,8, + 0,106,7,0,116,11,0,131,1,0,131,1,0,130,1,0, + 124,5,0,116,12,0,116,11,0,131,1,0,100,1,0,133, + 2,0,25,125,6,0,124,6,0,106,13,0,131,0,0,115, + 22,1,116,6,0,100,9,0,106,7,0,124,5,0,131,1, + 0,131,1,0,130,1,0,124,2,0,106,14,0,100,4,0, + 131,1,0,100,10,0,25,125,7,0,116,15,0,124,1,0, + 124,7,0,116,16,0,100,10,0,25,23,131,2,0,83,41, + 13,97,110,1,0,0,71,105,118,101,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,97,32,46,112,121,99,46,32, + 102,105,108,101,44,32,114,101,116,117,114,110,32,116,104,101, + 32,112,97,116,104,32,116,111,32,105,116,115,32,46,112,121, + 32,102,105,108,101,46,10,10,32,32,32,32,84,104,101,32, + 46,112,121,99,32,102,105,108,101,32,100,111,101,115,32,110, + 111,116,32,110,101,101,100,32,116,111,32,101,120,105,115,116, + 59,32,116,104,105,115,32,115,105,109,112,108,121,32,114,101, + 116,117,114,110,115,32,116,104,101,32,112,97,116,104,32,116, + 111,10,32,32,32,32,116,104,101,32,46,112,121,32,102,105, + 108,101,32,99,97,108,99,117,108,97,116,101,100,32,116,111, + 32,99,111,114,114,101,115,112,111,110,100,32,116,111,32,116, + 104,101,32,46,112,121,99,32,102,105,108,101,46,32,32,73, + 102,32,112,97,116,104,32,100,111,101,115,10,32,32,32,32, + 110,111,116,32,99,111,110,102,111,114,109,32,116,111,32,80, + 69,80,32,51,49,52,55,47,52,56,56,32,102,111,114,109, + 97,116,44,32,86,97,108,117,101,69,114,114,111,114,32,119, + 105,108,108,32,98,101,32,114,97,105,115,101,100,46,32,73, + 102,10,32,32,32,32,115,121,115,46,105,109,112,108,101,109, + 101,110,116,97,116,105,111,110,46,99,97,99,104,101,95,116, + 97,103,32,105,115,32,78,111,110,101,32,116,104,101,110,32, + 78,111,116,73,109,112,108,101,109,101,110,116,101,100,69,114, + 114,111,114,32,105,115,32,114,97,105,115,101,100,46,10,10, + 32,32,32,32,78,122,36,115,121,115,46,105,109,112,108,101, + 109,101,110,116,97,116,105,111,110,46,99,97,99,104,101,95, + 116,97,103,32,105,115,32,78,111,110,101,122,37,123,125,32, + 110,111,116,32,98,111,116,116,111,109,45,108,101,118,101,108, + 32,100,105,114,101,99,116,111,114,121,32,105,110,32,123,33, + 114,125,114,60,0,0,0,114,58,0,0,0,233,3,0,0, + 0,122,33,101,120,112,101,99,116,101,100,32,111,110,108,121, + 32,50,32,111,114,32,51,32,100,111,116,115,32,105,110,32, + 123,33,114,125,122,57,111,112,116,105,109,105,122,97,116,105, + 111,110,32,112,111,114,116,105,111,110,32,111,102,32,102,105, + 108,101,110,97,109,101,32,100,111,101,115,32,110,111,116,32, + 115,116,97,114,116,32,119,105,116,104,32,123,33,114,125,122, + 52,111,112,116,105,109,105,122,97,116,105,111,110,32,108,101, + 118,101,108,32,123,33,114,125,32,105,115,32,110,111,116,32, + 97,110,32,97,108,112,104,97,110,117,109,101,114,105,99,32, + 118,97,108,117,101,114,61,0,0,0,62,2,0,0,0,114, + 58,0,0,0,114,82,0,0,0,233,254,255,255,255,41,17, + 114,8,0,0,0,114,66,0,0,0,114,67,0,0,0,114, + 68,0,0,0,114,40,0,0,0,114,75,0,0,0,114,73, + 0,0,0,114,49,0,0,0,218,5,99,111,117,110,116,114, + 36,0,0,0,114,10,0,0,0,114,74,0,0,0,114,33, + 0,0,0,114,72,0,0,0,218,9,112,97,114,116,105,116, + 105,111,110,114,30,0,0,0,218,15,83,79,85,82,67,69, + 95,83,85,70,70,73,88,69,83,41,8,114,37,0,0,0, + 114,78,0,0,0,90,16,112,121,99,97,99,104,101,95,102, + 105,108,101,110,97,109,101,90,7,112,121,99,97,99,104,101, + 90,9,100,111,116,95,99,111,117,110,116,114,59,0,0,0, + 90,9,111,112,116,95,108,101,118,101,108,90,13,98,97,115, + 101,95,102,105,108,101,110,97,109,101,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,218,17,115,111,117,114,99, + 101,95,102,114,111,109,95,99,97,99,104,101,64,1,0,0, + 115,44,0,0,0,0,9,18,1,12,1,18,1,18,1,12, + 1,9,1,15,1,15,1,12,1,9,1,15,1,12,1,22, + 1,15,1,9,1,12,1,22,1,12,1,9,1,12,1,19, + 1,114,87,0,0,0,99,1,0,0,0,0,0,0,0,5, + 0,0,0,12,0,0,0,67,0,0,0,115,164,0,0,0, + 116,0,0,124,0,0,131,1,0,100,1,0,107,2,0,114, + 22,0,100,2,0,83,124,0,0,106,1,0,100,3,0,131, + 1,0,92,3,0,125,1,0,125,2,0,125,3,0,124,1, + 0,12,115,81,0,124,3,0,106,2,0,131,0,0,100,7, + 0,100,8,0,133,2,0,25,100,6,0,107,3,0,114,85, + 0,124,0,0,83,121,16,0,116,3,0,124,0,0,131,1, + 0,125,4,0,87,110,40,0,4,116,4,0,116,5,0,102, + 2,0,107,10,0,114,143,0,1,1,1,124,0,0,100,2, + 0,100,9,0,133,2,0,25,125,4,0,89,110,1,0,88, + 116,6,0,124,4,0,131,1,0,114,160,0,124,4,0,83, + 124,0,0,83,41,10,122,188,67,111,110,118,101,114,116,32, + 97,32,98,121,116,101,99,111,100,101,32,102,105,108,101,32, + 112,97,116,104,32,116,111,32,97,32,115,111,117,114,99,101, + 32,112,97,116,104,32,40,105,102,32,112,111,115,115,105,98, + 108,101,41,46,10,10,32,32,32,32,84,104,105,115,32,102, + 117,110,99,116,105,111,110,32,101,120,105,115,116,115,32,112, + 117,114,101,108,121,32,102,111,114,32,98,97,99,107,119,97, + 114,100,115,45,99,111,109,112,97,116,105,98,105,108,105,116, + 121,32,102,111,114,10,32,32,32,32,80,121,73,109,112,111, + 114,116,95,69,120,101,99,67,111,100,101,77,111,100,117,108, + 101,87,105,116,104,70,105,108,101,110,97,109,101,115,40,41, + 32,105,110,32,116,104,101,32,67,32,65,80,73,46,10,10, + 32,32,32,32,114,61,0,0,0,78,114,60,0,0,0,114, + 82,0,0,0,114,31,0,0,0,90,2,112,121,233,253,255, + 255,255,233,255,255,255,255,114,89,0,0,0,41,7,114,33, + 0,0,0,114,34,0,0,0,218,5,108,111,119,101,114,114, + 87,0,0,0,114,68,0,0,0,114,73,0,0,0,114,46, + 0,0,0,41,5,218,13,98,121,116,101,99,111,100,101,95, + 112,97,116,104,114,80,0,0,0,114,38,0,0,0,90,9, + 101,120,116,101,110,115,105,111,110,218,11,115,111,117,114,99, + 101,95,112,97,116,104,114,4,0,0,0,114,4,0,0,0, + 114,6,0,0,0,218,15,95,103,101,116,95,115,111,117,114, + 99,101,102,105,108,101,97,1,0,0,115,20,0,0,0,0, + 7,18,1,4,1,24,1,35,1,4,1,3,1,16,1,19, + 1,21,1,114,93,0,0,0,99,1,0,0,0,0,0,0, + 0,1,0,0,0,11,0,0,0,67,0,0,0,115,92,0, + 0,0,124,0,0,106,0,0,116,1,0,116,2,0,131,1, + 0,131,1,0,114,59,0,121,14,0,116,3,0,124,0,0, + 131,1,0,83,87,113,88,0,4,116,4,0,107,10,0,114, + 55,0,1,1,1,89,113,88,0,88,110,29,0,124,0,0, + 106,0,0,116,1,0,116,5,0,131,1,0,131,1,0,114, + 84,0,124,0,0,83,100,0,0,83,100,0,0,83,41,1, + 78,41,6,218,8,101,110,100,115,119,105,116,104,218,5,116, + 117,112,108,101,114,86,0,0,0,114,81,0,0,0,114,68, + 0,0,0,114,76,0,0,0,41,1,218,8,102,105,108,101, + 110,97,109,101,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,11,95,103,101,116,95,99,97,99,104,101,100, + 116,1,0,0,115,16,0,0,0,0,1,21,1,3,1,14, + 1,13,1,8,1,21,1,4,2,114,97,0,0,0,99,1, + 0,0,0,0,0,0,0,2,0,0,0,11,0,0,0,67, + 0,0,0,115,60,0,0,0,121,19,0,116,0,0,124,0, + 0,131,1,0,106,1,0,125,1,0,87,110,24,0,4,116, + 2,0,107,10,0,114,45,0,1,1,1,100,1,0,125,1, + 0,89,110,1,0,88,124,1,0,100,2,0,79,125,1,0, + 124,1,0,83,41,3,122,51,67,97,108,99,117,108,97,116, + 101,32,116,104,101,32,109,111,100,101,32,112,101,114,109,105, + 115,115,105,111,110,115,32,102,111,114,32,97,32,98,121,116, + 101,99,111,100,101,32,102,105,108,101,46,105,182,1,0,0, + 233,128,0,0,0,41,3,114,41,0,0,0,114,43,0,0, + 0,114,42,0,0,0,41,2,114,37,0,0,0,114,44,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,10,95,99,97,108,99,95,109,111,100,101,128,1,0, + 0,115,12,0,0,0,0,2,3,1,19,1,13,1,11,3, + 10,1,114,99,0,0,0,218,9,118,101,114,98,111,115,105, + 116,121,114,31,0,0,0,99,1,0,0,0,1,0,0,0, + 3,0,0,0,4,0,0,0,71,0,0,0,115,75,0,0, + 0,116,0,0,106,1,0,106,2,0,124,1,0,107,5,0, + 114,71,0,124,0,0,106,3,0,100,6,0,131,1,0,115, + 43,0,100,3,0,124,0,0,23,125,0,0,116,4,0,124, + 0,0,106,5,0,124,2,0,140,0,0,100,4,0,116,0, + 0,106,6,0,131,1,1,1,100,5,0,83,41,7,122,61, + 80,114,105,110,116,32,116,104,101,32,109,101,115,115,97,103, + 101,32,116,111,32,115,116,100,101,114,114,32,105,102,32,45, + 118,47,80,89,84,72,79,78,86,69,82,66,79,83,69,32, + 105,115,32,116,117,114,110,101,100,32,111,110,46,250,1,35, + 250,7,105,109,112,111,114,116,32,122,2,35,32,114,56,0, + 0,0,78,41,2,114,101,0,0,0,114,102,0,0,0,41, + 7,114,8,0,0,0,114,69,0,0,0,218,7,118,101,114, + 98,111,115,101,114,10,0,0,0,218,5,112,114,105,110,116, + 114,49,0,0,0,218,6,115,116,100,101,114,114,41,3,114, + 77,0,0,0,114,100,0,0,0,218,4,97,114,103,115,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,218,16, + 95,118,101,114,98,111,115,101,95,109,101,115,115,97,103,101, + 140,1,0,0,115,8,0,0,0,0,2,18,1,15,1,10, + 1,114,107,0,0,0,99,1,0,0,0,0,0,0,0,3, + 0,0,0,11,0,0,0,3,0,0,0,115,84,0,0,0, + 100,1,0,135,0,0,102,1,0,100,2,0,100,3,0,134, + 1,0,125,1,0,121,13,0,116,0,0,106,1,0,125,2, + 0,87,110,30,0,4,116,2,0,107,10,0,114,66,0,1, + 1,1,100,4,0,100,5,0,132,0,0,125,2,0,89,110, + 1,0,88,124,2,0,124,1,0,136,0,0,131,2,0,1, + 124,1,0,83,41,6,122,252,68,101,99,111,114,97,116,111, + 114,32,116,111,32,118,101,114,105,102,121,32,116,104,97,116, + 32,116,104,101,32,109,111,100,117,108,101,32,98,101,105,110, + 103,32,114,101,113,117,101,115,116,101,100,32,109,97,116,99, + 104,101,115,32,116,104,101,32,111,110,101,32,116,104,101,10, + 32,32,32,32,108,111,97,100,101,114,32,99,97,110,32,104, + 97,110,100,108,101,46,10,10,32,32,32,32,84,104,101,32, + 102,105,114,115,116,32,97,114,103,117,109,101,110,116,32,40, + 115,101,108,102,41,32,109,117,115,116,32,100,101,102,105,110, + 101,32,95,110,97,109,101,32,119,104,105,99,104,32,116,104, + 101,32,115,101,99,111,110,100,32,97,114,103,117,109,101,110, + 116,32,105,115,10,32,32,32,32,99,111,109,112,97,114,101, + 100,32,97,103,97,105,110,115,116,46,32,73,102,32,116,104, + 101,32,99,111,109,112,97,114,105,115,111,110,32,102,97,105, + 108,115,32,116,104,101,110,32,73,109,112,111,114,116,69,114, + 114,111,114,32,105,115,32,114,97,105,115,101,100,46,10,10, + 32,32,32,32,78,99,2,0,0,0,0,0,0,0,4,0, + 0,0,5,0,0,0,31,0,0,0,115,89,0,0,0,124, + 1,0,100,0,0,107,8,0,114,24,0,124,0,0,106,0, + 0,125,1,0,110,46,0,124,0,0,106,0,0,124,1,0, + 107,3,0,114,70,0,116,1,0,100,1,0,124,0,0,106, + 0,0,124,1,0,102,2,0,22,100,2,0,124,1,0,131, + 1,1,130,1,0,136,0,0,124,0,0,124,1,0,124,2, + 0,124,3,0,142,2,0,83,41,3,78,122,30,108,111,97, + 100,101,114,32,102,111,114,32,37,115,32,99,97,110,110,111, + 116,32,104,97,110,100,108,101,32,37,115,218,4,110,97,109, + 101,41,2,114,108,0,0,0,218,11,73,109,112,111,114,116, + 69,114,114,111,114,41,4,218,4,115,101,108,102,114,108,0, + 0,0,114,106,0,0,0,90,6,107,119,97,114,103,115,41, + 1,218,6,109,101,116,104,111,100,114,4,0,0,0,114,6, + 0,0,0,218,19,95,99,104,101,99,107,95,110,97,109,101, + 95,119,114,97,112,112,101,114,156,1,0,0,115,12,0,0, + 0,0,1,12,1,12,1,15,1,6,1,25,1,122,40,95, + 99,104,101,99,107,95,110,97,109,101,46,60,108,111,99,97, + 108,115,62,46,95,99,104,101,99,107,95,110,97,109,101,95, + 119,114,97,112,112,101,114,99,2,0,0,0,0,0,0,0, + 3,0,0,0,7,0,0,0,83,0,0,0,115,92,0,0, + 0,120,66,0,100,1,0,100,2,0,100,3,0,100,4,0, + 103,4,0,68,93,46,0,125,2,0,116,0,0,124,1,0, + 124,2,0,131,2,0,114,19,0,116,1,0,124,0,0,124, + 2,0,116,2,0,124,1,0,124,2,0,131,2,0,131,3, + 0,1,113,19,0,87,124,0,0,106,3,0,106,4,0,124, + 1,0,106,3,0,131,1,0,1,100,0,0,83,41,5,78, + 218,10,95,95,109,111,100,117,108,101,95,95,218,8,95,95, + 110,97,109,101,95,95,218,12,95,95,113,117,97,108,110,97, + 109,101,95,95,218,7,95,95,100,111,99,95,95,41,5,218, + 7,104,97,115,97,116,116,114,218,7,115,101,116,97,116,116, + 114,218,7,103,101,116,97,116,116,114,218,8,95,95,100,105, + 99,116,95,95,218,6,117,112,100,97,116,101,41,3,90,3, + 110,101,119,90,3,111,108,100,114,54,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,218,5,95,119, + 114,97,112,167,1,0,0,115,8,0,0,0,0,1,25,1, + 15,1,29,1,122,26,95,99,104,101,99,107,95,110,97,109, + 101,46,60,108,111,99,97,108,115,62,46,95,119,114,97,112, + 41,3,218,10,95,98,111,111,116,115,116,114,97,112,114,122, + 0,0,0,218,9,78,97,109,101,69,114,114,111,114,41,3, + 114,111,0,0,0,114,112,0,0,0,114,122,0,0,0,114, + 4,0,0,0,41,1,114,111,0,0,0,114,6,0,0,0, + 218,11,95,99,104,101,99,107,95,110,97,109,101,148,1,0, + 0,115,14,0,0,0,0,8,21,7,3,1,13,1,13,2, + 17,5,13,1,114,125,0,0,0,99,2,0,0,0,0,0, + 0,0,5,0,0,0,4,0,0,0,67,0,0,0,115,84, + 0,0,0,124,0,0,106,0,0,124,1,0,131,1,0,92, + 2,0,125,2,0,125,3,0,124,2,0,100,1,0,107,8, + 0,114,80,0,116,1,0,124,3,0,131,1,0,114,80,0, + 100,2,0,125,4,0,116,2,0,106,3,0,124,4,0,106, + 4,0,124,3,0,100,3,0,25,131,1,0,116,5,0,131, + 2,0,1,124,2,0,83,41,4,122,155,84,114,121,32,116, + 111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32, + 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, + 100,32,109,111,100,117,108,101,32,98,121,32,100,101,108,101, + 103,97,116,105,110,103,32,116,111,10,32,32,32,32,115,101, + 108,102,46,102,105,110,100,95,108,111,97,100,101,114,40,41, + 46,10,10,32,32,32,32,84,104,105,115,32,109,101,116,104, + 111,100,32,105,115,32,100,101,112,114,101,99,97,116,101,100, + 32,105,110,32,102,97,118,111,114,32,111,102,32,102,105,110, + 100,101,114,46,102,105,110,100,95,115,112,101,99,40,41,46, + 10,10,32,32,32,32,78,122,44,78,111,116,32,105,109,112, + 111,114,116,105,110,103,32,100,105,114,101,99,116,111,114,121, + 32,123,125,58,32,109,105,115,115,105,110,103,32,95,95,105, + 110,105,116,95,95,114,61,0,0,0,41,6,218,11,102,105, + 110,100,95,108,111,97,100,101,114,114,33,0,0,0,114,62, + 0,0,0,114,63,0,0,0,114,49,0,0,0,218,13,73, + 109,112,111,114,116,87,97,114,110,105,110,103,41,5,114,110, + 0,0,0,218,8,102,117,108,108,110,97,109,101,218,6,108, + 111,97,100,101,114,218,8,112,111,114,116,105,111,110,115,218, + 3,109,115,103,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,17,95,102,105,110,100,95,109,111,100,117,108, + 101,95,115,104,105,109,176,1,0,0,115,10,0,0,0,0, + 10,21,1,24,1,6,1,29,1,114,132,0,0,0,99,4, + 0,0,0,0,0,0,0,11,0,0,0,19,0,0,0,67, + 0,0,0,115,252,1,0,0,105,0,0,125,4,0,124,2, + 0,100,1,0,107,9,0,114,31,0,124,2,0,124,4,0, + 100,2,0,60,110,6,0,100,3,0,125,2,0,124,3,0, + 100,1,0,107,9,0,114,59,0,124,3,0,124,4,0,100, + 4,0,60,124,0,0,100,1,0,100,5,0,133,2,0,25, + 125,5,0,124,0,0,100,5,0,100,6,0,133,2,0,25, + 125,6,0,124,0,0,100,6,0,100,7,0,133,2,0,25, + 125,7,0,124,5,0,116,0,0,107,3,0,114,180,0,124, + 5,0,116,1,0,107,3,0,114,180,0,100,8,0,106,2, + 0,124,2,0,124,5,0,131,2,0,125,8,0,116,3,0, + 100,9,0,124,8,0,131,2,0,1,116,4,0,124,8,0, + 124,4,0,141,1,0,130,1,0,110,119,0,116,5,0,124, + 6,0,131,1,0,100,5,0,107,3,0,114,241,0,100,10, + 0,106,2,0,124,2,0,131,1,0,125,8,0,116,3,0, + 100,9,0,124,8,0,131,2,0,1,116,6,0,124,8,0, + 131,1,0,130,1,0,110,58,0,116,5,0,124,7,0,131, + 1,0,100,5,0,107,3,0,114,43,1,100,11,0,106,2, + 0,124,2,0,131,1,0,125,8,0,116,3,0,100,9,0, + 124,8,0,131,2,0,1,116,6,0,124,8,0,131,1,0, + 130,1,0,124,1,0,100,1,0,107,9,0,114,238,1,121, + 20,0,116,7,0,124,1,0,100,12,0,25,131,1,0,125, + 9,0,87,110,18,0,4,116,8,0,107,10,0,114,95,1, + 1,1,1,89,110,62,0,88,116,9,0,124,6,0,131,1, + 0,124,9,0,107,3,0,114,157,1,100,13,0,106,2,0, + 124,2,0,131,1,0,125,8,0,116,3,0,100,9,0,124, + 8,0,131,2,0,1,116,4,0,124,8,0,124,4,0,141, + 1,0,130,1,0,121,18,0,124,1,0,100,14,0,25,100, + 15,0,64,125,10,0,87,110,18,0,4,116,8,0,107,10, + 0,114,195,1,1,1,1,89,110,43,0,88,116,9,0,124, + 7,0,131,1,0,124,10,0,107,3,0,114,238,1,116,4, + 0,100,13,0,106,2,0,124,2,0,131,1,0,124,4,0, + 141,1,0,130,1,0,124,0,0,100,7,0,100,1,0,133, + 2,0,25,83,41,16,97,122,1,0,0,86,97,108,105,100, + 97,116,101,32,116,104,101,32,104,101,97,100,101,114,32,111, + 102,32,116,104,101,32,112,97,115,115,101,100,45,105,110,32, + 98,121,116,101,99,111,100,101,32,97,103,97,105,110,115,116, + 32,115,111,117,114,99,101,95,115,116,97,116,115,32,40,105, + 102,10,32,32,32,32,103,105,118,101,110,41,32,97,110,100, + 32,114,101,116,117,114,110,105,110,103,32,116,104,101,32,98, + 121,116,101,99,111,100,101,32,116,104,97,116,32,99,97,110, + 32,98,101,32,99,111,109,112,105,108,101,100,32,98,121,32, + 99,111,109,112,105,108,101,40,41,46,10,10,32,32,32,32, + 65,108,108,32,111,116,104,101,114,32,97,114,103,117,109,101, + 110,116,115,32,97,114,101,32,117,115,101,100,32,116,111,32, + 101,110,104,97,110,99,101,32,101,114,114,111,114,32,114,101, + 112,111,114,116,105,110,103,46,10,10,32,32,32,32,73,109, + 112,111,114,116,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,32,119,104,101,110,32,116,104,101,32,109,97,103, + 105,99,32,110,117,109,98,101,114,32,105,115,32,105,110,99, + 111,114,114,101,99,116,32,111,114,32,116,104,101,32,98,121, + 116,101,99,111,100,101,32,105,115,10,32,32,32,32,102,111, + 117,110,100,32,116,111,32,98,101,32,115,116,97,108,101,46, + 32,69,79,70,69,114,114,111,114,32,105,115,32,114,97,105, + 115,101,100,32,119,104,101,110,32,116,104,101,32,100,97,116, + 97,32,105,115,32,102,111,117,110,100,32,116,111,32,98,101, + 10,32,32,32,32,116,114,117,110,99,97,116,101,100,46,10, + 10,32,32,32,32,78,114,108,0,0,0,122,10,60,98,121, + 116,101,99,111,100,101,62,114,37,0,0,0,114,14,0,0, + 0,233,8,0,0,0,233,12,0,0,0,122,30,98,97,100, + 32,109,97,103,105,99,32,110,117,109,98,101,114,32,105,110, + 32,123,33,114,125,58,32,123,33,114,125,122,2,123,125,122, + 43,114,101,97,99,104,101,100,32,69,79,70,32,119,104,105, + 108,101,32,114,101,97,100,105,110,103,32,116,105,109,101,115, + 116,97,109,112,32,105,110,32,123,33,114,125,122,48,114,101, + 97,99,104,101,100,32,69,79,70,32,119,104,105,108,101,32, + 114,101,97,100,105,110,103,32,115,105,122,101,32,111,102,32, + 115,111,117,114,99,101,32,105,110,32,123,33,114,125,218,5, + 109,116,105,109,101,122,26,98,121,116,101,99,111,100,101,32, + 105,115,32,115,116,97,108,101,32,102,111,114,32,123,33,114, + 125,218,4,115,105,122,101,108,3,0,0,0,255,127,255,127, + 3,0,41,10,218,12,77,65,71,73,67,95,78,85,77,66, + 69,82,218,24,95,66,65,67,75,67,79,77,80,65,84,95, + 77,65,71,73,67,95,78,85,77,66,69,82,114,49,0,0, + 0,114,107,0,0,0,114,109,0,0,0,114,33,0,0,0, + 218,8,69,79,70,69,114,114,111,114,114,16,0,0,0,218, + 8,75,101,121,69,114,114,111,114,114,21,0,0,0,41,11, + 114,55,0,0,0,218,12,115,111,117,114,99,101,95,115,116, + 97,116,115,114,108,0,0,0,114,37,0,0,0,90,11,101, + 120,99,95,100,101,116,97,105,108,115,90,5,109,97,103,105, + 99,90,13,114,97,119,95,116,105,109,101,115,116,97,109,112, + 90,8,114,97,119,95,115,105,122,101,114,77,0,0,0,218, + 12,115,111,117,114,99,101,95,109,116,105,109,101,218,11,115, + 111,117,114,99,101,95,115,105,122,101,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,218,25,95,118,97,108,105, + 100,97,116,101,95,98,121,116,101,99,111,100,101,95,104,101, + 97,100,101,114,193,1,0,0,115,78,0,0,0,0,11,6, + 1,12,1,13,3,6,1,12,1,10,1,16,1,16,1,16, + 1,12,2,12,1,18,1,13,1,18,1,18,1,15,1,13, + 1,15,1,18,1,15,1,13,1,12,1,12,1,3,1,20, + 1,13,1,5,2,18,1,15,1,13,1,15,1,3,1,18, + 1,13,1,5,2,18,1,15,1,9,1,114,144,0,0,0, + 99,4,0,0,0,0,0,0,0,5,0,0,0,6,0,0, + 0,67,0,0,0,115,112,0,0,0,116,0,0,106,1,0, + 124,0,0,131,1,0,125,4,0,116,2,0,124,4,0,116, + 3,0,131,2,0,114,75,0,116,4,0,100,1,0,124,2, + 0,131,2,0,1,124,3,0,100,2,0,107,9,0,114,71, + 0,116,5,0,106,6,0,124,4,0,124,3,0,131,2,0, + 1,124,4,0,83,116,7,0,100,3,0,106,8,0,124,2, + 0,131,1,0,100,4,0,124,1,0,100,5,0,124,2,0, + 131,1,2,130,1,0,100,2,0,83,41,6,122,60,67,111, + 109,112,105,108,101,32,98,121,116,101,99,111,100,101,32,97, + 115,32,114,101,116,117,114,110,101,100,32,98,121,32,95,118, + 97,108,105,100,97,116,101,95,98,121,116,101,99,111,100,101, + 95,104,101,97,100,101,114,40,41,46,122,21,99,111,100,101, + 32,111,98,106,101,99,116,32,102,114,111,109,32,123,33,114, + 125,78,122,23,78,111,110,45,99,111,100,101,32,111,98,106, + 101,99,116,32,105,110,32,123,33,114,125,114,108,0,0,0, + 114,37,0,0,0,41,9,218,7,109,97,114,115,104,97,108, + 90,5,108,111,97,100,115,218,10,105,115,105,110,115,116,97, + 110,99,101,218,10,95,99,111,100,101,95,116,121,112,101,114, + 107,0,0,0,218,4,95,105,109,112,90,16,95,102,105,120, + 95,99,111,95,102,105,108,101,110,97,109,101,114,109,0,0, + 0,114,49,0,0,0,41,5,114,55,0,0,0,114,108,0, + 0,0,114,91,0,0,0,114,92,0,0,0,218,4,99,111, + 100,101,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,17,95,99,111,109,112,105,108,101,95,98,121,116,101, + 99,111,100,101,250,1,0,0,115,16,0,0,0,0,2,15, + 1,15,1,13,1,12,1,16,1,4,2,18,1,114,150,0, + 0,0,114,61,0,0,0,99,3,0,0,0,0,0,0,0, + 4,0,0,0,3,0,0,0,67,0,0,0,115,76,0,0, + 0,116,0,0,116,1,0,131,1,0,125,3,0,124,3,0, + 106,2,0,116,3,0,124,1,0,131,1,0,131,1,0,1, + 124,3,0,106,2,0,116,3,0,124,2,0,131,1,0,131, + 1,0,1,124,3,0,106,2,0,116,4,0,106,5,0,124, + 0,0,131,1,0,131,1,0,1,124,3,0,83,41,1,122, + 80,67,111,109,112,105,108,101,32,97,32,99,111,100,101,32, + 111,98,106,101,99,116,32,105,110,116,111,32,98,121,116,101, + 99,111,100,101,32,102,111,114,32,119,114,105,116,105,110,103, + 32,111,117,116,32,116,111,32,97,32,98,121,116,101,45,99, + 111,109,112,105,108,101,100,10,32,32,32,32,102,105,108,101, + 46,41,6,218,9,98,121,116,101,97,114,114,97,121,114,137, + 0,0,0,218,6,101,120,116,101,110,100,114,19,0,0,0, + 114,145,0,0,0,90,5,100,117,109,112,115,41,4,114,149, + 0,0,0,114,135,0,0,0,114,143,0,0,0,114,55,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,17,95,99,111,100,101,95,116,111,95,98,121,116,101, + 99,111,100,101,6,2,0,0,115,10,0,0,0,0,3,12, + 1,19,1,19,1,22,1,114,153,0,0,0,99,1,0,0, + 0,0,0,0,0,5,0,0,0,4,0,0,0,67,0,0, + 0,115,89,0,0,0,100,1,0,100,2,0,108,0,0,125, + 1,0,116,1,0,106,2,0,124,0,0,131,1,0,106,3, + 0,125,2,0,124,1,0,106,4,0,124,2,0,131,1,0, + 125,3,0,116,1,0,106,5,0,100,2,0,100,3,0,131, + 2,0,125,4,0,124,4,0,106,6,0,124,0,0,106,6, + 0,124,3,0,100,1,0,25,131,1,0,131,1,0,83,41, + 4,122,121,68,101,99,111,100,101,32,98,121,116,101,115,32, + 114,101,112,114,101,115,101,110,116,105,110,103,32,115,111,117, + 114,99,101,32,99,111,100,101,32,97,110,100,32,114,101,116, + 117,114,110,32,116,104,101,32,115,116,114,105,110,103,46,10, + 10,32,32,32,32,85,110,105,118,101,114,115,97,108,32,110, + 101,119,108,105,110,101,32,115,117,112,112,111,114,116,32,105, + 115,32,117,115,101,100,32,105,110,32,116,104,101,32,100,101, + 99,111,100,105,110,103,46,10,32,32,32,32,114,61,0,0, + 0,78,84,41,7,218,8,116,111,107,101,110,105,122,101,114, + 51,0,0,0,90,7,66,121,116,101,115,73,79,90,8,114, + 101,97,100,108,105,110,101,90,15,100,101,116,101,99,116,95, + 101,110,99,111,100,105,110,103,90,25,73,110,99,114,101,109, + 101,110,116,97,108,78,101,119,108,105,110,101,68,101,99,111, + 100,101,114,218,6,100,101,99,111,100,101,41,5,218,12,115, + 111,117,114,99,101,95,98,121,116,101,115,114,154,0,0,0, + 90,21,115,111,117,114,99,101,95,98,121,116,101,115,95,114, + 101,97,100,108,105,110,101,218,8,101,110,99,111,100,105,110, + 103,90,15,110,101,119,108,105,110,101,95,100,101,99,111,100, + 101,114,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,13,100,101,99,111,100,101,95,115,111,117,114,99,101, + 16,2,0,0,115,10,0,0,0,0,5,12,1,18,1,15, + 1,18,1,114,158,0,0,0,114,129,0,0,0,218,26,115, + 117,98,109,111,100,117,108,101,95,115,101,97,114,99,104,95, + 108,111,99,97,116,105,111,110,115,99,2,0,0,0,2,0, + 0,0,9,0,0,0,19,0,0,0,67,0,0,0,115,89, + 1,0,0,124,1,0,100,1,0,107,8,0,114,73,0,100, + 2,0,125,1,0,116,0,0,124,2,0,100,3,0,131,2, + 0,114,73,0,121,19,0,124,2,0,106,1,0,124,0,0, + 131,1,0,125,1,0,87,110,18,0,4,116,2,0,107,10, + 0,114,72,0,1,1,1,89,110,1,0,88,116,3,0,106, + 4,0,124,0,0,124,2,0,100,4,0,124,1,0,131,2, + 1,125,4,0,100,5,0,124,4,0,95,5,0,124,2,0, + 100,1,0,107,8,0,114,194,0,120,73,0,116,6,0,131, + 0,0,68,93,58,0,92,2,0,125,5,0,125,6,0,124, + 1,0,106,7,0,116,8,0,124,6,0,131,1,0,131,1, + 0,114,128,0,124,5,0,124,0,0,124,1,0,131,2,0, + 125,2,0,124,2,0,124,4,0,95,9,0,80,113,128,0, + 87,100,1,0,83,124,3,0,116,10,0,107,8,0,114,23, + 1,116,0,0,124,2,0,100,6,0,131,2,0,114,32,1, + 121,19,0,124,2,0,106,11,0,124,0,0,131,1,0,125, + 7,0,87,110,18,0,4,116,2,0,107,10,0,114,4,1, + 1,1,1,89,113,32,1,88,124,7,0,114,32,1,103,0, + 0,124,4,0,95,12,0,110,9,0,124,3,0,124,4,0, + 95,12,0,124,4,0,106,12,0,103,0,0,107,2,0,114, + 85,1,124,1,0,114,85,1,116,13,0,124,1,0,131,1, + 0,100,7,0,25,125,8,0,124,4,0,106,12,0,106,14, + 0,124,8,0,131,1,0,1,124,4,0,83,41,8,97,61, + 1,0,0,82,101,116,117,114,110,32,97,32,109,111,100,117, + 108,101,32,115,112,101,99,32,98,97,115,101,100,32,111,110, + 32,97,32,102,105,108,101,32,108,111,99,97,116,105,111,110, + 46,10,10,32,32,32,32,84,111,32,105,110,100,105,99,97, + 116,101,32,116,104,97,116,32,116,104,101,32,109,111,100,117, + 108,101,32,105,115,32,97,32,112,97,99,107,97,103,101,44, + 32,115,101,116,10,32,32,32,32,115,117,98,109,111,100,117, + 108,101,95,115,101,97,114,99,104,95,108,111,99,97,116,105, + 111,110,115,32,116,111,32,97,32,108,105,115,116,32,111,102, + 32,100,105,114,101,99,116,111,114,121,32,112,97,116,104,115, + 46,32,32,65,110,10,32,32,32,32,101,109,112,116,121,32, + 108,105,115,116,32,105,115,32,115,117,102,102,105,99,105,101, + 110,116,44,32,116,104,111,117,103,104,32,105,116,115,32,110, + 111,116,32,111,116,104,101,114,119,105,115,101,32,117,115,101, + 102,117,108,32,116,111,32,116,104,101,10,32,32,32,32,105, + 109,112,111,114,116,32,115,121,115,116,101,109,46,10,10,32, + 32,32,32,84,104,101,32,108,111,97,100,101,114,32,109,117, + 115,116,32,116,97,107,101,32,97,32,115,112,101,99,32,97, + 115,32,105,116,115,32,111,110,108,121,32,95,95,105,110,105, + 116,95,95,40,41,32,97,114,103,46,10,10,32,32,32,32, + 78,122,9,60,117,110,107,110,111,119,110,62,218,12,103,101, + 116,95,102,105,108,101,110,97,109,101,218,6,111,114,105,103, + 105,110,84,218,10,105,115,95,112,97,99,107,97,103,101,114, + 61,0,0,0,41,15,114,117,0,0,0,114,160,0,0,0, + 114,109,0,0,0,114,123,0,0,0,218,10,77,111,100,117, + 108,101,83,112,101,99,90,13,95,115,101,116,95,102,105,108, + 101,97,116,116,114,218,27,95,103,101,116,95,115,117,112,112, + 111,114,116,101,100,95,102,105,108,101,95,108,111,97,100,101, + 114,115,114,94,0,0,0,114,95,0,0,0,114,129,0,0, + 0,218,9,95,80,79,80,85,76,65,84,69,114,162,0,0, + 0,114,159,0,0,0,114,40,0,0,0,218,6,97,112,112, + 101,110,100,41,9,114,108,0,0,0,90,8,108,111,99,97, + 116,105,111,110,114,129,0,0,0,114,159,0,0,0,218,4, + 115,112,101,99,218,12,108,111,97,100,101,114,95,99,108,97, + 115,115,218,8,115,117,102,102,105,120,101,115,114,162,0,0, + 0,90,7,100,105,114,110,97,109,101,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,218,23,115,112,101,99,95, + 102,114,111,109,95,102,105,108,101,95,108,111,99,97,116,105, + 111,110,33,2,0,0,115,60,0,0,0,0,12,12,4,6, + 1,15,2,3,1,19,1,13,1,5,8,24,1,9,3,12, + 1,22,1,21,1,15,1,9,1,5,2,4,3,12,2,15, + 1,3,1,19,1,13,1,5,2,6,1,12,2,9,1,15, + 1,6,1,16,1,16,2,114,170,0,0,0,99,0,0,0, + 0,0,0,0,0,0,0,0,0,5,0,0,0,64,0,0, + 0,115,121,0,0,0,101,0,0,90,1,0,100,0,0,90, + 2,0,100,1,0,90,3,0,100,2,0,90,4,0,100,3, + 0,90,5,0,100,4,0,90,6,0,101,7,0,100,5,0, + 100,6,0,132,0,0,131,1,0,90,8,0,101,7,0,100, + 7,0,100,8,0,132,0,0,131,1,0,90,9,0,101,7, + 0,100,9,0,100,9,0,100,10,0,100,11,0,132,2,0, + 131,1,0,90,10,0,101,7,0,100,9,0,100,12,0,100, + 13,0,132,1,0,131,1,0,90,11,0,100,9,0,83,41, + 14,218,21,87,105,110,100,111,119,115,82,101,103,105,115,116, + 114,121,70,105,110,100,101,114,122,62,77,101,116,97,32,112, + 97,116,104,32,102,105,110,100,101,114,32,102,111,114,32,109, + 111,100,117,108,101,115,32,100,101,99,108,97,114,101,100,32, + 105,110,32,116,104,101,32,87,105,110,100,111,119,115,32,114, + 101,103,105,115,116,114,121,46,122,59,83,111,102,116,119,97, + 114,101,92,80,121,116,104,111,110,92,80,121,116,104,111,110, + 67,111,114,101,92,123,115,121,115,95,118,101,114,115,105,111, + 110,125,92,77,111,100,117,108,101,115,92,123,102,117,108,108, + 110,97,109,101,125,122,65,83,111,102,116,119,97,114,101,92, + 80,121,116,104,111,110,92,80,121,116,104,111,110,67,111,114, + 101,92,123,115,121,115,95,118,101,114,115,105,111,110,125,92, + 77,111,100,117,108,101,115,92,123,102,117,108,108,110,97,109, + 101,125,92,68,101,98,117,103,70,99,2,0,0,0,0,0, + 0,0,2,0,0,0,11,0,0,0,67,0,0,0,115,67, + 0,0,0,121,23,0,116,0,0,106,1,0,116,0,0,106, + 2,0,124,1,0,131,2,0,83,87,110,37,0,4,116,3, + 0,107,10,0,114,62,0,1,1,1,116,0,0,106,1,0, + 116,0,0,106,4,0,124,1,0,131,2,0,83,89,110,1, + 0,88,100,0,0,83,41,1,78,41,5,218,7,95,119,105, + 110,114,101,103,90,7,79,112,101,110,75,101,121,90,17,72, + 75,69,89,95,67,85,82,82,69,78,84,95,85,83,69,82, + 114,42,0,0,0,90,18,72,75,69,89,95,76,79,67,65, + 76,95,77,65,67,72,73,78,69,41,2,218,3,99,108,115, + 114,5,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,218,14,95,111,112,101,110,95,114,101,103,105, + 115,116,114,121,111,2,0,0,115,8,0,0,0,0,2,3, + 1,23,1,13,1,122,36,87,105,110,100,111,119,115,82,101, + 103,105,115,116,114,121,70,105,110,100,101,114,46,95,111,112, + 101,110,95,114,101,103,105,115,116,114,121,99,2,0,0,0, + 0,0,0,0,6,0,0,0,16,0,0,0,67,0,0,0, + 115,143,0,0,0,124,0,0,106,0,0,114,21,0,124,0, + 0,106,1,0,125,2,0,110,9,0,124,0,0,106,2,0, + 125,2,0,124,2,0,106,3,0,100,1,0,124,1,0,100, + 2,0,116,4,0,106,5,0,100,0,0,100,3,0,133,2, + 0,25,131,0,2,125,3,0,121,47,0,124,0,0,106,6, + 0,124,3,0,131,1,0,143,25,0,125,4,0,116,7,0, + 106,8,0,124,4,0,100,4,0,131,2,0,125,5,0,87, + 100,0,0,81,82,88,87,110,22,0,4,116,9,0,107,10, + 0,114,138,0,1,1,1,100,0,0,83,89,110,1,0,88, + 124,5,0,83,41,5,78,114,128,0,0,0,90,11,115,121, + 115,95,118,101,114,115,105,111,110,114,82,0,0,0,114,32, + 0,0,0,41,10,218,11,68,69,66,85,71,95,66,85,73, + 76,68,218,18,82,69,71,73,83,84,82,89,95,75,69,89, + 95,68,69,66,85,71,218,12,82,69,71,73,83,84,82,89, + 95,75,69,89,114,49,0,0,0,114,8,0,0,0,218,7, + 118,101,114,115,105,111,110,114,174,0,0,0,114,172,0,0, + 0,90,10,81,117,101,114,121,86,97,108,117,101,114,42,0, + 0,0,41,6,114,173,0,0,0,114,128,0,0,0,90,12, + 114,101,103,105,115,116,114,121,95,107,101,121,114,5,0,0, + 0,90,4,104,107,101,121,218,8,102,105,108,101,112,97,116, + 104,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, + 218,16,95,115,101,97,114,99,104,95,114,101,103,105,115,116, + 114,121,118,2,0,0,115,22,0,0,0,0,2,9,1,12, + 2,9,1,15,1,22,1,3,1,18,1,29,1,13,1,9, + 1,122,38,87,105,110,100,111,119,115,82,101,103,105,115,116, + 114,121,70,105,110,100,101,114,46,95,115,101,97,114,99,104, + 95,114,101,103,105,115,116,114,121,78,99,4,0,0,0,0, + 0,0,0,8,0,0,0,14,0,0,0,67,0,0,0,115, + 158,0,0,0,124,0,0,106,0,0,124,1,0,131,1,0, + 125,4,0,124,4,0,100,0,0,107,8,0,114,31,0,100, + 0,0,83,121,14,0,116,1,0,124,4,0,131,1,0,1, + 87,110,22,0,4,116,2,0,107,10,0,114,69,0,1,1, + 1,100,0,0,83,89,110,1,0,88,120,81,0,116,3,0, + 131,0,0,68,93,70,0,92,2,0,125,5,0,125,6,0, + 124,4,0,106,4,0,116,5,0,124,6,0,131,1,0,131, + 1,0,114,80,0,116,6,0,106,7,0,124,1,0,124,5, + 0,124,1,0,124,4,0,131,2,0,100,1,0,124,4,0, + 131,2,1,125,7,0,124,7,0,83,113,80,0,87,100,0, + 0,83,41,2,78,114,161,0,0,0,41,8,114,180,0,0, + 0,114,41,0,0,0,114,42,0,0,0,114,164,0,0,0, + 114,94,0,0,0,114,95,0,0,0,114,123,0,0,0,218, + 16,115,112,101,99,95,102,114,111,109,95,108,111,97,100,101, + 114,41,8,114,173,0,0,0,114,128,0,0,0,114,37,0, + 0,0,218,6,116,97,114,103,101,116,114,179,0,0,0,114, + 129,0,0,0,114,169,0,0,0,114,167,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,6,0,0,0,218,9,102, + 105,110,100,95,115,112,101,99,133,2,0,0,115,26,0,0, + 0,0,2,15,1,12,1,4,1,3,1,14,1,13,1,9, + 1,22,1,21,1,9,1,15,1,9,1,122,31,87,105,110, + 100,111,119,115,82,101,103,105,115,116,114,121,70,105,110,100, + 101,114,46,102,105,110,100,95,115,112,101,99,99,3,0,0, + 0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,0, + 0,115,45,0,0,0,124,0,0,106,0,0,124,1,0,124, + 2,0,131,2,0,125,3,0,124,3,0,100,1,0,107,9, + 0,114,37,0,124,3,0,106,1,0,83,100,1,0,83,100, + 1,0,83,41,2,122,108,70,105,110,100,32,109,111,100,117, + 108,101,32,110,97,109,101,100,32,105,110,32,116,104,101,32, + 114,101,103,105,115,116,114,121,46,10,10,32,32,32,32,32, + 32,32,32,84,104,105,115,32,109,101,116,104,111,100,32,105, + 115,32,100,101,112,114,101,99,97,116,101,100,46,32,32,85, + 115,101,32,101,120,101,99,95,109,111,100,117,108,101,40,41, + 32,105,110,115,116,101,97,100,46,10,10,32,32,32,32,32, + 32,32,32,78,41,2,114,183,0,0,0,114,129,0,0,0, + 41,4,114,173,0,0,0,114,128,0,0,0,114,37,0,0, + 0,114,167,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,6,0,0,0,218,11,102,105,110,100,95,109,111,100,117, + 108,101,149,2,0,0,115,8,0,0,0,0,7,18,1,12, + 1,7,2,122,33,87,105,110,100,111,119,115,82,101,103,105, + 115,116,114,121,70,105,110,100,101,114,46,102,105,110,100,95, + 109,111,100,117,108,101,41,12,114,114,0,0,0,114,113,0, + 0,0,114,115,0,0,0,114,116,0,0,0,114,177,0,0, + 0,114,176,0,0,0,114,175,0,0,0,218,11,99,108,97, + 115,115,109,101,116,104,111,100,114,174,0,0,0,114,180,0, + 0,0,114,183,0,0,0,114,184,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,10,95,99,97,108,99,95,109,111,100,101,106,1,0,0, - 115,12,0,0,0,0,2,3,1,19,1,13,1,11,3,10, - 1,114,99,0,0,0,218,9,118,101,114,98,111,115,105,116, - 121,114,31,0,0,0,99,1,0,0,0,1,0,0,0,3, - 0,0,0,4,0,0,0,71,0,0,0,115,75,0,0,0, - 116,0,0,106,1,0,106,2,0,124,1,0,107,5,0,114, - 71,0,124,0,0,106,3,0,100,6,0,131,1,0,115,43, - 0,100,3,0,124,0,0,23,125,0,0,116,4,0,124,0, - 0,106,5,0,124,2,0,140,0,0,100,4,0,116,0,0, - 106,6,0,131,1,1,1,100,5,0,83,41,7,122,61,80, - 114,105,110,116,32,116,104,101,32,109,101,115,115,97,103,101, - 32,116,111,32,115,116,100,101,114,114,32,105,102,32,45,118, - 47,80,89,84,72,79,78,86,69,82,66,79,83,69,32,105, - 115,32,116,117,114,110,101,100,32,111,110,46,250,1,35,250, - 7,105,109,112,111,114,116,32,122,2,35,32,114,56,0,0, - 0,78,41,2,114,101,0,0,0,114,102,0,0,0,41,7, - 114,8,0,0,0,114,69,0,0,0,218,7,118,101,114,98, - 111,115,101,114,10,0,0,0,218,5,112,114,105,110,116,114, - 49,0,0,0,218,6,115,116,100,101,114,114,41,3,114,77, - 0,0,0,114,100,0,0,0,218,4,97,114,103,115,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,218,16,95, - 118,101,114,98,111,115,101,95,109,101,115,115,97,103,101,118, - 1,0,0,115,8,0,0,0,0,2,18,1,15,1,10,1, - 114,107,0,0,0,99,1,0,0,0,0,0,0,0,3,0, - 0,0,11,0,0,0,3,0,0,0,115,84,0,0,0,100, - 1,0,135,0,0,102,1,0,100,2,0,100,3,0,134,1, - 0,125,1,0,121,13,0,116,0,0,106,1,0,125,2,0, - 87,110,30,0,4,116,2,0,107,10,0,114,66,0,1,1, - 1,100,4,0,100,5,0,132,0,0,125,2,0,89,110,1, - 0,88,124,2,0,124,1,0,136,0,0,131,2,0,1,124, - 1,0,83,41,6,122,252,68,101,99,111,114,97,116,111,114, - 32,116,111,32,118,101,114,105,102,121,32,116,104,97,116,32, - 116,104,101,32,109,111,100,117,108,101,32,98,101,105,110,103, - 32,114,101,113,117,101,115,116,101,100,32,109,97,116,99,104, - 101,115,32,116,104,101,32,111,110,101,32,116,104,101,10,32, - 32,32,32,108,111,97,100,101,114,32,99,97,110,32,104,97, - 110,100,108,101,46,10,10,32,32,32,32,84,104,101,32,102, - 105,114,115,116,32,97,114,103,117,109,101,110,116,32,40,115, - 101,108,102,41,32,109,117,115,116,32,100,101,102,105,110,101, - 32,95,110,97,109,101,32,119,104,105,99,104,32,116,104,101, - 32,115,101,99,111,110,100,32,97,114,103,117,109,101,110,116, - 32,105,115,10,32,32,32,32,99,111,109,112,97,114,101,100, - 32,97,103,97,105,110,115,116,46,32,73,102,32,116,104,101, - 32,99,111,109,112,97,114,105,115,111,110,32,102,97,105,108, - 115,32,116,104,101,110,32,73,109,112,111,114,116,69,114,114, - 111,114,32,105,115,32,114,97,105,115,101,100,46,10,10,32, - 32,32,32,78,99,2,0,0,0,0,0,0,0,4,0,0, - 0,5,0,0,0,31,0,0,0,115,89,0,0,0,124,1, - 0,100,0,0,107,8,0,114,24,0,124,0,0,106,0,0, - 125,1,0,110,46,0,124,0,0,106,0,0,124,1,0,107, - 3,0,114,70,0,116,1,0,100,1,0,124,0,0,106,0, - 0,124,1,0,102,2,0,22,100,2,0,124,1,0,131,1, - 1,130,1,0,136,0,0,124,0,0,124,1,0,124,2,0, - 124,3,0,142,2,0,83,41,3,78,122,30,108,111,97,100, - 101,114,32,102,111,114,32,37,115,32,99,97,110,110,111,116, - 32,104,97,110,100,108,101,32,37,115,218,4,110,97,109,101, - 41,2,114,108,0,0,0,218,11,73,109,112,111,114,116,69, - 114,114,111,114,41,4,218,4,115,101,108,102,114,108,0,0, - 0,114,106,0,0,0,90,6,107,119,97,114,103,115,41,1, - 218,6,109,101,116,104,111,100,114,4,0,0,0,114,6,0, - 0,0,218,19,95,99,104,101,99,107,95,110,97,109,101,95, - 119,114,97,112,112,101,114,134,1,0,0,115,12,0,0,0, - 0,1,12,1,12,1,15,1,6,1,25,1,122,40,95,99, - 104,101,99,107,95,110,97,109,101,46,60,108,111,99,97,108, - 115,62,46,95,99,104,101,99,107,95,110,97,109,101,95,119, - 114,97,112,112,101,114,99,2,0,0,0,0,0,0,0,3, - 0,0,0,7,0,0,0,83,0,0,0,115,92,0,0,0, - 120,66,0,100,1,0,100,2,0,100,3,0,100,4,0,103, - 4,0,68,93,46,0,125,2,0,116,0,0,124,1,0,124, - 2,0,131,2,0,114,19,0,116,1,0,124,0,0,124,2, - 0,116,2,0,124,1,0,124,2,0,131,2,0,131,3,0, - 1,113,19,0,87,124,0,0,106,3,0,106,4,0,124,1, - 0,106,3,0,131,1,0,1,100,0,0,83,41,5,78,218, - 10,95,95,109,111,100,117,108,101,95,95,218,8,95,95,110, - 97,109,101,95,95,218,12,95,95,113,117,97,108,110,97,109, - 101,95,95,218,7,95,95,100,111,99,95,95,41,5,218,7, - 104,97,115,97,116,116,114,218,7,115,101,116,97,116,116,114, - 218,7,103,101,116,97,116,116,114,218,8,95,95,100,105,99, - 116,95,95,218,6,117,112,100,97,116,101,41,3,90,3,110, - 101,119,90,3,111,108,100,114,54,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,218,5,95,119,114, - 97,112,145,1,0,0,115,8,0,0,0,0,1,25,1,15, - 1,29,1,122,26,95,99,104,101,99,107,95,110,97,109,101, - 46,60,108,111,99,97,108,115,62,46,95,119,114,97,112,41, - 3,218,10,95,98,111,111,116,115,116,114,97,112,114,122,0, - 0,0,218,9,78,97,109,101,69,114,114,111,114,41,3,114, - 111,0,0,0,114,112,0,0,0,114,122,0,0,0,114,4, - 0,0,0,41,1,114,111,0,0,0,114,6,0,0,0,218, - 11,95,99,104,101,99,107,95,110,97,109,101,126,1,0,0, - 115,14,0,0,0,0,8,21,7,3,1,13,1,13,2,17, - 5,13,1,114,125,0,0,0,99,2,0,0,0,0,0,0, - 0,5,0,0,0,4,0,0,0,67,0,0,0,115,84,0, - 0,0,124,0,0,106,0,0,124,1,0,131,1,0,92,2, - 0,125,2,0,125,3,0,124,2,0,100,1,0,107,8,0, - 114,80,0,116,1,0,124,3,0,131,1,0,114,80,0,100, - 2,0,125,4,0,116,2,0,106,3,0,124,4,0,106,4, - 0,124,3,0,100,3,0,25,131,1,0,116,5,0,131,2, - 0,1,124,2,0,83,41,4,122,155,84,114,121,32,116,111, - 32,102,105,110,100,32,97,32,108,111,97,100,101,114,32,102, - 111,114,32,116,104,101,32,115,112,101,99,105,102,105,101,100, - 32,109,111,100,117,108,101,32,98,121,32,100,101,108,101,103, - 97,116,105,110,103,32,116,111,10,32,32,32,32,115,101,108, - 102,46,102,105,110,100,95,108,111,97,100,101,114,40,41,46, - 10,10,32,32,32,32,84,104,105,115,32,109,101,116,104,111, - 100,32,105,115,32,100,101,112,114,101,99,97,116,101,100,32, - 105,110,32,102,97,118,111,114,32,111,102,32,102,105,110,100, - 101,114,46,102,105,110,100,95,115,112,101,99,40,41,46,10, - 10,32,32,32,32,78,122,44,78,111,116,32,105,109,112,111, - 114,116,105,110,103,32,100,105,114,101,99,116,111,114,121,32, - 123,125,58,32,109,105,115,115,105,110,103,32,95,95,105,110, - 105,116,95,95,114,61,0,0,0,41,6,218,11,102,105,110, - 100,95,108,111,97,100,101,114,114,33,0,0,0,114,62,0, - 0,0,114,63,0,0,0,114,49,0,0,0,218,13,73,109, - 112,111,114,116,87,97,114,110,105,110,103,41,5,114,110,0, - 0,0,218,8,102,117,108,108,110,97,109,101,218,6,108,111, - 97,100,101,114,218,8,112,111,114,116,105,111,110,115,218,3, - 109,115,103,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,17,95,102,105,110,100,95,109,111,100,117,108,101, - 95,115,104,105,109,154,1,0,0,115,10,0,0,0,0,10, - 21,1,24,1,6,1,29,1,114,132,0,0,0,99,4,0, - 0,0,0,0,0,0,11,0,0,0,19,0,0,0,67,0, - 0,0,115,240,1,0,0,105,0,0,125,4,0,124,2,0, - 100,1,0,107,9,0,114,31,0,124,2,0,124,4,0,100, - 2,0,60,110,6,0,100,3,0,125,2,0,124,3,0,100, - 1,0,107,9,0,114,59,0,124,3,0,124,4,0,100,4, - 0,60,124,0,0,100,1,0,100,5,0,133,2,0,25,125, - 5,0,124,0,0,100,5,0,100,6,0,133,2,0,25,125, - 6,0,124,0,0,100,6,0,100,7,0,133,2,0,25,125, - 7,0,124,5,0,116,0,0,107,3,0,114,168,0,100,8, - 0,106,1,0,124,2,0,124,5,0,131,2,0,125,8,0, - 116,2,0,100,9,0,124,8,0,131,2,0,1,116,3,0, - 124,8,0,124,4,0,141,1,0,130,1,0,110,119,0,116, - 4,0,124,6,0,131,1,0,100,5,0,107,3,0,114,229, - 0,100,10,0,106,1,0,124,2,0,131,1,0,125,8,0, - 116,2,0,100,9,0,124,8,0,131,2,0,1,116,5,0, - 124,8,0,131,1,0,130,1,0,110,58,0,116,4,0,124, - 7,0,131,1,0,100,5,0,107,3,0,114,31,1,100,11, - 0,106,1,0,124,2,0,131,1,0,125,8,0,116,2,0, - 100,9,0,124,8,0,131,2,0,1,116,5,0,124,8,0, - 131,1,0,130,1,0,124,1,0,100,1,0,107,9,0,114, - 226,1,121,20,0,116,6,0,124,1,0,100,12,0,25,131, - 1,0,125,9,0,87,110,18,0,4,116,7,0,107,10,0, - 114,83,1,1,1,1,89,110,62,0,88,116,8,0,124,6, - 0,131,1,0,124,9,0,107,3,0,114,145,1,100,13,0, - 106,1,0,124,2,0,131,1,0,125,8,0,116,2,0,100, - 9,0,124,8,0,131,2,0,1,116,3,0,124,8,0,124, - 4,0,141,1,0,130,1,0,121,18,0,124,1,0,100,14, - 0,25,100,15,0,64,125,10,0,87,110,18,0,4,116,7, - 0,107,10,0,114,183,1,1,1,1,89,110,43,0,88,116, - 8,0,124,7,0,131,1,0,124,10,0,107,3,0,114,226, - 1,116,3,0,100,13,0,106,1,0,124,2,0,131,1,0, - 124,4,0,141,1,0,130,1,0,124,0,0,100,7,0,100, - 1,0,133,2,0,25,83,41,16,97,122,1,0,0,86,97, - 108,105,100,97,116,101,32,116,104,101,32,104,101,97,100,101, - 114,32,111,102,32,116,104,101,32,112,97,115,115,101,100,45, - 105,110,32,98,121,116,101,99,111,100,101,32,97,103,97,105, - 110,115,116,32,115,111,117,114,99,101,95,115,116,97,116,115, - 32,40,105,102,10,32,32,32,32,103,105,118,101,110,41,32, - 97,110,100,32,114,101,116,117,114,110,105,110,103,32,116,104, - 101,32,98,121,116,101,99,111,100,101,32,116,104,97,116,32, - 99,97,110,32,98,101,32,99,111,109,112,105,108,101,100,32, - 98,121,32,99,111,109,112,105,108,101,40,41,46,10,10,32, - 32,32,32,65,108,108,32,111,116,104,101,114,32,97,114,103, - 117,109,101,110,116,115,32,97,114,101,32,117,115,101,100,32, - 116,111,32,101,110,104,97,110,99,101,32,101,114,114,111,114, - 32,114,101,112,111,114,116,105,110,103,46,10,10,32,32,32, - 32,73,109,112,111,114,116,69,114,114,111,114,32,105,115,32, - 114,97,105,115,101,100,32,119,104,101,110,32,116,104,101,32, - 109,97,103,105,99,32,110,117,109,98,101,114,32,105,115,32, - 105,110,99,111,114,114,101,99,116,32,111,114,32,116,104,101, - 32,98,121,116,101,99,111,100,101,32,105,115,10,32,32,32, - 32,102,111,117,110,100,32,116,111,32,98,101,32,115,116,97, - 108,101,46,32,69,79,70,69,114,114,111,114,32,105,115,32, - 114,97,105,115,101,100,32,119,104,101,110,32,116,104,101,32, - 100,97,116,97,32,105,115,32,102,111,117,110,100,32,116,111, - 32,98,101,10,32,32,32,32,116,114,117,110,99,97,116,101, - 100,46,10,10,32,32,32,32,78,114,108,0,0,0,122,10, - 60,98,121,116,101,99,111,100,101,62,114,37,0,0,0,114, - 14,0,0,0,233,8,0,0,0,233,12,0,0,0,122,30, - 98,97,100,32,109,97,103,105,99,32,110,117,109,98,101,114, - 32,105,110,32,123,33,114,125,58,32,123,33,114,125,122,2, - 123,125,122,43,114,101,97,99,104,101,100,32,69,79,70,32, - 119,104,105,108,101,32,114,101,97,100,105,110,103,32,116,105, - 109,101,115,116,97,109,112,32,105,110,32,123,33,114,125,122, - 48,114,101,97,99,104,101,100,32,69,79,70,32,119,104,105, - 108,101,32,114,101,97,100,105,110,103,32,115,105,122,101,32, - 111,102,32,115,111,117,114,99,101,32,105,110,32,123,33,114, - 125,218,5,109,116,105,109,101,122,26,98,121,116,101,99,111, - 100,101,32,105,115,32,115,116,97,108,101,32,102,111,114,32, - 123,33,114,125,218,4,115,105,122,101,108,3,0,0,0,255, - 127,255,127,3,0,41,9,218,12,77,65,71,73,67,95,78, - 85,77,66,69,82,114,49,0,0,0,114,107,0,0,0,114, - 109,0,0,0,114,33,0,0,0,218,8,69,79,70,69,114, - 114,111,114,114,16,0,0,0,218,8,75,101,121,69,114,114, - 111,114,114,21,0,0,0,41,11,114,55,0,0,0,218,12, - 115,111,117,114,99,101,95,115,116,97,116,115,114,108,0,0, - 0,114,37,0,0,0,90,11,101,120,99,95,100,101,116,97, - 105,108,115,90,5,109,97,103,105,99,90,13,114,97,119,95, - 116,105,109,101,115,116,97,109,112,90,8,114,97,119,95,115, - 105,122,101,114,77,0,0,0,218,12,115,111,117,114,99,101, - 95,109,116,105,109,101,218,11,115,111,117,114,99,101,95,115, - 105,122,101,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,25,95,118,97,108,105,100,97,116,101,95,98,121, - 116,101,99,111,100,101,95,104,101,97,100,101,114,171,1,0, - 0,115,76,0,0,0,0,11,6,1,12,1,13,3,6,1, - 12,1,10,1,16,1,16,1,16,1,12,1,18,1,13,1, - 18,1,18,1,15,1,13,1,15,1,18,1,15,1,13,1, - 12,1,12,1,3,1,20,1,13,1,5,2,18,1,15,1, - 13,1,15,1,3,1,18,1,13,1,5,2,18,1,15,1, - 9,1,114,143,0,0,0,99,4,0,0,0,0,0,0,0, - 5,0,0,0,6,0,0,0,67,0,0,0,115,112,0,0, - 0,116,0,0,106,1,0,124,0,0,131,1,0,125,4,0, - 116,2,0,124,4,0,116,3,0,131,2,0,114,75,0,116, - 4,0,100,1,0,124,2,0,131,2,0,1,124,3,0,100, - 2,0,107,9,0,114,71,0,116,5,0,106,6,0,124,4, - 0,124,3,0,131,2,0,1,124,4,0,83,116,7,0,100, - 3,0,106,8,0,124,2,0,131,1,0,100,4,0,124,1, - 0,100,5,0,124,2,0,131,1,2,130,1,0,100,2,0, - 83,41,6,122,60,67,111,109,112,105,108,101,32,98,121,116, - 101,99,111,100,101,32,97,115,32,114,101,116,117,114,110,101, - 100,32,98,121,32,95,118,97,108,105,100,97,116,101,95,98, - 121,116,101,99,111,100,101,95,104,101,97,100,101,114,40,41, - 46,122,21,99,111,100,101,32,111,98,106,101,99,116,32,102, - 114,111,109,32,123,33,114,125,78,122,23,78,111,110,45,99, - 111,100,101,32,111,98,106,101,99,116,32,105,110,32,123,33, - 114,125,114,108,0,0,0,114,37,0,0,0,41,9,218,7, - 109,97,114,115,104,97,108,90,5,108,111,97,100,115,218,10, - 105,115,105,110,115,116,97,110,99,101,218,10,95,99,111,100, - 101,95,116,121,112,101,114,107,0,0,0,218,4,95,105,109, - 112,90,16,95,102,105,120,95,99,111,95,102,105,108,101,110, - 97,109,101,114,109,0,0,0,114,49,0,0,0,41,5,114, - 55,0,0,0,114,108,0,0,0,114,91,0,0,0,114,92, - 0,0,0,218,4,99,111,100,101,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,17,95,99,111,109,112,105, - 108,101,95,98,121,116,101,99,111,100,101,226,1,0,0,115, - 16,0,0,0,0,2,15,1,15,1,13,1,12,1,16,1, - 4,2,18,1,114,149,0,0,0,114,61,0,0,0,99,3, - 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, - 0,0,0,115,76,0,0,0,116,0,0,116,1,0,131,1, - 0,125,3,0,124,3,0,106,2,0,116,3,0,124,1,0, - 131,1,0,131,1,0,1,124,3,0,106,2,0,116,3,0, - 124,2,0,131,1,0,131,1,0,1,124,3,0,106,2,0, - 116,4,0,106,5,0,124,0,0,131,1,0,131,1,0,1, - 124,3,0,83,41,1,122,80,67,111,109,112,105,108,101,32, - 97,32,99,111,100,101,32,111,98,106,101,99,116,32,105,110, - 116,111,32,98,121,116,101,99,111,100,101,32,102,111,114,32, - 119,114,105,116,105,110,103,32,111,117,116,32,116,111,32,97, - 32,98,121,116,101,45,99,111,109,112,105,108,101,100,10,32, - 32,32,32,102,105,108,101,46,41,6,218,9,98,121,116,101, - 97,114,114,97,121,114,137,0,0,0,218,6,101,120,116,101, - 110,100,114,19,0,0,0,114,144,0,0,0,90,5,100,117, - 109,112,115,41,4,114,148,0,0,0,114,135,0,0,0,114, - 142,0,0,0,114,55,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,17,95,99,111,100,101,95, - 116,111,95,98,121,116,101,99,111,100,101,238,1,0,0,115, - 10,0,0,0,0,3,12,1,19,1,19,1,22,1,114,152, - 0,0,0,99,1,0,0,0,0,0,0,0,5,0,0,0, - 4,0,0,0,67,0,0,0,115,89,0,0,0,100,1,0, - 100,2,0,108,0,0,125,1,0,116,1,0,106,2,0,124, - 0,0,131,1,0,106,3,0,125,2,0,124,1,0,106,4, - 0,124,2,0,131,1,0,125,3,0,116,1,0,106,5,0, - 100,2,0,100,3,0,131,2,0,125,4,0,124,4,0,106, - 6,0,124,0,0,106,6,0,124,3,0,100,1,0,25,131, - 1,0,131,1,0,83,41,4,122,121,68,101,99,111,100,101, - 32,98,121,116,101,115,32,114,101,112,114,101,115,101,110,116, - 105,110,103,32,115,111,117,114,99,101,32,99,111,100,101,32, - 97,110,100,32,114,101,116,117,114,110,32,116,104,101,32,115, - 116,114,105,110,103,46,10,10,32,32,32,32,85,110,105,118, - 101,114,115,97,108,32,110,101,119,108,105,110,101,32,115,117, - 112,112,111,114,116,32,105,115,32,117,115,101,100,32,105,110, - 32,116,104,101,32,100,101,99,111,100,105,110,103,46,10,32, - 32,32,32,114,61,0,0,0,78,84,41,7,218,8,116,111, - 107,101,110,105,122,101,114,51,0,0,0,90,7,66,121,116, - 101,115,73,79,90,8,114,101,97,100,108,105,110,101,90,15, - 100,101,116,101,99,116,95,101,110,99,111,100,105,110,103,90, - 25,73,110,99,114,101,109,101,110,116,97,108,78,101,119,108, - 105,110,101,68,101,99,111,100,101,114,218,6,100,101,99,111, - 100,101,41,5,218,12,115,111,117,114,99,101,95,98,121,116, - 101,115,114,153,0,0,0,90,21,115,111,117,114,99,101,95, - 98,121,116,101,115,95,114,101,97,100,108,105,110,101,218,8, - 101,110,99,111,100,105,110,103,90,15,110,101,119,108,105,110, - 101,95,100,101,99,111,100,101,114,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,13,100,101,99,111,100,101, - 95,115,111,117,114,99,101,248,1,0,0,115,10,0,0,0, - 0,5,12,1,18,1,15,1,18,1,114,157,0,0,0,114, - 129,0,0,0,218,26,115,117,98,109,111,100,117,108,101,95, - 115,101,97,114,99,104,95,108,111,99,97,116,105,111,110,115, - 99,2,0,0,0,2,0,0,0,9,0,0,0,19,0,0, - 0,67,0,0,0,115,89,1,0,0,124,1,0,100,1,0, - 107,8,0,114,73,0,100,2,0,125,1,0,116,0,0,124, - 2,0,100,3,0,131,2,0,114,73,0,121,19,0,124,2, - 0,106,1,0,124,0,0,131,1,0,125,1,0,87,110,18, - 0,4,116,2,0,107,10,0,114,72,0,1,1,1,89,110, - 1,0,88,116,3,0,106,4,0,124,0,0,124,2,0,100, - 4,0,124,1,0,131,2,1,125,4,0,100,5,0,124,4, - 0,95,5,0,124,2,0,100,1,0,107,8,0,114,194,0, - 120,73,0,116,6,0,131,0,0,68,93,58,0,92,2,0, - 125,5,0,125,6,0,124,1,0,106,7,0,116,8,0,124, - 6,0,131,1,0,131,1,0,114,128,0,124,5,0,124,0, - 0,124,1,0,131,2,0,125,2,0,124,2,0,124,4,0, - 95,9,0,80,113,128,0,87,100,1,0,83,124,3,0,116, - 10,0,107,8,0,114,23,1,116,0,0,124,2,0,100,6, - 0,131,2,0,114,32,1,121,19,0,124,2,0,106,11,0, - 124,0,0,131,1,0,125,7,0,87,110,18,0,4,116,2, - 0,107,10,0,114,4,1,1,1,1,89,113,32,1,88,124, - 7,0,114,32,1,103,0,0,124,4,0,95,12,0,110,9, - 0,124,3,0,124,4,0,95,12,0,124,4,0,106,12,0, - 103,0,0,107,2,0,114,85,1,124,1,0,114,85,1,116, - 13,0,124,1,0,131,1,0,100,7,0,25,125,8,0,124, - 4,0,106,12,0,106,14,0,124,8,0,131,1,0,1,124, - 4,0,83,41,8,97,61,1,0,0,82,101,116,117,114,110, - 32,97,32,109,111,100,117,108,101,32,115,112,101,99,32,98, - 97,115,101,100,32,111,110,32,97,32,102,105,108,101,32,108, - 111,99,97,116,105,111,110,46,10,10,32,32,32,32,84,111, - 32,105,110,100,105,99,97,116,101,32,116,104,97,116,32,116, - 104,101,32,109,111,100,117,108,101,32,105,115,32,97,32,112, - 97,99,107,97,103,101,44,32,115,101,116,10,32,32,32,32, - 115,117,98,109,111,100,117,108,101,95,115,101,97,114,99,104, - 95,108,111,99,97,116,105,111,110,115,32,116,111,32,97,32, - 108,105,115,116,32,111,102,32,100,105,114,101,99,116,111,114, - 121,32,112,97,116,104,115,46,32,32,65,110,10,32,32,32, - 32,101,109,112,116,121,32,108,105,115,116,32,105,115,32,115, - 117,102,102,105,99,105,101,110,116,44,32,116,104,111,117,103, - 104,32,105,116,115,32,110,111,116,32,111,116,104,101,114,119, - 105,115,101,32,117,115,101,102,117,108,32,116,111,32,116,104, - 101,10,32,32,32,32,105,109,112,111,114,116,32,115,121,115, - 116,101,109,46,10,10,32,32,32,32,84,104,101,32,108,111, - 97,100,101,114,32,109,117,115,116,32,116,97,107,101,32,97, - 32,115,112,101,99,32,97,115,32,105,116,115,32,111,110,108, - 121,32,95,95,105,110,105,116,95,95,40,41,32,97,114,103, - 46,10,10,32,32,32,32,78,122,9,60,117,110,107,110,111, - 119,110,62,218,12,103,101,116,95,102,105,108,101,110,97,109, - 101,218,6,111,114,105,103,105,110,84,218,10,105,115,95,112, - 97,99,107,97,103,101,114,61,0,0,0,41,15,114,117,0, - 0,0,114,159,0,0,0,114,109,0,0,0,114,123,0,0, - 0,218,10,77,111,100,117,108,101,83,112,101,99,90,13,95, - 115,101,116,95,102,105,108,101,97,116,116,114,218,27,95,103, - 101,116,95,115,117,112,112,111,114,116,101,100,95,102,105,108, - 101,95,108,111,97,100,101,114,115,114,94,0,0,0,114,95, - 0,0,0,114,129,0,0,0,218,9,95,80,79,80,85,76, - 65,84,69,114,161,0,0,0,114,158,0,0,0,114,40,0, - 0,0,218,6,97,112,112,101,110,100,41,9,114,108,0,0, - 0,90,8,108,111,99,97,116,105,111,110,114,129,0,0,0, - 114,158,0,0,0,218,4,115,112,101,99,218,12,108,111,97, - 100,101,114,95,99,108,97,115,115,218,8,115,117,102,102,105, - 120,101,115,114,161,0,0,0,90,7,100,105,114,110,97,109, - 101,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 218,23,115,112,101,99,95,102,114,111,109,95,102,105,108,101, - 95,108,111,99,97,116,105,111,110,9,2,0,0,115,60,0, - 0,0,0,12,12,4,6,1,15,2,3,1,19,1,13,1, - 5,8,24,1,9,3,12,1,22,1,21,1,15,1,9,1, - 5,2,4,3,12,2,15,1,3,1,19,1,13,1,5,2, - 6,1,12,2,9,1,15,1,6,1,16,1,16,2,114,169, + 114,171,0,0,0,99,2,0,0,115,20,0,0,0,12,2, + 6,3,6,3,6,2,6,2,18,7,18,15,3,1,21,15, + 3,1,114,171,0,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,64,0,0,0,115,70,0,0, + 0,101,0,0,90,1,0,100,0,0,90,2,0,100,1,0, + 90,3,0,100,2,0,100,3,0,132,0,0,90,4,0,100, + 4,0,100,5,0,132,0,0,90,5,0,100,6,0,100,7, + 0,132,0,0,90,6,0,100,8,0,100,9,0,132,0,0, + 90,7,0,100,10,0,83,41,11,218,13,95,76,111,97,100, + 101,114,66,97,115,105,99,115,122,83,66,97,115,101,32,99, + 108,97,115,115,32,111,102,32,99,111,109,109,111,110,32,99, + 111,100,101,32,110,101,101,100,101,100,32,98,121,32,98,111, + 116,104,32,83,111,117,114,99,101,76,111,97,100,101,114,32, + 97,110,100,10,32,32,32,32,83,111,117,114,99,101,108,101, + 115,115,70,105,108,101,76,111,97,100,101,114,46,99,2,0, + 0,0,0,0,0,0,5,0,0,0,3,0,0,0,67,0, + 0,0,115,88,0,0,0,116,0,0,124,0,0,106,1,0, + 124,1,0,131,1,0,131,1,0,100,1,0,25,125,2,0, + 124,2,0,106,2,0,100,2,0,100,1,0,131,2,0,100, + 3,0,25,125,3,0,124,1,0,106,3,0,100,2,0,131, + 1,0,100,4,0,25,125,4,0,124,3,0,100,5,0,107, + 2,0,111,87,0,124,4,0,100,5,0,107,3,0,83,41, + 6,122,141,67,111,110,99,114,101,116,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,73,110, + 115,112,101,99,116,76,111,97,100,101,114,46,105,115,95,112, + 97,99,107,97,103,101,32,98,121,32,99,104,101,99,107,105, + 110,103,32,105,102,10,32,32,32,32,32,32,32,32,116,104, + 101,32,112,97,116,104,32,114,101,116,117,114,110,101,100,32, + 98,121,32,103,101,116,95,102,105,108,101,110,97,109,101,32, + 104,97,115,32,97,32,102,105,108,101,110,97,109,101,32,111, + 102,32,39,95,95,105,110,105,116,95,95,46,112,121,39,46, + 114,31,0,0,0,114,60,0,0,0,114,61,0,0,0,114, + 58,0,0,0,218,8,95,95,105,110,105,116,95,95,41,4, + 114,40,0,0,0,114,160,0,0,0,114,36,0,0,0,114, + 34,0,0,0,41,5,114,110,0,0,0,114,128,0,0,0, + 114,96,0,0,0,90,13,102,105,108,101,110,97,109,101,95, + 98,97,115,101,90,9,116,97,105,108,95,110,97,109,101,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,162, + 0,0,0,168,2,0,0,115,8,0,0,0,0,3,25,1, + 22,1,19,1,122,24,95,76,111,97,100,101,114,66,97,115, + 105,99,115,46,105,115,95,112,97,99,107,97,103,101,99,2, + 0,0,0,0,0,0,0,2,0,0,0,1,0,0,0,67, + 0,0,0,115,4,0,0,0,100,1,0,83,41,2,122,42, + 85,115,101,32,100,101,102,97,117,108,116,32,115,101,109,97, + 110,116,105,99,115,32,102,111,114,32,109,111,100,117,108,101, + 32,99,114,101,97,116,105,111,110,46,78,114,4,0,0,0, + 41,2,114,110,0,0,0,114,167,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,218,13,99,114,101, + 97,116,101,95,109,111,100,117,108,101,176,2,0,0,115,0, + 0,0,0,122,27,95,76,111,97,100,101,114,66,97,115,105, + 99,115,46,99,114,101,97,116,101,95,109,111,100,117,108,101, + 99,2,0,0,0,0,0,0,0,3,0,0,0,4,0,0, + 0,67,0,0,0,115,80,0,0,0,124,0,0,106,0,0, + 124,1,0,106,1,0,131,1,0,125,2,0,124,2,0,100, + 1,0,107,8,0,114,54,0,116,2,0,100,2,0,106,3, + 0,124,1,0,106,1,0,131,1,0,131,1,0,130,1,0, + 116,4,0,106,5,0,116,6,0,124,2,0,124,1,0,106, + 7,0,131,3,0,1,100,1,0,83,41,3,122,19,69,120, + 101,99,117,116,101,32,116,104,101,32,109,111,100,117,108,101, + 46,78,122,52,99,97,110,110,111,116,32,108,111,97,100,32, + 109,111,100,117,108,101,32,123,33,114,125,32,119,104,101,110, + 32,103,101,116,95,99,111,100,101,40,41,32,114,101,116,117, + 114,110,115,32,78,111,110,101,41,8,218,8,103,101,116,95, + 99,111,100,101,114,114,0,0,0,114,109,0,0,0,114,49, + 0,0,0,114,123,0,0,0,218,25,95,99,97,108,108,95, + 119,105,116,104,95,102,114,97,109,101,115,95,114,101,109,111, + 118,101,100,218,4,101,120,101,99,114,120,0,0,0,41,3, + 114,110,0,0,0,218,6,109,111,100,117,108,101,114,149,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,11,101,120,101,99,95,109,111,100,117,108,101,179,2, + 0,0,115,10,0,0,0,0,2,18,1,12,1,9,1,15, + 1,122,25,95,76,111,97,100,101,114,66,97,115,105,99,115, + 46,101,120,101,99,95,109,111,100,117,108,101,99,2,0,0, + 0,0,0,0,0,2,0,0,0,3,0,0,0,67,0,0, + 0,115,16,0,0,0,116,0,0,106,1,0,124,0,0,124, + 1,0,131,2,0,83,41,1,78,41,2,114,123,0,0,0, + 218,17,95,108,111,97,100,95,109,111,100,117,108,101,95,115, + 104,105,109,41,2,114,110,0,0,0,114,128,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,218,11, + 108,111,97,100,95,109,111,100,117,108,101,187,2,0,0,115, + 2,0,0,0,0,1,122,25,95,76,111,97,100,101,114,66, + 97,115,105,99,115,46,108,111,97,100,95,109,111,100,117,108, + 101,78,41,8,114,114,0,0,0,114,113,0,0,0,114,115, + 0,0,0,114,116,0,0,0,114,162,0,0,0,114,188,0, + 0,0,114,193,0,0,0,114,195,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, + 114,186,0,0,0,163,2,0,0,115,10,0,0,0,12,3, + 6,2,12,8,12,3,12,8,114,186,0,0,0,99,0,0, + 0,0,0,0,0,0,0,0,0,0,4,0,0,0,64,0, + 0,0,115,106,0,0,0,101,0,0,90,1,0,100,0,0, + 90,2,0,100,1,0,100,2,0,132,0,0,90,3,0,100, + 3,0,100,4,0,132,0,0,90,4,0,100,5,0,100,6, + 0,132,0,0,90,5,0,100,7,0,100,8,0,132,0,0, + 90,6,0,100,9,0,100,10,0,132,0,0,90,7,0,100, + 11,0,100,18,0,100,13,0,100,14,0,132,0,1,90,8, + 0,100,15,0,100,16,0,132,0,0,90,9,0,100,17,0, + 83,41,19,218,12,83,111,117,114,99,101,76,111,97,100,101, + 114,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, + 0,0,67,0,0,0,115,10,0,0,0,116,0,0,130,1, + 0,100,1,0,83,41,2,122,178,79,112,116,105,111,110,97, + 108,32,109,101,116,104,111,100,32,116,104,97,116,32,114,101, + 116,117,114,110,115,32,116,104,101,32,109,111,100,105,102,105, + 99,97,116,105,111,110,32,116,105,109,101,32,40,97,110,32, + 105,110,116,41,32,102,111,114,32,116,104,101,10,32,32,32, + 32,32,32,32,32,115,112,101,99,105,102,105,101,100,32,112, + 97,116,104,44,32,119,104,101,114,101,32,112,97,116,104,32, + 105,115,32,97,32,115,116,114,46,10,10,32,32,32,32,32, + 32,32,32,82,97,105,115,101,115,32,73,79,69,114,114,111, + 114,32,119,104,101,110,32,116,104,101,32,112,97,116,104,32, + 99,97,110,110,111,116,32,98,101,32,104,97,110,100,108,101, + 100,46,10,32,32,32,32,32,32,32,32,78,41,1,218,7, + 73,79,69,114,114,111,114,41,2,114,110,0,0,0,114,37, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, + 0,0,218,10,112,97,116,104,95,109,116,105,109,101,193,2, + 0,0,115,2,0,0,0,0,6,122,23,83,111,117,114,99, + 101,76,111,97,100,101,114,46,112,97,116,104,95,109,116,105, + 109,101,99,2,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,67,0,0,0,115,19,0,0,0,100,1,0,124, + 0,0,106,0,0,124,1,0,131,1,0,105,1,0,83,41, + 2,97,170,1,0,0,79,112,116,105,111,110,97,108,32,109, + 101,116,104,111,100,32,114,101,116,117,114,110,105,110,103,32, + 97,32,109,101,116,97,100,97,116,97,32,100,105,99,116,32, + 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, + 100,32,112,97,116,104,10,32,32,32,32,32,32,32,32,116, + 111,32,98,121,32,116,104,101,32,112,97,116,104,32,40,115, + 116,114,41,46,10,32,32,32,32,32,32,32,32,80,111,115, + 115,105,98,108,101,32,107,101,121,115,58,10,32,32,32,32, + 32,32,32,32,45,32,39,109,116,105,109,101,39,32,40,109, + 97,110,100,97,116,111,114,121,41,32,105,115,32,116,104,101, + 32,110,117,109,101,114,105,99,32,116,105,109,101,115,116,97, + 109,112,32,111,102,32,108,97,115,116,32,115,111,117,114,99, + 101,10,32,32,32,32,32,32,32,32,32,32,99,111,100,101, + 32,109,111,100,105,102,105,99,97,116,105,111,110,59,10,32, + 32,32,32,32,32,32,32,45,32,39,115,105,122,101,39,32, + 40,111,112,116,105,111,110,97,108,41,32,105,115,32,116,104, + 101,32,115,105,122,101,32,105,110,32,98,121,116,101,115,32, + 111,102,32,116,104,101,32,115,111,117,114,99,101,32,99,111, + 100,101,46,10,10,32,32,32,32,32,32,32,32,73,109,112, + 108,101,109,101,110,116,105,110,103,32,116,104,105,115,32,109, + 101,116,104,111,100,32,97,108,108,111,119,115,32,116,104,101, + 32,108,111,97,100,101,114,32,116,111,32,114,101,97,100,32, + 98,121,116,101,99,111,100,101,32,102,105,108,101,115,46,10, + 32,32,32,32,32,32,32,32,82,97,105,115,101,115,32,73, + 79,69,114,114,111,114,32,119,104,101,110,32,116,104,101,32, + 112,97,116,104,32,99,97,110,110,111,116,32,98,101,32,104, + 97,110,100,108,101,100,46,10,32,32,32,32,32,32,32,32, + 114,135,0,0,0,41,1,114,198,0,0,0,41,2,114,110, + 0,0,0,114,37,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,6,0,0,0,218,10,112,97,116,104,95,115,116, + 97,116,115,201,2,0,0,115,2,0,0,0,0,11,122,23, + 83,111,117,114,99,101,76,111,97,100,101,114,46,112,97,116, + 104,95,115,116,97,116,115,99,4,0,0,0,0,0,0,0, + 4,0,0,0,3,0,0,0,67,0,0,0,115,16,0,0, + 0,124,0,0,106,0,0,124,2,0,124,3,0,131,2,0, + 83,41,1,122,228,79,112,116,105,111,110,97,108,32,109,101, + 116,104,111,100,32,119,104,105,99,104,32,119,114,105,116,101, + 115,32,100,97,116,97,32,40,98,121,116,101,115,41,32,116, + 111,32,97,32,102,105,108,101,32,112,97,116,104,32,40,97, + 32,115,116,114,41,46,10,10,32,32,32,32,32,32,32,32, + 73,109,112,108,101,109,101,110,116,105,110,103,32,116,104,105, + 115,32,109,101,116,104,111,100,32,97,108,108,111,119,115,32, + 102,111,114,32,116,104,101,32,119,114,105,116,105,110,103,32, + 111,102,32,98,121,116,101,99,111,100,101,32,102,105,108,101, + 115,46,10,10,32,32,32,32,32,32,32,32,84,104,101,32, + 115,111,117,114,99,101,32,112,97,116,104,32,105,115,32,110, + 101,101,100,101,100,32,105,110,32,111,114,100,101,114,32,116, + 111,32,99,111,114,114,101,99,116,108,121,32,116,114,97,110, + 115,102,101,114,32,112,101,114,109,105,115,115,105,111,110,115, + 10,32,32,32,32,32,32,32,32,41,1,218,8,115,101,116, + 95,100,97,116,97,41,4,114,110,0,0,0,114,92,0,0, + 0,90,10,99,97,99,104,101,95,112,97,116,104,114,55,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,15,95,99,97,99,104,101,95,98,121,116,101,99,111, + 100,101,214,2,0,0,115,2,0,0,0,0,8,122,28,83, + 111,117,114,99,101,76,111,97,100,101,114,46,95,99,97,99, + 104,101,95,98,121,116,101,99,111,100,101,99,3,0,0,0, + 0,0,0,0,3,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,1,0,83,41,2,122,150,79,112,116, + 105,111,110,97,108,32,109,101,116,104,111,100,32,119,104,105, + 99,104,32,119,114,105,116,101,115,32,100,97,116,97,32,40, + 98,121,116,101,115,41,32,116,111,32,97,32,102,105,108,101, + 32,112,97,116,104,32,40,97,32,115,116,114,41,46,10,10, + 32,32,32,32,32,32,32,32,73,109,112,108,101,109,101,110, + 116,105,110,103,32,116,104,105,115,32,109,101,116,104,111,100, + 32,97,108,108,111,119,115,32,102,111,114,32,116,104,101,32, + 119,114,105,116,105,110,103,32,111,102,32,98,121,116,101,99, + 111,100,101,32,102,105,108,101,115,46,10,32,32,32,32,32, + 32,32,32,78,114,4,0,0,0,41,3,114,110,0,0,0, + 114,37,0,0,0,114,55,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,114,200,0,0,0,224,2, + 0,0,115,0,0,0,0,122,21,83,111,117,114,99,101,76, + 111,97,100,101,114,46,115,101,116,95,100,97,116,97,99,2, + 0,0,0,0,0,0,0,5,0,0,0,16,0,0,0,67, + 0,0,0,115,105,0,0,0,124,0,0,106,0,0,124,1, + 0,131,1,0,125,2,0,121,19,0,124,0,0,106,1,0, + 124,2,0,131,1,0,125,3,0,87,110,58,0,4,116,2, + 0,107,10,0,114,94,0,1,125,4,0,1,122,26,0,116, + 3,0,100,1,0,100,2,0,124,1,0,131,1,1,124,4, + 0,130,2,0,87,89,100,3,0,100,3,0,125,4,0,126, + 4,0,88,110,1,0,88,116,4,0,124,3,0,131,1,0, + 83,41,4,122,52,67,111,110,99,114,101,116,101,32,105,109, + 112,108,101,109,101,110,116,97,116,105,111,110,32,111,102,32, + 73,110,115,112,101,99,116,76,111,97,100,101,114,46,103,101, + 116,95,115,111,117,114,99,101,46,122,39,115,111,117,114,99, + 101,32,110,111,116,32,97,118,97,105,108,97,98,108,101,32, + 116,104,114,111,117,103,104,32,103,101,116,95,100,97,116,97, + 40,41,114,108,0,0,0,78,41,5,114,160,0,0,0,218, + 8,103,101,116,95,100,97,116,97,114,42,0,0,0,114,109, + 0,0,0,114,158,0,0,0,41,5,114,110,0,0,0,114, + 128,0,0,0,114,37,0,0,0,114,156,0,0,0,218,3, + 101,120,99,114,4,0,0,0,114,4,0,0,0,114,6,0, + 0,0,218,10,103,101,116,95,115,111,117,114,99,101,231,2, + 0,0,115,14,0,0,0,0,2,15,1,3,1,19,1,18, + 1,9,1,31,1,122,23,83,111,117,114,99,101,76,111,97, + 100,101,114,46,103,101,116,95,115,111,117,114,99,101,218,9, + 95,111,112,116,105,109,105,122,101,114,31,0,0,0,99,3, + 0,0,0,1,0,0,0,4,0,0,0,9,0,0,0,67, + 0,0,0,115,34,0,0,0,116,0,0,106,1,0,116,2, + 0,124,1,0,124,2,0,100,1,0,100,2,0,100,3,0, + 100,4,0,124,3,0,131,4,2,83,41,5,122,130,82,101, + 116,117,114,110,32,116,104,101,32,99,111,100,101,32,111,98, + 106,101,99,116,32,99,111,109,112,105,108,101,100,32,102,114, + 111,109,32,115,111,117,114,99,101,46,10,10,32,32,32,32, + 32,32,32,32,84,104,101,32,39,100,97,116,97,39,32,97, + 114,103,117,109,101,110,116,32,99,97,110,32,98,101,32,97, + 110,121,32,111,98,106,101,99,116,32,116,121,112,101,32,116, + 104,97,116,32,99,111,109,112,105,108,101,40,41,32,115,117, + 112,112,111,114,116,115,46,10,32,32,32,32,32,32,32,32, + 114,191,0,0,0,218,12,100,111,110,116,95,105,110,104,101, + 114,105,116,84,114,70,0,0,0,41,3,114,123,0,0,0, + 114,190,0,0,0,218,7,99,111,109,112,105,108,101,41,4, + 114,110,0,0,0,114,55,0,0,0,114,37,0,0,0,114, + 205,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,14,115,111,117,114,99,101,95,116,111,95,99, + 111,100,101,241,2,0,0,115,4,0,0,0,0,5,21,1, + 122,27,83,111,117,114,99,101,76,111,97,100,101,114,46,115, + 111,117,114,99,101,95,116,111,95,99,111,100,101,99,2,0, + 0,0,0,0,0,0,10,0,0,0,43,0,0,0,67,0, + 0,0,115,174,1,0,0,124,0,0,106,0,0,124,1,0, + 131,1,0,125,2,0,100,1,0,125,3,0,121,16,0,116, + 1,0,124,2,0,131,1,0,125,4,0,87,110,24,0,4, + 116,2,0,107,10,0,114,63,0,1,1,1,100,1,0,125, + 4,0,89,110,202,0,88,121,19,0,124,0,0,106,3,0, + 124,2,0,131,1,0,125,5,0,87,110,18,0,4,116,4, + 0,107,10,0,114,103,0,1,1,1,89,110,162,0,88,116, + 5,0,124,5,0,100,2,0,25,131,1,0,125,3,0,121, + 19,0,124,0,0,106,6,0,124,4,0,131,1,0,125,6, + 0,87,110,18,0,4,116,7,0,107,10,0,114,159,0,1, + 1,1,89,110,106,0,88,121,34,0,116,8,0,124,6,0, + 100,3,0,124,5,0,100,4,0,124,1,0,100,5,0,124, + 4,0,131,1,3,125,7,0,87,110,24,0,4,116,9,0, + 116,10,0,102,2,0,107,10,0,114,220,0,1,1,1,89, + 110,45,0,88,116,11,0,100,6,0,124,4,0,124,2,0, + 131,3,0,1,116,12,0,124,7,0,100,4,0,124,1,0, + 100,7,0,124,4,0,100,8,0,124,2,0,131,1,3,83, + 124,0,0,106,6,0,124,2,0,131,1,0,125,8,0,124, + 0,0,106,13,0,124,8,0,124,2,0,131,2,0,125,9, + 0,116,11,0,100,9,0,124,2,0,131,2,0,1,116,14, + 0,106,15,0,12,114,170,1,124,4,0,100,1,0,107,9, + 0,114,170,1,124,3,0,100,1,0,107,9,0,114,170,1, + 116,16,0,124,9,0,124,3,0,116,17,0,124,8,0,131, + 1,0,131,3,0,125,6,0,121,36,0,124,0,0,106,18, + 0,124,2,0,124,4,0,124,6,0,131,3,0,1,116,11, + 0,100,10,0,124,4,0,131,2,0,1,87,110,18,0,4, + 116,2,0,107,10,0,114,169,1,1,1,1,89,110,1,0, + 88,124,9,0,83,41,11,122,190,67,111,110,99,114,101,116, + 101,32,105,109,112,108,101,109,101,110,116,97,116,105,111,110, + 32,111,102,32,73,110,115,112,101,99,116,76,111,97,100,101, + 114,46,103,101,116,95,99,111,100,101,46,10,10,32,32,32, + 32,32,32,32,32,82,101,97,100,105,110,103,32,111,102,32, + 98,121,116,101,99,111,100,101,32,114,101,113,117,105,114,101, + 115,32,112,97,116,104,95,115,116,97,116,115,32,116,111,32, + 98,101,32,105,109,112,108,101,109,101,110,116,101,100,46,32, + 84,111,32,119,114,105,116,101,10,32,32,32,32,32,32,32, + 32,98,121,116,101,99,111,100,101,44,32,115,101,116,95,100, + 97,116,97,32,109,117,115,116,32,97,108,115,111,32,98,101, + 32,105,109,112,108,101,109,101,110,116,101,100,46,10,10,32, + 32,32,32,32,32,32,32,78,114,135,0,0,0,114,141,0, + 0,0,114,108,0,0,0,114,37,0,0,0,122,13,123,125, + 32,109,97,116,99,104,101,115,32,123,125,114,91,0,0,0, + 114,92,0,0,0,122,19,99,111,100,101,32,111,98,106,101, + 99,116,32,102,114,111,109,32,123,125,122,10,119,114,111,116, + 101,32,123,33,114,125,41,19,114,160,0,0,0,114,81,0, + 0,0,114,68,0,0,0,114,199,0,0,0,114,197,0,0, + 0,114,16,0,0,0,114,202,0,0,0,114,42,0,0,0, + 114,144,0,0,0,114,109,0,0,0,114,139,0,0,0,114, + 107,0,0,0,114,150,0,0,0,114,208,0,0,0,114,8, + 0,0,0,218,19,100,111,110,116,95,119,114,105,116,101,95, + 98,121,116,101,99,111,100,101,114,153,0,0,0,114,33,0, + 0,0,114,201,0,0,0,41,10,114,110,0,0,0,114,128, + 0,0,0,114,92,0,0,0,114,142,0,0,0,114,91,0, + 0,0,218,2,115,116,114,55,0,0,0,218,10,98,121,116, + 101,115,95,100,97,116,97,114,156,0,0,0,90,11,99,111, + 100,101,95,111,98,106,101,99,116,114,4,0,0,0,114,4, + 0,0,0,114,6,0,0,0,114,189,0,0,0,249,2,0, + 0,115,78,0,0,0,0,7,15,1,6,1,3,1,16,1, + 13,1,11,2,3,1,19,1,13,1,5,2,16,1,3,1, + 19,1,13,1,5,2,3,1,9,1,12,1,13,1,19,1, + 5,2,9,1,7,1,15,1,6,1,7,1,15,1,18,1, + 13,1,22,1,12,1,9,1,15,1,3,1,19,1,17,1, + 13,1,5,1,122,21,83,111,117,114,99,101,76,111,97,100, + 101,114,46,103,101,116,95,99,111,100,101,78,114,89,0,0, + 0,41,10,114,114,0,0,0,114,113,0,0,0,114,115,0, + 0,0,114,198,0,0,0,114,199,0,0,0,114,201,0,0, + 0,114,200,0,0,0,114,204,0,0,0,114,208,0,0,0, + 114,189,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,114,196,0,0,0,191,2, + 0,0,115,14,0,0,0,12,2,12,8,12,13,12,10,12, + 7,12,10,18,8,114,196,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,115, + 112,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, + 100,1,0,90,3,0,100,2,0,100,3,0,132,0,0,90, + 4,0,100,4,0,100,5,0,132,0,0,90,5,0,100,6, + 0,100,7,0,132,0,0,90,6,0,101,7,0,135,0,0, + 102,1,0,100,8,0,100,9,0,134,0,0,131,1,0,90, + 8,0,101,7,0,100,10,0,100,11,0,132,0,0,131,1, + 0,90,9,0,100,12,0,100,13,0,132,0,0,90,10,0, + 135,0,0,83,41,14,218,10,70,105,108,101,76,111,97,100, + 101,114,122,103,66,97,115,101,32,102,105,108,101,32,108,111, + 97,100,101,114,32,99,108,97,115,115,32,119,104,105,99,104, + 32,105,109,112,108,101,109,101,110,116,115,32,116,104,101,32, + 108,111,97,100,101,114,32,112,114,111,116,111,99,111,108,32, + 109,101,116,104,111,100,115,32,116,104,97,116,10,32,32,32, + 32,114,101,113,117,105,114,101,32,102,105,108,101,32,115,121, + 115,116,101,109,32,117,115,97,103,101,46,99,3,0,0,0, + 0,0,0,0,3,0,0,0,2,0,0,0,67,0,0,0, + 115,22,0,0,0,124,1,0,124,0,0,95,0,0,124,2, + 0,124,0,0,95,1,0,100,1,0,83,41,2,122,75,67, + 97,99,104,101,32,116,104,101,32,109,111,100,117,108,101,32, + 110,97,109,101,32,97,110,100,32,116,104,101,32,112,97,116, + 104,32,116,111,32,116,104,101,32,102,105,108,101,32,102,111, + 117,110,100,32,98,121,32,116,104,101,10,32,32,32,32,32, + 32,32,32,102,105,110,100,101,114,46,78,41,2,114,108,0, + 0,0,114,37,0,0,0,41,3,114,110,0,0,0,114,128, + 0,0,0,114,37,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,6,0,0,0,114,187,0,0,0,50,3,0,0, + 115,4,0,0,0,0,3,9,1,122,19,70,105,108,101,76, + 111,97,100,101,114,46,95,95,105,110,105,116,95,95,99,2, + 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, + 0,0,0,115,34,0,0,0,124,0,0,106,0,0,124,1, + 0,106,0,0,107,2,0,111,33,0,124,0,0,106,1,0, + 124,1,0,106,1,0,107,2,0,83,41,1,78,41,2,218, + 9,95,95,99,108,97,115,115,95,95,114,120,0,0,0,41, + 2,114,110,0,0,0,218,5,111,116,104,101,114,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,218,6,95,95, + 101,113,95,95,56,3,0,0,115,4,0,0,0,0,1,18, + 1,122,17,70,105,108,101,76,111,97,100,101,114,46,95,95, + 101,113,95,95,99,1,0,0,0,0,0,0,0,1,0,0, + 0,3,0,0,0,67,0,0,0,115,26,0,0,0,116,0, + 0,124,0,0,106,1,0,131,1,0,116,0,0,124,0,0, + 106,2,0,131,1,0,65,83,41,1,78,41,3,218,4,104, + 97,115,104,114,108,0,0,0,114,37,0,0,0,41,1,114, + 110,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,8,95,95,104,97,115,104,95,95,60,3,0, + 0,115,2,0,0,0,0,1,122,19,70,105,108,101,76,111, + 97,100,101,114,46,95,95,104,97,115,104,95,95,99,2,0, + 0,0,0,0,0,0,2,0,0,0,3,0,0,0,3,0, + 0,0,115,22,0,0,0,116,0,0,116,1,0,124,0,0, + 131,2,0,106,2,0,124,1,0,131,1,0,83,41,1,122, + 100,76,111,97,100,32,97,32,109,111,100,117,108,101,32,102, + 114,111,109,32,97,32,102,105,108,101,46,10,10,32,32,32, + 32,32,32,32,32,84,104,105,115,32,109,101,116,104,111,100, + 32,105,115,32,100,101,112,114,101,99,97,116,101,100,46,32, + 32,85,115,101,32,101,120,101,99,95,109,111,100,117,108,101, + 40,41,32,105,110,115,116,101,97,100,46,10,10,32,32,32, + 32,32,32,32,32,41,3,218,5,115,117,112,101,114,114,212, + 0,0,0,114,195,0,0,0,41,2,114,110,0,0,0,114, + 128,0,0,0,41,1,114,213,0,0,0,114,4,0,0,0, + 114,6,0,0,0,114,195,0,0,0,63,3,0,0,115,2, + 0,0,0,0,10,122,22,70,105,108,101,76,111,97,100,101, + 114,46,108,111,97,100,95,109,111,100,117,108,101,99,2,0, + 0,0,0,0,0,0,2,0,0,0,1,0,0,0,67,0, + 0,0,115,7,0,0,0,124,0,0,106,0,0,83,41,1, + 122,58,82,101,116,117,114,110,32,116,104,101,32,112,97,116, + 104,32,116,111,32,116,104,101,32,115,111,117,114,99,101,32, + 102,105,108,101,32,97,115,32,102,111,117,110,100,32,98,121, + 32,116,104,101,32,102,105,110,100,101,114,46,41,1,114,37, + 0,0,0,41,2,114,110,0,0,0,114,128,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,160, + 0,0,0,75,3,0,0,115,2,0,0,0,0,3,122,23, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,102, + 105,108,101,110,97,109,101,99,2,0,0,0,0,0,0,0, + 3,0,0,0,9,0,0,0,67,0,0,0,115,42,0,0, + 0,116,0,0,106,1,0,124,1,0,100,1,0,131,2,0, + 143,17,0,125,2,0,124,2,0,106,2,0,131,0,0,83, + 87,100,2,0,81,82,88,100,2,0,83,41,3,122,39,82, + 101,116,117,114,110,32,116,104,101,32,100,97,116,97,32,102, + 114,111,109,32,112,97,116,104,32,97,115,32,114,97,119,32, + 98,121,116,101,115,46,218,1,114,78,41,3,114,51,0,0, + 0,114,52,0,0,0,90,4,114,101,97,100,41,3,114,110, + 0,0,0,114,37,0,0,0,114,56,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,114,202,0,0, + 0,80,3,0,0,115,4,0,0,0,0,2,21,1,122,19, + 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,100, + 97,116,97,41,11,114,114,0,0,0,114,113,0,0,0,114, + 115,0,0,0,114,116,0,0,0,114,187,0,0,0,114,215, + 0,0,0,114,217,0,0,0,114,125,0,0,0,114,195,0, + 0,0,114,160,0,0,0,114,202,0,0,0,114,4,0,0, + 0,114,4,0,0,0,41,1,114,213,0,0,0,114,6,0, + 0,0,114,212,0,0,0,45,3,0,0,115,14,0,0,0, + 12,3,6,2,12,6,12,4,12,3,24,12,18,5,114,212, 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, - 5,0,0,0,64,0,0,0,115,121,0,0,0,101,0,0, + 4,0,0,0,64,0,0,0,115,64,0,0,0,101,0,0, 90,1,0,100,0,0,90,2,0,100,1,0,90,3,0,100, - 2,0,90,4,0,100,3,0,90,5,0,100,4,0,90,6, - 0,101,7,0,100,5,0,100,6,0,132,0,0,131,1,0, - 90,8,0,101,7,0,100,7,0,100,8,0,132,0,0,131, - 1,0,90,9,0,101,7,0,100,9,0,100,9,0,100,10, - 0,100,11,0,132,2,0,131,1,0,90,10,0,101,7,0, - 100,9,0,100,12,0,100,13,0,132,1,0,131,1,0,90, - 11,0,100,9,0,83,41,14,218,21,87,105,110,100,111,119, - 115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,122, - 62,77,101,116,97,32,112,97,116,104,32,102,105,110,100,101, - 114,32,102,111,114,32,109,111,100,117,108,101,115,32,100,101, - 99,108,97,114,101,100,32,105,110,32,116,104,101,32,87,105, - 110,100,111,119,115,32,114,101,103,105,115,116,114,121,46,122, - 59,83,111,102,116,119,97,114,101,92,80,121,116,104,111,110, - 92,80,121,116,104,111,110,67,111,114,101,92,123,115,121,115, - 95,118,101,114,115,105,111,110,125,92,77,111,100,117,108,101, - 115,92,123,102,117,108,108,110,97,109,101,125,122,65,83,111, - 102,116,119,97,114,101,92,80,121,116,104,111,110,92,80,121, - 116,104,111,110,67,111,114,101,92,123,115,121,115,95,118,101, - 114,115,105,111,110,125,92,77,111,100,117,108,101,115,92,123, - 102,117,108,108,110,97,109,101,125,92,68,101,98,117,103,70, - 99,2,0,0,0,0,0,0,0,2,0,0,0,11,0,0, - 0,67,0,0,0,115,67,0,0,0,121,23,0,116,0,0, - 106,1,0,116,0,0,106,2,0,124,1,0,131,2,0,83, - 87,110,37,0,4,116,3,0,107,10,0,114,62,0,1,1, - 1,116,0,0,106,1,0,116,0,0,106,4,0,124,1,0, - 131,2,0,83,89,110,1,0,88,100,0,0,83,41,1,78, - 41,5,218,7,95,119,105,110,114,101,103,90,7,79,112,101, - 110,75,101,121,90,17,72,75,69,89,95,67,85,82,82,69, - 78,84,95,85,83,69,82,114,42,0,0,0,90,18,72,75, - 69,89,95,76,79,67,65,76,95,77,65,67,72,73,78,69, - 41,2,218,3,99,108,115,114,5,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,218,14,95,111,112, - 101,110,95,114,101,103,105,115,116,114,121,87,2,0,0,115, - 8,0,0,0,0,2,3,1,23,1,13,1,122,36,87,105, - 110,100,111,119,115,82,101,103,105,115,116,114,121,70,105,110, - 100,101,114,46,95,111,112,101,110,95,114,101,103,105,115,116, - 114,121,99,2,0,0,0,0,0,0,0,6,0,0,0,16, - 0,0,0,67,0,0,0,115,143,0,0,0,124,0,0,106, - 0,0,114,21,0,124,0,0,106,1,0,125,2,0,110,9, - 0,124,0,0,106,2,0,125,2,0,124,2,0,106,3,0, - 100,1,0,124,1,0,100,2,0,116,4,0,106,5,0,100, - 0,0,100,3,0,133,2,0,25,131,0,2,125,3,0,121, - 47,0,124,0,0,106,6,0,124,3,0,131,1,0,143,25, - 0,125,4,0,116,7,0,106,8,0,124,4,0,100,4,0, - 131,2,0,125,5,0,87,100,0,0,81,82,88,87,110,22, - 0,4,116,9,0,107,10,0,114,138,0,1,1,1,100,0, - 0,83,89,110,1,0,88,124,5,0,83,41,5,78,114,128, - 0,0,0,90,11,115,121,115,95,118,101,114,115,105,111,110, - 114,82,0,0,0,114,32,0,0,0,41,10,218,11,68,69, - 66,85,71,95,66,85,73,76,68,218,18,82,69,71,73,83, - 84,82,89,95,75,69,89,95,68,69,66,85,71,218,12,82, - 69,71,73,83,84,82,89,95,75,69,89,114,49,0,0,0, - 114,8,0,0,0,218,7,118,101,114,115,105,111,110,114,173, - 0,0,0,114,171,0,0,0,90,10,81,117,101,114,121,86, - 97,108,117,101,114,42,0,0,0,41,6,114,172,0,0,0, - 114,128,0,0,0,90,12,114,101,103,105,115,116,114,121,95, - 107,101,121,114,5,0,0,0,90,4,104,107,101,121,218,8, - 102,105,108,101,112,97,116,104,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,218,16,95,115,101,97,114,99,104, - 95,114,101,103,105,115,116,114,121,94,2,0,0,115,22,0, - 0,0,0,2,9,1,12,2,9,1,15,1,22,1,3,1, - 18,1,29,1,13,1,9,1,122,38,87,105,110,100,111,119, - 115,82,101,103,105,115,116,114,121,70,105,110,100,101,114,46, - 95,115,101,97,114,99,104,95,114,101,103,105,115,116,114,121, - 78,99,4,0,0,0,0,0,0,0,8,0,0,0,14,0, - 0,0,67,0,0,0,115,158,0,0,0,124,0,0,106,0, - 0,124,1,0,131,1,0,125,4,0,124,4,0,100,0,0, - 107,8,0,114,31,0,100,0,0,83,121,14,0,116,1,0, - 124,4,0,131,1,0,1,87,110,22,0,4,116,2,0,107, - 10,0,114,69,0,1,1,1,100,0,0,83,89,110,1,0, - 88,120,81,0,116,3,0,131,0,0,68,93,70,0,92,2, - 0,125,5,0,125,6,0,124,4,0,106,4,0,116,5,0, - 124,6,0,131,1,0,131,1,0,114,80,0,116,6,0,106, - 7,0,124,1,0,124,5,0,124,1,0,124,4,0,131,2, - 0,100,1,0,124,4,0,131,2,1,125,7,0,124,7,0, - 83,113,80,0,87,100,0,0,83,41,2,78,114,160,0,0, - 0,41,8,114,179,0,0,0,114,41,0,0,0,114,42,0, - 0,0,114,163,0,0,0,114,94,0,0,0,114,95,0,0, - 0,114,123,0,0,0,218,16,115,112,101,99,95,102,114,111, - 109,95,108,111,97,100,101,114,41,8,114,172,0,0,0,114, - 128,0,0,0,114,37,0,0,0,218,6,116,97,114,103,101, - 116,114,178,0,0,0,114,129,0,0,0,114,168,0,0,0, - 114,166,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,218,9,102,105,110,100,95,115,112,101,99,109, - 2,0,0,115,26,0,0,0,0,2,15,1,12,1,4,1, - 3,1,14,1,13,1,9,1,22,1,21,1,9,1,15,1, - 9,1,122,31,87,105,110,100,111,119,115,82,101,103,105,115, - 116,114,121,70,105,110,100,101,114,46,102,105,110,100,95,115, - 112,101,99,99,3,0,0,0,0,0,0,0,4,0,0,0, - 3,0,0,0,67,0,0,0,115,45,0,0,0,124,0,0, - 106,0,0,124,1,0,124,2,0,131,2,0,125,3,0,124, - 3,0,100,1,0,107,9,0,114,37,0,124,3,0,106,1, - 0,83,100,1,0,83,100,1,0,83,41,2,122,108,70,105, - 110,100,32,109,111,100,117,108,101,32,110,97,109,101,100,32, - 105,110,32,116,104,101,32,114,101,103,105,115,116,114,121,46, - 10,10,32,32,32,32,32,32,32,32,84,104,105,115,32,109, - 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, - 116,101,100,46,32,32,85,115,101,32,101,120,101,99,95,109, - 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,46, - 10,10,32,32,32,32,32,32,32,32,78,41,2,114,182,0, - 0,0,114,129,0,0,0,41,4,114,172,0,0,0,114,128, - 0,0,0,114,37,0,0,0,114,166,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,6,0,0,0,218,11,102,105, - 110,100,95,109,111,100,117,108,101,125,2,0,0,115,8,0, - 0,0,0,7,18,1,12,1,7,2,122,33,87,105,110,100, - 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, - 114,46,102,105,110,100,95,109,111,100,117,108,101,41,12,114, + 2,0,100,3,0,132,0,0,90,4,0,100,4,0,100,5, + 0,132,0,0,90,5,0,100,6,0,100,7,0,100,8,0, + 100,9,0,132,0,1,90,6,0,100,10,0,83,41,11,218, + 16,83,111,117,114,99,101,70,105,108,101,76,111,97,100,101, + 114,122,62,67,111,110,99,114,101,116,101,32,105,109,112,108, + 101,109,101,110,116,97,116,105,111,110,32,111,102,32,83,111, + 117,114,99,101,76,111,97,100,101,114,32,117,115,105,110,103, + 32,116,104,101,32,102,105,108,101,32,115,121,115,116,101,109, + 46,99,2,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,34,0,0,0,116,0,0,124,1, + 0,131,1,0,125,2,0,100,1,0,124,2,0,106,1,0, + 100,2,0,124,2,0,106,2,0,105,2,0,83,41,3,122, + 33,82,101,116,117,114,110,32,116,104,101,32,109,101,116,97, + 100,97,116,97,32,102,111,114,32,116,104,101,32,112,97,116, + 104,46,114,135,0,0,0,114,136,0,0,0,41,3,114,41, + 0,0,0,218,8,115,116,95,109,116,105,109,101,90,7,115, + 116,95,115,105,122,101,41,3,114,110,0,0,0,114,37,0, + 0,0,114,210,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,114,199,0,0,0,90,3,0,0,115, + 4,0,0,0,0,2,12,1,122,27,83,111,117,114,99,101, + 70,105,108,101,76,111,97,100,101,114,46,112,97,116,104,95, + 115,116,97,116,115,99,4,0,0,0,0,0,0,0,5,0, + 0,0,5,0,0,0,67,0,0,0,115,34,0,0,0,116, + 0,0,124,1,0,131,1,0,125,4,0,124,0,0,106,1, + 0,124,2,0,124,3,0,100,1,0,124,4,0,131,2,1, + 83,41,2,78,218,5,95,109,111,100,101,41,2,114,99,0, + 0,0,114,200,0,0,0,41,5,114,110,0,0,0,114,92, + 0,0,0,114,91,0,0,0,114,55,0,0,0,114,44,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,114,201,0,0,0,95,3,0,0,115,4,0,0,0,0, + 2,12,1,122,32,83,111,117,114,99,101,70,105,108,101,76, + 111,97,100,101,114,46,95,99,97,99,104,101,95,98,121,116, + 101,99,111,100,101,114,222,0,0,0,105,182,1,0,0,99, + 3,0,0,0,1,0,0,0,9,0,0,0,17,0,0,0, + 67,0,0,0,115,53,1,0,0,116,0,0,124,1,0,131, + 1,0,92,2,0,125,4,0,125,5,0,103,0,0,125,6, + 0,120,54,0,124,4,0,114,80,0,116,1,0,124,4,0, + 131,1,0,12,114,80,0,116,0,0,124,4,0,131,1,0, + 92,2,0,125,4,0,125,7,0,124,6,0,106,2,0,124, + 7,0,131,1,0,1,113,27,0,87,120,132,0,116,3,0, + 124,6,0,131,1,0,68,93,118,0,125,7,0,116,4,0, + 124,4,0,124,7,0,131,2,0,125,4,0,121,17,0,116, + 5,0,106,6,0,124,4,0,131,1,0,1,87,113,94,0, + 4,116,7,0,107,10,0,114,155,0,1,1,1,119,94,0, + 89,113,94,0,4,116,8,0,107,10,0,114,211,0,1,125, + 8,0,1,122,25,0,116,9,0,100,1,0,124,4,0,124, + 8,0,131,3,0,1,100,2,0,83,87,89,100,2,0,100, + 2,0,125,8,0,126,8,0,88,113,94,0,88,113,94,0, + 87,121,33,0,116,10,0,124,1,0,124,2,0,124,3,0, + 131,3,0,1,116,9,0,100,3,0,124,1,0,131,2,0, + 1,87,110,53,0,4,116,8,0,107,10,0,114,48,1,1, + 125,8,0,1,122,21,0,116,9,0,100,1,0,124,1,0, + 124,8,0,131,3,0,1,87,89,100,2,0,100,2,0,125, + 8,0,126,8,0,88,110,1,0,88,100,2,0,83,41,4, + 122,27,87,114,105,116,101,32,98,121,116,101,115,32,100,97, + 116,97,32,116,111,32,97,32,102,105,108,101,46,122,27,99, + 111,117,108,100,32,110,111,116,32,99,114,101,97,116,101,32, + 123,33,114,125,58,32,123,33,114,125,78,122,12,99,114,101, + 97,116,101,100,32,123,33,114,125,41,11,114,40,0,0,0, + 114,48,0,0,0,114,166,0,0,0,114,35,0,0,0,114, + 30,0,0,0,114,3,0,0,0,90,5,109,107,100,105,114, + 218,15,70,105,108,101,69,120,105,115,116,115,69,114,114,111, + 114,114,42,0,0,0,114,107,0,0,0,114,57,0,0,0, + 41,9,114,110,0,0,0,114,37,0,0,0,114,55,0,0, + 0,114,222,0,0,0,218,6,112,97,114,101,110,116,114,96, + 0,0,0,114,29,0,0,0,114,25,0,0,0,114,203,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,114,200,0,0,0,100,3,0,0,115,38,0,0,0,0, + 2,18,1,6,2,22,1,18,1,17,2,19,1,15,1,3, + 1,17,1,13,2,7,1,18,3,16,1,27,1,3,1,16, + 1,17,1,18,2,122,25,83,111,117,114,99,101,70,105,108, + 101,76,111,97,100,101,114,46,115,101,116,95,100,97,116,97, + 78,41,7,114,114,0,0,0,114,113,0,0,0,114,115,0, + 0,0,114,116,0,0,0,114,199,0,0,0,114,201,0,0, + 0,114,200,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,6,0,0,0,114,220,0,0,0,86, + 3,0,0,115,8,0,0,0,12,2,6,2,12,5,12,5, + 114,220,0,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,2,0,0,0,64,0,0,0,115,46,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,90,3, + 0,100,2,0,100,3,0,132,0,0,90,4,0,100,4,0, + 100,5,0,132,0,0,90,5,0,100,6,0,83,41,7,218, + 20,83,111,117,114,99,101,108,101,115,115,70,105,108,101,76, + 111,97,100,101,114,122,45,76,111,97,100,101,114,32,119,104, + 105,99,104,32,104,97,110,100,108,101,115,32,115,111,117,114, + 99,101,108,101,115,115,32,102,105,108,101,32,105,109,112,111, + 114,116,115,46,99,2,0,0,0,0,0,0,0,5,0,0, + 0,6,0,0,0,67,0,0,0,115,76,0,0,0,124,0, + 0,106,0,0,124,1,0,131,1,0,125,2,0,124,0,0, + 106,1,0,124,2,0,131,1,0,125,3,0,116,2,0,124, + 3,0,100,1,0,124,1,0,100,2,0,124,2,0,131,1, + 2,125,4,0,116,3,0,124,4,0,100,1,0,124,1,0, + 100,3,0,124,2,0,131,1,2,83,41,4,78,114,108,0, + 0,0,114,37,0,0,0,114,91,0,0,0,41,4,114,160, + 0,0,0,114,202,0,0,0,114,144,0,0,0,114,150,0, + 0,0,41,5,114,110,0,0,0,114,128,0,0,0,114,37, + 0,0,0,114,55,0,0,0,114,211,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,114,189,0,0, + 0,133,3,0,0,115,8,0,0,0,0,1,15,1,15,1, + 24,1,122,29,83,111,117,114,99,101,108,101,115,115,70,105, + 108,101,76,111,97,100,101,114,46,103,101,116,95,99,111,100, + 101,99,2,0,0,0,0,0,0,0,2,0,0,0,1,0, + 0,0,67,0,0,0,115,4,0,0,0,100,1,0,83,41, + 2,122,39,82,101,116,117,114,110,32,78,111,110,101,32,97, + 115,32,116,104,101,114,101,32,105,115,32,110,111,32,115,111, + 117,114,99,101,32,99,111,100,101,46,78,114,4,0,0,0, + 41,2,114,110,0,0,0,114,128,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,114,204,0,0,0, + 139,3,0,0,115,2,0,0,0,0,2,122,31,83,111,117, + 114,99,101,108,101,115,115,70,105,108,101,76,111,97,100,101, + 114,46,103,101,116,95,115,111,117,114,99,101,78,41,6,114, 114,0,0,0,114,113,0,0,0,114,115,0,0,0,114,116, - 0,0,0,114,176,0,0,0,114,175,0,0,0,114,174,0, - 0,0,218,11,99,108,97,115,115,109,101,116,104,111,100,114, - 173,0,0,0,114,179,0,0,0,114,182,0,0,0,114,183, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,114,170,0,0,0,75,2,0,0, - 115,20,0,0,0,12,2,6,3,6,3,6,2,6,2,18, - 7,18,15,3,1,21,15,3,1,114,170,0,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, - 0,0,0,115,70,0,0,0,101,0,0,90,1,0,100,0, - 0,90,2,0,100,1,0,90,3,0,100,2,0,100,3,0, - 132,0,0,90,4,0,100,4,0,100,5,0,132,0,0,90, - 5,0,100,6,0,100,7,0,132,0,0,90,6,0,100,8, - 0,100,9,0,132,0,0,90,7,0,100,10,0,83,41,11, - 218,13,95,76,111,97,100,101,114,66,97,115,105,99,115,122, - 83,66,97,115,101,32,99,108,97,115,115,32,111,102,32,99, - 111,109,109,111,110,32,99,111,100,101,32,110,101,101,100,101, - 100,32,98,121,32,98,111,116,104,32,83,111,117,114,99,101, - 76,111,97,100,101,114,32,97,110,100,10,32,32,32,32,83, - 111,117,114,99,101,108,101,115,115,70,105,108,101,76,111,97, - 100,101,114,46,99,2,0,0,0,0,0,0,0,5,0,0, - 0,3,0,0,0,67,0,0,0,115,88,0,0,0,116,0, - 0,124,0,0,106,1,0,124,1,0,131,1,0,131,1,0, - 100,1,0,25,125,2,0,124,2,0,106,2,0,100,2,0, - 100,1,0,131,2,0,100,3,0,25,125,3,0,124,1,0, - 106,3,0,100,2,0,131,1,0,100,4,0,25,125,4,0, - 124,3,0,100,5,0,107,2,0,111,87,0,124,4,0,100, - 5,0,107,3,0,83,41,6,122,141,67,111,110,99,114,101, - 116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,32,111,102,32,73,110,115,112,101,99,116,76,111,97,100, - 101,114,46,105,115,95,112,97,99,107,97,103,101,32,98,121, - 32,99,104,101,99,107,105,110,103,32,105,102,10,32,32,32, - 32,32,32,32,32,116,104,101,32,112,97,116,104,32,114,101, - 116,117,114,110,101,100,32,98,121,32,103,101,116,95,102,105, - 108,101,110,97,109,101,32,104,97,115,32,97,32,102,105,108, - 101,110,97,109,101,32,111,102,32,39,95,95,105,110,105,116, - 95,95,46,112,121,39,46,114,31,0,0,0,114,60,0,0, - 0,114,61,0,0,0,114,58,0,0,0,218,8,95,95,105, - 110,105,116,95,95,41,4,114,40,0,0,0,114,159,0,0, - 0,114,36,0,0,0,114,34,0,0,0,41,5,114,110,0, - 0,0,114,128,0,0,0,114,96,0,0,0,90,13,102,105, - 108,101,110,97,109,101,95,98,97,115,101,90,9,116,97,105, - 108,95,110,97,109,101,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,161,0,0,0,144,2,0,0,115,8, - 0,0,0,0,3,25,1,22,1,19,1,122,24,95,76,111, - 97,100,101,114,66,97,115,105,99,115,46,105,115,95,112,97, - 99,107,97,103,101,99,2,0,0,0,0,0,0,0,2,0, - 0,0,1,0,0,0,67,0,0,0,115,4,0,0,0,100, - 1,0,83,41,2,122,42,85,115,101,32,100,101,102,97,117, - 108,116,32,115,101,109,97,110,116,105,99,115,32,102,111,114, - 32,109,111,100,117,108,101,32,99,114,101,97,116,105,111,110, - 46,78,114,4,0,0,0,41,2,114,110,0,0,0,114,166, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,13,99,114,101,97,116,101,95,109,111,100,117,108, - 101,152,2,0,0,115,0,0,0,0,122,27,95,76,111,97, - 100,101,114,66,97,115,105,99,115,46,99,114,101,97,116,101, - 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, - 3,0,0,0,4,0,0,0,67,0,0,0,115,80,0,0, - 0,124,0,0,106,0,0,124,1,0,106,1,0,131,1,0, - 125,2,0,124,2,0,100,1,0,107,8,0,114,54,0,116, - 2,0,100,2,0,106,3,0,124,1,0,106,1,0,131,1, - 0,131,1,0,130,1,0,116,4,0,106,5,0,116,6,0, - 124,2,0,124,1,0,106,7,0,131,3,0,1,100,1,0, - 83,41,3,122,19,69,120,101,99,117,116,101,32,116,104,101, - 32,109,111,100,117,108,101,46,78,122,52,99,97,110,110,111, - 116,32,108,111,97,100,32,109,111,100,117,108,101,32,123,33, - 114,125,32,119,104,101,110,32,103,101,116,95,99,111,100,101, - 40,41,32,114,101,116,117,114,110,115,32,78,111,110,101,41, - 8,218,8,103,101,116,95,99,111,100,101,114,114,0,0,0, - 114,109,0,0,0,114,49,0,0,0,114,123,0,0,0,218, - 25,95,99,97,108,108,95,119,105,116,104,95,102,114,97,109, - 101,115,95,114,101,109,111,118,101,100,218,4,101,120,101,99, - 114,120,0,0,0,41,3,114,110,0,0,0,218,6,109,111, - 100,117,108,101,114,148,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,11,101,120,101,99,95,109, - 111,100,117,108,101,155,2,0,0,115,10,0,0,0,0,2, - 18,1,12,1,9,1,15,1,122,25,95,76,111,97,100,101, - 114,66,97,115,105,99,115,46,101,120,101,99,95,109,111,100, - 117,108,101,99,2,0,0,0,0,0,0,0,2,0,0,0, - 3,0,0,0,67,0,0,0,115,16,0,0,0,116,0,0, - 106,1,0,124,0,0,124,1,0,131,2,0,83,41,1,78, - 41,2,114,123,0,0,0,218,17,95,108,111,97,100,95,109, - 111,100,117,108,101,95,115,104,105,109,41,2,114,110,0,0, - 0,114,128,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,218,11,108,111,97,100,95,109,111,100,117, - 108,101,163,2,0,0,115,2,0,0,0,0,1,122,25,95, - 76,111,97,100,101,114,66,97,115,105,99,115,46,108,111,97, - 100,95,109,111,100,117,108,101,78,41,8,114,114,0,0,0, - 114,113,0,0,0,114,115,0,0,0,114,116,0,0,0,114, - 161,0,0,0,114,187,0,0,0,114,192,0,0,0,114,194, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,114,185,0,0,0,139,2,0,0, - 115,10,0,0,0,12,3,6,2,12,8,12,3,12,8,114, - 185,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, - 0,4,0,0,0,64,0,0,0,115,106,0,0,0,101,0, - 0,90,1,0,100,0,0,90,2,0,100,1,0,100,2,0, - 132,0,0,90,3,0,100,3,0,100,4,0,132,0,0,90, - 4,0,100,5,0,100,6,0,132,0,0,90,5,0,100,7, - 0,100,8,0,132,0,0,90,6,0,100,9,0,100,10,0, - 132,0,0,90,7,0,100,11,0,100,18,0,100,13,0,100, - 14,0,132,0,1,90,8,0,100,15,0,100,16,0,132,0, - 0,90,9,0,100,17,0,83,41,19,218,12,83,111,117,114, - 99,101,76,111,97,100,101,114,99,2,0,0,0,0,0,0, - 0,2,0,0,0,1,0,0,0,67,0,0,0,115,10,0, - 0,0,116,0,0,130,1,0,100,1,0,83,41,2,122,178, - 79,112,116,105,111,110,97,108,32,109,101,116,104,111,100,32, - 116,104,97,116,32,114,101,116,117,114,110,115,32,116,104,101, - 32,109,111,100,105,102,105,99,97,116,105,111,110,32,116,105, - 109,101,32,40,97,110,32,105,110,116,41,32,102,111,114,32, - 116,104,101,10,32,32,32,32,32,32,32,32,115,112,101,99, - 105,102,105,101,100,32,112,97,116,104,44,32,119,104,101,114, - 101,32,112,97,116,104,32,105,115,32,97,32,115,116,114,46, - 10,10,32,32,32,32,32,32,32,32,82,97,105,115,101,115, - 32,73,79,69,114,114,111,114,32,119,104,101,110,32,116,104, - 101,32,112,97,116,104,32,99,97,110,110,111,116,32,98,101, - 32,104,97,110,100,108,101,100,46,10,32,32,32,32,32,32, - 32,32,78,41,1,218,7,73,79,69,114,114,111,114,41,2, - 114,110,0,0,0,114,37,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,218,10,112,97,116,104,95, - 109,116,105,109,101,169,2,0,0,115,2,0,0,0,0,6, - 122,23,83,111,117,114,99,101,76,111,97,100,101,114,46,112, - 97,116,104,95,109,116,105,109,101,99,2,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,67,0,0,0,115,19, - 0,0,0,100,1,0,124,0,0,106,0,0,124,1,0,131, - 1,0,105,1,0,83,41,2,97,170,1,0,0,79,112,116, - 105,111,110,97,108,32,109,101,116,104,111,100,32,114,101,116, - 117,114,110,105,110,103,32,97,32,109,101,116,97,100,97,116, - 97,32,100,105,99,116,32,102,111,114,32,116,104,101,32,115, - 112,101,99,105,102,105,101,100,32,112,97,116,104,10,32,32, - 32,32,32,32,32,32,116,111,32,98,121,32,116,104,101,32, - 112,97,116,104,32,40,115,116,114,41,46,10,32,32,32,32, - 32,32,32,32,80,111,115,115,105,98,108,101,32,107,101,121, - 115,58,10,32,32,32,32,32,32,32,32,45,32,39,109,116, - 105,109,101,39,32,40,109,97,110,100,97,116,111,114,121,41, - 32,105,115,32,116,104,101,32,110,117,109,101,114,105,99,32, - 116,105,109,101,115,116,97,109,112,32,111,102,32,108,97,115, - 116,32,115,111,117,114,99,101,10,32,32,32,32,32,32,32, - 32,32,32,99,111,100,101,32,109,111,100,105,102,105,99,97, - 116,105,111,110,59,10,32,32,32,32,32,32,32,32,45,32, - 39,115,105,122,101,39,32,40,111,112,116,105,111,110,97,108, - 41,32,105,115,32,116,104,101,32,115,105,122,101,32,105,110, - 32,98,121,116,101,115,32,111,102,32,116,104,101,32,115,111, - 117,114,99,101,32,99,111,100,101,46,10,10,32,32,32,32, - 32,32,32,32,73,109,112,108,101,109,101,110,116,105,110,103, - 32,116,104,105,115,32,109,101,116,104,111,100,32,97,108,108, - 111,119,115,32,116,104,101,32,108,111,97,100,101,114,32,116, - 111,32,114,101,97,100,32,98,121,116,101,99,111,100,101,32, - 102,105,108,101,115,46,10,32,32,32,32,32,32,32,32,82, - 97,105,115,101,115,32,73,79,69,114,114,111,114,32,119,104, - 101,110,32,116,104,101,32,112,97,116,104,32,99,97,110,110, - 111,116,32,98,101,32,104,97,110,100,108,101,100,46,10,32, - 32,32,32,32,32,32,32,114,135,0,0,0,41,1,114,197, - 0,0,0,41,2,114,110,0,0,0,114,37,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,6,0,0,0,218,10, - 112,97,116,104,95,115,116,97,116,115,177,2,0,0,115,2, - 0,0,0,0,11,122,23,83,111,117,114,99,101,76,111,97, - 100,101,114,46,112,97,116,104,95,115,116,97,116,115,99,4, - 0,0,0,0,0,0,0,4,0,0,0,3,0,0,0,67, - 0,0,0,115,16,0,0,0,124,0,0,106,0,0,124,2, - 0,124,3,0,131,2,0,83,41,1,122,228,79,112,116,105, - 111,110,97,108,32,109,101,116,104,111,100,32,119,104,105,99, - 104,32,119,114,105,116,101,115,32,100,97,116,97,32,40,98, - 121,116,101,115,41,32,116,111,32,97,32,102,105,108,101,32, - 112,97,116,104,32,40,97,32,115,116,114,41,46,10,10,32, - 32,32,32,32,32,32,32,73,109,112,108,101,109,101,110,116, - 105,110,103,32,116,104,105,115,32,109,101,116,104,111,100,32, - 97,108,108,111,119,115,32,102,111,114,32,116,104,101,32,119, - 114,105,116,105,110,103,32,111,102,32,98,121,116,101,99,111, - 100,101,32,102,105,108,101,115,46,10,10,32,32,32,32,32, - 32,32,32,84,104,101,32,115,111,117,114,99,101,32,112,97, - 116,104,32,105,115,32,110,101,101,100,101,100,32,105,110,32, - 111,114,100,101,114,32,116,111,32,99,111,114,114,101,99,116, - 108,121,32,116,114,97,110,115,102,101,114,32,112,101,114,109, - 105,115,115,105,111,110,115,10,32,32,32,32,32,32,32,32, - 41,1,218,8,115,101,116,95,100,97,116,97,41,4,114,110, - 0,0,0,114,92,0,0,0,90,10,99,97,99,104,101,95, - 112,97,116,104,114,55,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,15,95,99,97,99,104,101, - 95,98,121,116,101,99,111,100,101,190,2,0,0,115,2,0, - 0,0,0,8,122,28,83,111,117,114,99,101,76,111,97,100, - 101,114,46,95,99,97,99,104,101,95,98,121,116,101,99,111, - 100,101,99,3,0,0,0,0,0,0,0,3,0,0,0,1, - 0,0,0,67,0,0,0,115,4,0,0,0,100,1,0,83, - 41,2,122,150,79,112,116,105,111,110,97,108,32,109,101,116, - 104,111,100,32,119,104,105,99,104,32,119,114,105,116,101,115, - 32,100,97,116,97,32,40,98,121,116,101,115,41,32,116,111, - 32,97,32,102,105,108,101,32,112,97,116,104,32,40,97,32, - 115,116,114,41,46,10,10,32,32,32,32,32,32,32,32,73, - 109,112,108,101,109,101,110,116,105,110,103,32,116,104,105,115, - 32,109,101,116,104,111,100,32,97,108,108,111,119,115,32,102, - 111,114,32,116,104,101,32,119,114,105,116,105,110,103,32,111, - 102,32,98,121,116,101,99,111,100,101,32,102,105,108,101,115, - 46,10,32,32,32,32,32,32,32,32,78,114,4,0,0,0, - 41,3,114,110,0,0,0,114,37,0,0,0,114,55,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,199,0,0,0,200,2,0,0,115,0,0,0,0,122,21, - 83,111,117,114,99,101,76,111,97,100,101,114,46,115,101,116, - 95,100,97,116,97,99,2,0,0,0,0,0,0,0,5,0, - 0,0,16,0,0,0,67,0,0,0,115,105,0,0,0,124, - 0,0,106,0,0,124,1,0,131,1,0,125,2,0,121,19, - 0,124,0,0,106,1,0,124,2,0,131,1,0,125,3,0, - 87,110,58,0,4,116,2,0,107,10,0,114,94,0,1,125, - 4,0,1,122,26,0,116,3,0,100,1,0,100,2,0,124, - 1,0,131,1,1,124,4,0,130,2,0,87,89,100,3,0, - 100,3,0,125,4,0,126,4,0,88,110,1,0,88,116,4, - 0,124,3,0,131,1,0,83,41,4,122,52,67,111,110,99, - 114,101,116,101,32,105,109,112,108,101,109,101,110,116,97,116, - 105,111,110,32,111,102,32,73,110,115,112,101,99,116,76,111, - 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,46, - 122,39,115,111,117,114,99,101,32,110,111,116,32,97,118,97, - 105,108,97,98,108,101,32,116,104,114,111,117,103,104,32,103, - 101,116,95,100,97,116,97,40,41,114,108,0,0,0,78,41, - 5,114,159,0,0,0,218,8,103,101,116,95,100,97,116,97, - 114,42,0,0,0,114,109,0,0,0,114,157,0,0,0,41, - 5,114,110,0,0,0,114,128,0,0,0,114,37,0,0,0, - 114,155,0,0,0,218,3,101,120,99,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,218,10,103,101,116,95,115, - 111,117,114,99,101,207,2,0,0,115,14,0,0,0,0,2, - 15,1,3,1,19,1,18,1,9,1,31,1,122,23,83,111, - 117,114,99,101,76,111,97,100,101,114,46,103,101,116,95,115, - 111,117,114,99,101,218,9,95,111,112,116,105,109,105,122,101, - 114,31,0,0,0,99,3,0,0,0,1,0,0,0,4,0, - 0,0,9,0,0,0,67,0,0,0,115,34,0,0,0,116, - 0,0,106,1,0,116,2,0,124,1,0,124,2,0,100,1, - 0,100,2,0,100,3,0,100,4,0,124,3,0,131,4,2, - 83,41,5,122,130,82,101,116,117,114,110,32,116,104,101,32, - 99,111,100,101,32,111,98,106,101,99,116,32,99,111,109,112, - 105,108,101,100,32,102,114,111,109,32,115,111,117,114,99,101, - 46,10,10,32,32,32,32,32,32,32,32,84,104,101,32,39, - 100,97,116,97,39,32,97,114,103,117,109,101,110,116,32,99, - 97,110,32,98,101,32,97,110,121,32,111,98,106,101,99,116, - 32,116,121,112,101,32,116,104,97,116,32,99,111,109,112,105, - 108,101,40,41,32,115,117,112,112,111,114,116,115,46,10,32, - 32,32,32,32,32,32,32,114,190,0,0,0,218,12,100,111, - 110,116,95,105,110,104,101,114,105,116,84,114,70,0,0,0, - 41,3,114,123,0,0,0,114,189,0,0,0,218,7,99,111, - 109,112,105,108,101,41,4,114,110,0,0,0,114,55,0,0, - 0,114,37,0,0,0,114,204,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,14,115,111,117,114, - 99,101,95,116,111,95,99,111,100,101,217,2,0,0,115,4, - 0,0,0,0,5,21,1,122,27,83,111,117,114,99,101,76, - 111,97,100,101,114,46,115,111,117,114,99,101,95,116,111,95, - 99,111,100,101,99,2,0,0,0,0,0,0,0,10,0,0, - 0,43,0,0,0,67,0,0,0,115,174,1,0,0,124,0, - 0,106,0,0,124,1,0,131,1,0,125,2,0,100,1,0, - 125,3,0,121,16,0,116,1,0,124,2,0,131,1,0,125, - 4,0,87,110,24,0,4,116,2,0,107,10,0,114,63,0, - 1,1,1,100,1,0,125,4,0,89,110,202,0,88,121,19, - 0,124,0,0,106,3,0,124,2,0,131,1,0,125,5,0, - 87,110,18,0,4,116,4,0,107,10,0,114,103,0,1,1, - 1,89,110,162,0,88,116,5,0,124,5,0,100,2,0,25, - 131,1,0,125,3,0,121,19,0,124,0,0,106,6,0,124, - 4,0,131,1,0,125,6,0,87,110,18,0,4,116,7,0, - 107,10,0,114,159,0,1,1,1,89,110,106,0,88,121,34, - 0,116,8,0,124,6,0,100,3,0,124,5,0,100,4,0, - 124,1,0,100,5,0,124,4,0,131,1,3,125,7,0,87, - 110,24,0,4,116,9,0,116,10,0,102,2,0,107,10,0, - 114,220,0,1,1,1,89,110,45,0,88,116,11,0,100,6, - 0,124,4,0,124,2,0,131,3,0,1,116,12,0,124,7, - 0,100,4,0,124,1,0,100,7,0,124,4,0,100,8,0, - 124,2,0,131,1,3,83,124,0,0,106,6,0,124,2,0, - 131,1,0,125,8,0,124,0,0,106,13,0,124,8,0,124, - 2,0,131,2,0,125,9,0,116,11,0,100,9,0,124,2, - 0,131,2,0,1,116,14,0,106,15,0,12,114,170,1,124, - 4,0,100,1,0,107,9,0,114,170,1,124,3,0,100,1, - 0,107,9,0,114,170,1,116,16,0,124,9,0,124,3,0, - 116,17,0,124,8,0,131,1,0,131,3,0,125,6,0,121, - 36,0,124,0,0,106,18,0,124,2,0,124,4,0,124,6, - 0,131,3,0,1,116,11,0,100,10,0,124,4,0,131,2, - 0,1,87,110,18,0,4,116,2,0,107,10,0,114,169,1, - 1,1,1,89,110,1,0,88,124,9,0,83,41,11,122,190, - 67,111,110,99,114,101,116,101,32,105,109,112,108,101,109,101, - 110,116,97,116,105,111,110,32,111,102,32,73,110,115,112,101, - 99,116,76,111,97,100,101,114,46,103,101,116,95,99,111,100, - 101,46,10,10,32,32,32,32,32,32,32,32,82,101,97,100, - 105,110,103,32,111,102,32,98,121,116,101,99,111,100,101,32, - 114,101,113,117,105,114,101,115,32,112,97,116,104,95,115,116, - 97,116,115,32,116,111,32,98,101,32,105,109,112,108,101,109, - 101,110,116,101,100,46,32,84,111,32,119,114,105,116,101,10, - 32,32,32,32,32,32,32,32,98,121,116,101,99,111,100,101, - 44,32,115,101,116,95,100,97,116,97,32,109,117,115,116,32, - 97,108,115,111,32,98,101,32,105,109,112,108,101,109,101,110, - 116,101,100,46,10,10,32,32,32,32,32,32,32,32,78,114, - 135,0,0,0,114,140,0,0,0,114,108,0,0,0,114,37, - 0,0,0,122,13,123,125,32,109,97,116,99,104,101,115,32, - 123,125,114,91,0,0,0,114,92,0,0,0,122,19,99,111, - 100,101,32,111,98,106,101,99,116,32,102,114,111,109,32,123, - 125,122,10,119,114,111,116,101,32,123,33,114,125,41,19,114, - 159,0,0,0,114,81,0,0,0,114,68,0,0,0,114,198, - 0,0,0,114,196,0,0,0,114,16,0,0,0,114,201,0, - 0,0,114,42,0,0,0,114,143,0,0,0,114,109,0,0, - 0,114,138,0,0,0,114,107,0,0,0,114,149,0,0,0, - 114,207,0,0,0,114,8,0,0,0,218,19,100,111,110,116, - 95,119,114,105,116,101,95,98,121,116,101,99,111,100,101,114, - 152,0,0,0,114,33,0,0,0,114,200,0,0,0,41,10, - 114,110,0,0,0,114,128,0,0,0,114,92,0,0,0,114, - 141,0,0,0,114,91,0,0,0,218,2,115,116,114,55,0, - 0,0,218,10,98,121,116,101,115,95,100,97,116,97,114,155, - 0,0,0,90,11,99,111,100,101,95,111,98,106,101,99,116, - 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,114, - 188,0,0,0,225,2,0,0,115,78,0,0,0,0,7,15, - 1,6,1,3,1,16,1,13,1,11,2,3,1,19,1,13, - 1,5,2,16,1,3,1,19,1,13,1,5,2,3,1,9, - 1,12,1,13,1,19,1,5,2,9,1,7,1,15,1,6, - 1,7,1,15,1,18,1,13,1,22,1,12,1,9,1,15, - 1,3,1,19,1,17,1,13,1,5,1,122,21,83,111,117, - 114,99,101,76,111,97,100,101,114,46,103,101,116,95,99,111, - 100,101,78,114,89,0,0,0,41,10,114,114,0,0,0,114, - 113,0,0,0,114,115,0,0,0,114,197,0,0,0,114,198, - 0,0,0,114,200,0,0,0,114,199,0,0,0,114,203,0, - 0,0,114,207,0,0,0,114,188,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,195,0,0,0,167,2,0,0,115,14,0,0,0,12,2, - 12,8,12,13,12,10,12,7,12,10,18,8,114,195,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, - 0,0,0,0,0,0,115,112,0,0,0,101,0,0,90,1, - 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 100,3,0,132,0,0,90,4,0,100,4,0,100,5,0,132, - 0,0,90,5,0,100,6,0,100,7,0,132,0,0,90,6, - 0,101,7,0,135,0,0,102,1,0,100,8,0,100,9,0, - 134,0,0,131,1,0,90,8,0,101,7,0,100,10,0,100, - 11,0,132,0,0,131,1,0,90,9,0,100,12,0,100,13, - 0,132,0,0,90,10,0,135,0,0,83,41,14,218,10,70, - 105,108,101,76,111,97,100,101,114,122,103,66,97,115,101,32, - 102,105,108,101,32,108,111,97,100,101,114,32,99,108,97,115, - 115,32,119,104,105,99,104,32,105,109,112,108,101,109,101,110, - 116,115,32,116,104,101,32,108,111,97,100,101,114,32,112,114, - 111,116,111,99,111,108,32,109,101,116,104,111,100,115,32,116, - 104,97,116,10,32,32,32,32,114,101,113,117,105,114,101,32, - 102,105,108,101,32,115,121,115,116,101,109,32,117,115,97,103, - 101,46,99,3,0,0,0,0,0,0,0,3,0,0,0,2, - 0,0,0,67,0,0,0,115,22,0,0,0,124,1,0,124, - 0,0,95,0,0,124,2,0,124,0,0,95,1,0,100,1, - 0,83,41,2,122,75,67,97,99,104,101,32,116,104,101,32, - 109,111,100,117,108,101,32,110,97,109,101,32,97,110,100,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32, - 102,105,108,101,32,102,111,117,110,100,32,98,121,32,116,104, - 101,10,32,32,32,32,32,32,32,32,102,105,110,100,101,114, - 46,78,41,2,114,108,0,0,0,114,37,0,0,0,41,3, - 114,110,0,0,0,114,128,0,0,0,114,37,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,186, - 0,0,0,26,3,0,0,115,4,0,0,0,0,3,9,1, - 122,19,70,105,108,101,76,111,97,100,101,114,46,95,95,105, - 110,105,116,95,95,99,2,0,0,0,0,0,0,0,2,0, - 0,0,2,0,0,0,67,0,0,0,115,34,0,0,0,124, - 0,0,106,0,0,124,1,0,106,0,0,107,2,0,111,33, - 0,124,0,0,106,1,0,124,1,0,106,1,0,107,2,0, - 83,41,1,78,41,2,218,9,95,95,99,108,97,115,115,95, - 95,114,120,0,0,0,41,2,114,110,0,0,0,218,5,111, - 116,104,101,114,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,218,6,95,95,101,113,95,95,32,3,0,0,115, - 4,0,0,0,0,1,18,1,122,17,70,105,108,101,76,111, - 97,100,101,114,46,95,95,101,113,95,95,99,1,0,0,0, - 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, - 115,26,0,0,0,116,0,0,124,0,0,106,1,0,131,1, - 0,116,0,0,124,0,0,106,2,0,131,1,0,65,83,41, - 1,78,41,3,218,4,104,97,115,104,114,108,0,0,0,114, - 37,0,0,0,41,1,114,110,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,8,95,95,104,97, - 115,104,95,95,36,3,0,0,115,2,0,0,0,0,1,122, - 19,70,105,108,101,76,111,97,100,101,114,46,95,95,104,97, - 115,104,95,95,99,2,0,0,0,0,0,0,0,2,0,0, - 0,3,0,0,0,3,0,0,0,115,22,0,0,0,116,0, - 0,116,1,0,124,0,0,131,2,0,106,2,0,124,1,0, - 131,1,0,83,41,1,122,100,76,111,97,100,32,97,32,109, - 111,100,117,108,101,32,102,114,111,109,32,97,32,102,105,108, - 101,46,10,10,32,32,32,32,32,32,32,32,84,104,105,115, - 32,109,101,116,104,111,100,32,105,115,32,100,101,112,114,101, - 99,97,116,101,100,46,32,32,85,115,101,32,101,120,101,99, - 95,109,111,100,117,108,101,40,41,32,105,110,115,116,101,97, - 100,46,10,10,32,32,32,32,32,32,32,32,41,3,218,5, - 115,117,112,101,114,114,211,0,0,0,114,194,0,0,0,41, - 2,114,110,0,0,0,114,128,0,0,0,41,1,114,212,0, - 0,0,114,4,0,0,0,114,6,0,0,0,114,194,0,0, - 0,39,3,0,0,115,2,0,0,0,0,10,122,22,70,105, - 108,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, - 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, - 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, - 0,106,0,0,83,41,1,122,58,82,101,116,117,114,110,32, - 116,104,101,32,112,97,116,104,32,116,111,32,116,104,101,32, - 115,111,117,114,99,101,32,102,105,108,101,32,97,115,32,102, - 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100, - 101,114,46,41,1,114,37,0,0,0,41,2,114,110,0,0, - 0,114,128,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,159,0,0,0,51,3,0,0,115,2, - 0,0,0,0,3,122,23,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,102,105,108,101,110,97,109,101,99,2, - 0,0,0,0,0,0,0,3,0,0,0,9,0,0,0,67, - 0,0,0,115,42,0,0,0,116,0,0,106,1,0,124,1, - 0,100,1,0,131,2,0,143,17,0,125,2,0,124,2,0, - 106,2,0,131,0,0,83,87,100,2,0,81,82,88,100,2, - 0,83,41,3,122,39,82,101,116,117,114,110,32,116,104,101, - 32,100,97,116,97,32,102,114,111,109,32,112,97,116,104,32, - 97,115,32,114,97,119,32,98,121,116,101,115,46,218,1,114, - 78,41,3,114,51,0,0,0,114,52,0,0,0,90,4,114, - 101,97,100,41,3,114,110,0,0,0,114,37,0,0,0,114, - 56,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,201,0,0,0,56,3,0,0,115,4,0,0, - 0,0,2,21,1,122,19,70,105,108,101,76,111,97,100,101, - 114,46,103,101,116,95,100,97,116,97,41,11,114,114,0,0, - 0,114,113,0,0,0,114,115,0,0,0,114,116,0,0,0, - 114,186,0,0,0,114,214,0,0,0,114,216,0,0,0,114, - 125,0,0,0,114,194,0,0,0,114,159,0,0,0,114,201, - 0,0,0,114,4,0,0,0,114,4,0,0,0,41,1,114, - 212,0,0,0,114,6,0,0,0,114,211,0,0,0,21,3, - 0,0,115,14,0,0,0,12,3,6,2,12,6,12,4,12, - 3,24,12,18,5,114,211,0,0,0,99,0,0,0,0,0, - 0,0,0,0,0,0,0,4,0,0,0,64,0,0,0,115, - 64,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, + 0,0,0,114,189,0,0,0,114,204,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,114,225,0,0,0,129,3,0,0,115,6,0,0,0,12, + 2,6,2,12,6,114,225,0,0,0,99,0,0,0,0,0, + 0,0,0,0,0,0,0,3,0,0,0,64,0,0,0,115, + 136,0,0,0,101,0,0,90,1,0,100,0,0,90,2,0, 100,1,0,90,3,0,100,2,0,100,3,0,132,0,0,90, 4,0,100,4,0,100,5,0,132,0,0,90,5,0,100,6, - 0,100,7,0,100,8,0,100,9,0,132,0,1,90,6,0, - 100,10,0,83,41,11,218,16,83,111,117,114,99,101,70,105, - 108,101,76,111,97,100,101,114,122,62,67,111,110,99,114,101, - 116,101,32,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,32,111,102,32,83,111,117,114,99,101,76,111,97,100,101, - 114,32,117,115,105,110,103,32,116,104,101,32,102,105,108,101, - 32,115,121,115,116,101,109,46,99,2,0,0,0,0,0,0, - 0,3,0,0,0,4,0,0,0,67,0,0,0,115,34,0, - 0,0,116,0,0,124,1,0,131,1,0,125,2,0,100,1, - 0,124,2,0,106,1,0,100,2,0,124,2,0,106,2,0, - 105,2,0,83,41,3,122,33,82,101,116,117,114,110,32,116, - 104,101,32,109,101,116,97,100,97,116,97,32,102,111,114,32, - 116,104,101,32,112,97,116,104,46,114,135,0,0,0,114,136, - 0,0,0,41,3,114,41,0,0,0,218,8,115,116,95,109, - 116,105,109,101,90,7,115,116,95,115,105,122,101,41,3,114, - 110,0,0,0,114,37,0,0,0,114,209,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,114,198,0, - 0,0,66,3,0,0,115,4,0,0,0,0,2,12,1,122, - 27,83,111,117,114,99,101,70,105,108,101,76,111,97,100,101, - 114,46,112,97,116,104,95,115,116,97,116,115,99,4,0,0, - 0,0,0,0,0,5,0,0,0,5,0,0,0,67,0,0, - 0,115,34,0,0,0,116,0,0,124,1,0,131,1,0,125, - 4,0,124,0,0,106,1,0,124,2,0,124,3,0,100,1, - 0,124,4,0,131,2,1,83,41,2,78,218,5,95,109,111, - 100,101,41,2,114,99,0,0,0,114,199,0,0,0,41,5, - 114,110,0,0,0,114,92,0,0,0,114,91,0,0,0,114, - 55,0,0,0,114,44,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,200,0,0,0,71,3,0, - 0,115,4,0,0,0,0,2,12,1,122,32,83,111,117,114, - 99,101,70,105,108,101,76,111,97,100,101,114,46,95,99,97, - 99,104,101,95,98,121,116,101,99,111,100,101,114,221,0,0, - 0,105,182,1,0,0,99,3,0,0,0,1,0,0,0,9, - 0,0,0,17,0,0,0,67,0,0,0,115,53,1,0,0, - 116,0,0,124,1,0,131,1,0,92,2,0,125,4,0,125, - 5,0,103,0,0,125,6,0,120,54,0,124,4,0,114,80, - 0,116,1,0,124,4,0,131,1,0,12,114,80,0,116,0, - 0,124,4,0,131,1,0,92,2,0,125,4,0,125,7,0, - 124,6,0,106,2,0,124,7,0,131,1,0,1,113,27,0, - 87,120,132,0,116,3,0,124,6,0,131,1,0,68,93,118, - 0,125,7,0,116,4,0,124,4,0,124,7,0,131,2,0, - 125,4,0,121,17,0,116,5,0,106,6,0,124,4,0,131, - 1,0,1,87,113,94,0,4,116,7,0,107,10,0,114,155, - 0,1,1,1,119,94,0,89,113,94,0,4,116,8,0,107, - 10,0,114,211,0,1,125,8,0,1,122,25,0,116,9,0, - 100,1,0,124,4,0,124,8,0,131,3,0,1,100,2,0, - 83,87,89,100,2,0,100,2,0,125,8,0,126,8,0,88, - 113,94,0,88,113,94,0,87,121,33,0,116,10,0,124,1, - 0,124,2,0,124,3,0,131,3,0,1,116,9,0,100,3, - 0,124,1,0,131,2,0,1,87,110,53,0,4,116,8,0, - 107,10,0,114,48,1,1,125,8,0,1,122,21,0,116,9, - 0,100,1,0,124,1,0,124,8,0,131,3,0,1,87,89, - 100,2,0,100,2,0,125,8,0,126,8,0,88,110,1,0, - 88,100,2,0,83,41,4,122,27,87,114,105,116,101,32,98, - 121,116,101,115,32,100,97,116,97,32,116,111,32,97,32,102, - 105,108,101,46,122,27,99,111,117,108,100,32,110,111,116,32, - 99,114,101,97,116,101,32,123,33,114,125,58,32,123,33,114, - 125,78,122,12,99,114,101,97,116,101,100,32,123,33,114,125, - 41,11,114,40,0,0,0,114,48,0,0,0,114,165,0,0, - 0,114,35,0,0,0,114,30,0,0,0,114,3,0,0,0, - 90,5,109,107,100,105,114,218,15,70,105,108,101,69,120,105, - 115,116,115,69,114,114,111,114,114,42,0,0,0,114,107,0, - 0,0,114,57,0,0,0,41,9,114,110,0,0,0,114,37, - 0,0,0,114,55,0,0,0,114,221,0,0,0,218,6,112, - 97,114,101,110,116,114,96,0,0,0,114,29,0,0,0,114, - 25,0,0,0,114,202,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,199,0,0,0,76,3,0, - 0,115,38,0,0,0,0,2,18,1,6,2,22,1,18,1, - 17,2,19,1,15,1,3,1,17,1,13,2,7,1,18,3, - 16,1,27,1,3,1,16,1,17,1,18,2,122,25,83,111, - 117,114,99,101,70,105,108,101,76,111,97,100,101,114,46,115, - 101,116,95,100,97,116,97,78,41,7,114,114,0,0,0,114, - 113,0,0,0,114,115,0,0,0,114,116,0,0,0,114,198, - 0,0,0,114,200,0,0,0,114,199,0,0,0,114,4,0, + 0,100,7,0,132,0,0,90,6,0,100,8,0,100,9,0, + 132,0,0,90,7,0,100,10,0,100,11,0,132,0,0,90, + 8,0,100,12,0,100,13,0,132,0,0,90,9,0,100,14, + 0,100,15,0,132,0,0,90,10,0,100,16,0,100,17,0, + 132,0,0,90,11,0,101,12,0,100,18,0,100,19,0,132, + 0,0,131,1,0,90,13,0,100,20,0,83,41,21,218,19, + 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, + 100,101,114,122,93,76,111,97,100,101,114,32,102,111,114,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 115,46,10,10,32,32,32,32,84,104,101,32,99,111,110,115, + 116,114,117,99,116,111,114,32,105,115,32,100,101,115,105,103, + 110,101,100,32,116,111,32,119,111,114,107,32,119,105,116,104, + 32,70,105,108,101,70,105,110,100,101,114,46,10,10,32,32, + 32,32,99,3,0,0,0,0,0,0,0,3,0,0,0,2, + 0,0,0,67,0,0,0,115,22,0,0,0,124,1,0,124, + 0,0,95,0,0,124,2,0,124,0,0,95,1,0,100,0, + 0,83,41,1,78,41,2,114,108,0,0,0,114,37,0,0, + 0,41,3,114,110,0,0,0,114,108,0,0,0,114,37,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,219,0,0,0,62,3,0,0,115,8,0,0,0,12, - 2,6,2,12,5,12,5,114,219,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,2,0,0,0,64,0,0, - 0,115,46,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,90,3,0,100,2,0,100,3,0,132,0, - 0,90,4,0,100,4,0,100,5,0,132,0,0,90,5,0, - 100,6,0,83,41,7,218,20,83,111,117,114,99,101,108,101, - 115,115,70,105,108,101,76,111,97,100,101,114,122,45,76,111, - 97,100,101,114,32,119,104,105,99,104,32,104,97,110,100,108, - 101,115,32,115,111,117,114,99,101,108,101,115,115,32,102,105, - 108,101,32,105,109,112,111,114,116,115,46,99,2,0,0,0, - 0,0,0,0,5,0,0,0,6,0,0,0,67,0,0,0, - 115,76,0,0,0,124,0,0,106,0,0,124,1,0,131,1, - 0,125,2,0,124,0,0,106,1,0,124,2,0,131,1,0, - 125,3,0,116,2,0,124,3,0,100,1,0,124,1,0,100, - 2,0,124,2,0,131,1,2,125,4,0,116,3,0,124,4, - 0,100,1,0,124,1,0,100,3,0,124,2,0,131,1,2, - 83,41,4,78,114,108,0,0,0,114,37,0,0,0,114,91, - 0,0,0,41,4,114,159,0,0,0,114,201,0,0,0,114, - 143,0,0,0,114,149,0,0,0,41,5,114,110,0,0,0, - 114,128,0,0,0,114,37,0,0,0,114,55,0,0,0,114, - 210,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,188,0,0,0,109,3,0,0,115,8,0,0, - 0,0,1,15,1,15,1,24,1,122,29,83,111,117,114,99, - 101,108,101,115,115,70,105,108,101,76,111,97,100,101,114,46, - 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, + 0,114,187,0,0,0,156,3,0,0,115,4,0,0,0,0, + 1,9,1,122,28,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,95,95,105,110,105,116,95, + 95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, + 0,0,67,0,0,0,115,34,0,0,0,124,0,0,106,0, + 0,124,1,0,106,0,0,107,2,0,111,33,0,124,0,0, + 106,1,0,124,1,0,106,1,0,107,2,0,83,41,1,78, + 41,2,114,213,0,0,0,114,120,0,0,0,41,2,114,110, + 0,0,0,114,214,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,6,0,0,0,114,215,0,0,0,160,3,0,0, + 115,4,0,0,0,0,1,18,1,122,26,69,120,116,101,110, + 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,95, + 95,101,113,95,95,99,1,0,0,0,0,0,0,0,1,0, + 0,0,3,0,0,0,67,0,0,0,115,26,0,0,0,116, + 0,0,124,0,0,106,1,0,131,1,0,116,0,0,124,0, + 0,106,2,0,131,1,0,65,83,41,1,78,41,3,114,216, + 0,0,0,114,108,0,0,0,114,37,0,0,0,41,1,114, + 110,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,114,217,0,0,0,164,3,0,0,115,2,0,0, + 0,0,1,122,28,69,120,116,101,110,115,105,111,110,70,105, + 108,101,76,111,97,100,101,114,46,95,95,104,97,115,104,95, + 95,99,2,0,0,0,0,0,0,0,3,0,0,0,4,0, + 0,0,67,0,0,0,115,47,0,0,0,116,0,0,106,1, + 0,116,2,0,106,3,0,124,1,0,131,2,0,125,2,0, + 116,4,0,100,1,0,124,1,0,106,5,0,124,0,0,106, + 6,0,131,3,0,1,124,2,0,83,41,2,122,38,67,114, + 101,97,116,101,32,97,110,32,117,110,105,116,105,97,108,105, + 122,101,100,32,101,120,116,101,110,115,105,111,110,32,109,111, + 100,117,108,101,122,38,101,120,116,101,110,115,105,111,110,32, + 109,111,100,117,108,101,32,123,33,114,125,32,108,111,97,100, + 101,100,32,102,114,111,109,32,123,33,114,125,41,7,114,123, + 0,0,0,114,190,0,0,0,114,148,0,0,0,90,14,99, + 114,101,97,116,101,95,100,121,110,97,109,105,99,114,107,0, + 0,0,114,108,0,0,0,114,37,0,0,0,41,3,114,110, + 0,0,0,114,167,0,0,0,114,192,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,114,188,0,0, + 0,167,3,0,0,115,10,0,0,0,0,2,6,1,15,1, + 6,1,16,1,122,33,69,120,116,101,110,115,105,111,110,70, + 105,108,101,76,111,97,100,101,114,46,99,114,101,97,116,101, + 95,109,111,100,117,108,101,99,2,0,0,0,0,0,0,0, + 2,0,0,0,4,0,0,0,67,0,0,0,115,45,0,0, + 0,116,0,0,106,1,0,116,2,0,106,3,0,124,1,0, + 131,2,0,1,116,4,0,100,1,0,124,0,0,106,5,0, + 124,0,0,106,6,0,131,3,0,1,100,2,0,83,41,3, + 122,30,73,110,105,116,105,97,108,105,122,101,32,97,110,32, + 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, + 122,40,101,120,116,101,110,115,105,111,110,32,109,111,100,117, + 108,101,32,123,33,114,125,32,101,120,101,99,117,116,101,100, + 32,102,114,111,109,32,123,33,114,125,78,41,7,114,123,0, + 0,0,114,190,0,0,0,114,148,0,0,0,90,12,101,120, + 101,99,95,100,121,110,97,109,105,99,114,107,0,0,0,114, + 108,0,0,0,114,37,0,0,0,41,2,114,110,0,0,0, + 114,192,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,114,193,0,0,0,175,3,0,0,115,6,0, + 0,0,0,2,19,1,6,1,122,31,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,101,120, + 101,99,95,109,111,100,117,108,101,99,2,0,0,0,0,0, + 0,0,2,0,0,0,4,0,0,0,3,0,0,0,115,48, + 0,0,0,116,0,0,124,0,0,106,1,0,131,1,0,100, + 1,0,25,137,0,0,116,2,0,135,0,0,102,1,0,100, + 2,0,100,3,0,134,0,0,116,3,0,68,131,1,0,131, + 1,0,83,41,4,122,49,82,101,116,117,114,110,32,84,114, + 117,101,32,105,102,32,116,104,101,32,101,120,116,101,110,115, + 105,111,110,32,109,111,100,117,108,101,32,105,115,32,97,32, + 112,97,99,107,97,103,101,46,114,31,0,0,0,99,1,0, + 0,0,0,0,0,0,2,0,0,0,4,0,0,0,51,0, + 0,0,115,31,0,0,0,124,0,0,93,21,0,125,1,0, + 136,0,0,100,0,0,124,1,0,23,107,2,0,86,1,113, + 3,0,100,1,0,83,41,2,114,187,0,0,0,78,114,4, + 0,0,0,41,2,114,24,0,0,0,218,6,115,117,102,102, + 105,120,41,1,218,9,102,105,108,101,95,110,97,109,101,114, + 4,0,0,0,114,6,0,0,0,250,9,60,103,101,110,101, + 120,112,114,62,184,3,0,0,115,2,0,0,0,6,1,122, + 49,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, + 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,41,4,114,40,0,0,0,114,37,0,0,0,218,3, + 97,110,121,218,18,69,88,84,69,78,83,73,79,78,95,83, + 85,70,70,73,88,69,83,41,2,114,110,0,0,0,114,128, + 0,0,0,114,4,0,0,0,41,1,114,228,0,0,0,114, + 6,0,0,0,114,162,0,0,0,181,3,0,0,115,6,0, + 0,0,0,2,19,1,18,1,122,30,69,120,116,101,110,115, + 105,111,110,70,105,108,101,76,111,97,100,101,114,46,105,115, + 95,112,97,99,107,97,103,101,99,2,0,0,0,0,0,0, 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, - 0,0,100,1,0,83,41,2,122,39,82,101,116,117,114,110, - 32,78,111,110,101,32,97,115,32,116,104,101,114,101,32,105, - 115,32,110,111,32,115,111,117,114,99,101,32,99,111,100,101, - 46,78,114,4,0,0,0,41,2,114,110,0,0,0,114,128, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,203,0,0,0,115,3,0,0,115,2,0,0,0, - 0,2,122,31,83,111,117,114,99,101,108,101,115,115,70,105, - 108,101,76,111,97,100,101,114,46,103,101,116,95,115,111,117, - 114,99,101,78,41,6,114,114,0,0,0,114,113,0,0,0, - 114,115,0,0,0,114,116,0,0,0,114,188,0,0,0,114, - 203,0,0,0,114,4,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,224,0,0,0,105,3,0, - 0,115,6,0,0,0,12,2,6,2,12,6,114,224,0,0, - 0,99,0,0,0,0,0,0,0,0,0,0,0,0,3,0, - 0,0,64,0,0,0,115,136,0,0,0,101,0,0,90,1, - 0,100,0,0,90,2,0,100,1,0,90,3,0,100,2,0, - 100,3,0,132,0,0,90,4,0,100,4,0,100,5,0,132, - 0,0,90,5,0,100,6,0,100,7,0,132,0,0,90,6, - 0,100,8,0,100,9,0,132,0,0,90,7,0,100,10,0, - 100,11,0,132,0,0,90,8,0,100,12,0,100,13,0,132, - 0,0,90,9,0,100,14,0,100,15,0,132,0,0,90,10, - 0,100,16,0,100,17,0,132,0,0,90,11,0,101,12,0, - 100,18,0,100,19,0,132,0,0,131,1,0,90,13,0,100, - 20,0,83,41,21,218,19,69,120,116,101,110,115,105,111,110, - 70,105,108,101,76,111,97,100,101,114,122,93,76,111,97,100, - 101,114,32,102,111,114,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,115,46,10,10,32,32,32,32,84, - 104,101,32,99,111,110,115,116,114,117,99,116,111,114,32,105, - 115,32,100,101,115,105,103,110,101,100,32,116,111,32,119,111, - 114,107,32,119,105,116,104,32,70,105,108,101,70,105,110,100, - 101,114,46,10,10,32,32,32,32,99,3,0,0,0,0,0, - 0,0,3,0,0,0,2,0,0,0,67,0,0,0,115,22, - 0,0,0,124,1,0,124,0,0,95,0,0,124,2,0,124, - 0,0,95,1,0,100,0,0,83,41,1,78,41,2,114,108, - 0,0,0,114,37,0,0,0,41,3,114,110,0,0,0,114, - 108,0,0,0,114,37,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,186,0,0,0,132,3,0, - 0,115,4,0,0,0,0,1,9,1,122,28,69,120,116,101, - 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 95,95,105,110,105,116,95,95,99,2,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,34,0, - 0,0,124,0,0,106,0,0,124,1,0,106,0,0,107,2, - 0,111,33,0,124,0,0,106,1,0,124,1,0,106,1,0, - 107,2,0,83,41,1,78,41,2,114,212,0,0,0,114,120, - 0,0,0,41,2,114,110,0,0,0,114,213,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,214, - 0,0,0,136,3,0,0,115,4,0,0,0,0,1,18,1, - 122,26,69,120,116,101,110,115,105,111,110,70,105,108,101,76, - 111,97,100,101,114,46,95,95,101,113,95,95,99,1,0,0, - 0,0,0,0,0,1,0,0,0,3,0,0,0,67,0,0, - 0,115,26,0,0,0,116,0,0,124,0,0,106,1,0,131, - 1,0,116,0,0,124,0,0,106,2,0,131,1,0,65,83, - 41,1,78,41,3,114,215,0,0,0,114,108,0,0,0,114, - 37,0,0,0,41,1,114,110,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,114,216,0,0,0,140, - 3,0,0,115,2,0,0,0,0,1,122,28,69,120,116,101, + 0,0,100,1,0,83,41,2,122,63,82,101,116,117,114,110, + 32,78,111,110,101,32,97,115,32,97,110,32,101,120,116,101, + 110,115,105,111,110,32,109,111,100,117,108,101,32,99,97,110, + 110,111,116,32,99,114,101,97,116,101,32,97,32,99,111,100, + 101,32,111,98,106,101,99,116,46,78,114,4,0,0,0,41, + 2,114,110,0,0,0,114,128,0,0,0,114,4,0,0,0, + 114,4,0,0,0,114,6,0,0,0,114,189,0,0,0,187, + 3,0,0,115,2,0,0,0,0,2,122,28,69,120,116,101, 110,115,105,111,110,70,105,108,101,76,111,97,100,101,114,46, - 95,95,104,97,115,104,95,95,99,2,0,0,0,0,0,0, - 0,3,0,0,0,4,0,0,0,67,0,0,0,115,47,0, - 0,0,116,0,0,106,1,0,116,2,0,106,3,0,124,1, - 0,131,2,0,125,2,0,116,4,0,100,1,0,124,1,0, - 106,5,0,124,0,0,106,6,0,131,3,0,1,124,2,0, - 83,41,2,122,38,67,114,101,97,116,101,32,97,110,32,117, - 110,105,116,105,97,108,105,122,101,100,32,101,120,116,101,110, - 115,105,111,110,32,109,111,100,117,108,101,122,38,101,120,116, - 101,110,115,105,111,110,32,109,111,100,117,108,101,32,123,33, - 114,125,32,108,111,97,100,101,100,32,102,114,111,109,32,123, - 33,114,125,41,7,114,123,0,0,0,114,189,0,0,0,114, - 147,0,0,0,90,14,99,114,101,97,116,101,95,100,121,110, - 97,109,105,99,114,107,0,0,0,114,108,0,0,0,114,37, - 0,0,0,41,3,114,110,0,0,0,114,166,0,0,0,114, - 191,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,187,0,0,0,143,3,0,0,115,10,0,0, - 0,0,2,6,1,15,1,6,1,16,1,122,33,69,120,116, - 101,110,115,105,111,110,70,105,108,101,76,111,97,100,101,114, - 46,99,114,101,97,116,101,95,109,111,100,117,108,101,99,2, - 0,0,0,0,0,0,0,2,0,0,0,4,0,0,0,67, - 0,0,0,115,45,0,0,0,116,0,0,106,1,0,116,2, - 0,106,3,0,124,1,0,131,2,0,1,116,4,0,100,1, - 0,124,0,0,106,5,0,124,0,0,106,6,0,131,3,0, - 1,100,2,0,83,41,3,122,30,73,110,105,116,105,97,108, - 105,122,101,32,97,110,32,101,120,116,101,110,115,105,111,110, - 32,109,111,100,117,108,101,122,40,101,120,116,101,110,115,105, - 111,110,32,109,111,100,117,108,101,32,123,33,114,125,32,101, - 120,101,99,117,116,101,100,32,102,114,111,109,32,123,33,114, - 125,78,41,7,114,123,0,0,0,114,189,0,0,0,114,147, - 0,0,0,90,12,101,120,101,99,95,100,121,110,97,109,105, - 99,114,107,0,0,0,114,108,0,0,0,114,37,0,0,0, - 41,2,114,110,0,0,0,114,191,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,114,192,0,0,0, - 151,3,0,0,115,6,0,0,0,0,2,19,1,6,1,122, - 31,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,101,120,101,99,95,109,111,100,117,108,101, - 99,2,0,0,0,0,0,0,0,2,0,0,0,4,0,0, - 0,3,0,0,0,115,48,0,0,0,116,0,0,124,0,0, - 106,1,0,131,1,0,100,1,0,25,137,0,0,116,2,0, - 135,0,0,102,1,0,100,2,0,100,3,0,134,0,0,116, - 3,0,68,131,1,0,131,1,0,83,41,4,122,49,82,101, - 116,117,114,110,32,84,114,117,101,32,105,102,32,116,104,101, - 32,101,120,116,101,110,115,105,111,110,32,109,111,100,117,108, - 101,32,105,115,32,97,32,112,97,99,107,97,103,101,46,114, - 31,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, - 0,4,0,0,0,51,0,0,0,115,31,0,0,0,124,0, - 0,93,21,0,125,1,0,136,0,0,100,0,0,124,1,0, - 23,107,2,0,86,1,113,3,0,100,1,0,83,41,2,114, - 186,0,0,0,78,114,4,0,0,0,41,2,114,24,0,0, - 0,218,6,115,117,102,102,105,120,41,1,218,9,102,105,108, - 101,95,110,97,109,101,114,4,0,0,0,114,6,0,0,0, - 250,9,60,103,101,110,101,120,112,114,62,160,3,0,0,115, - 2,0,0,0,6,1,122,49,69,120,116,101,110,115,105,111, - 110,70,105,108,101,76,111,97,100,101,114,46,105,115,95,112, - 97,99,107,97,103,101,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,41,4,114,40,0,0,0, - 114,37,0,0,0,218,3,97,110,121,218,18,69,88,84,69, - 78,83,73,79,78,95,83,85,70,70,73,88,69,83,41,2, - 114,110,0,0,0,114,128,0,0,0,114,4,0,0,0,41, - 1,114,227,0,0,0,114,6,0,0,0,114,161,0,0,0, - 157,3,0,0,115,6,0,0,0,0,2,19,1,18,1,122, - 30,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, - 97,100,101,114,46,105,115,95,112,97,99,107,97,103,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,122, - 63,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 97,110,32,101,120,116,101,110,115,105,111,110,32,109,111,100, - 117,108,101,32,99,97,110,110,111,116,32,99,114,101,97,116, - 101,32,97,32,99,111,100,101,32,111,98,106,101,99,116,46, - 78,114,4,0,0,0,41,2,114,110,0,0,0,114,128,0, + 103,101,116,95,99,111,100,101,99,2,0,0,0,0,0,0, + 0,2,0,0,0,1,0,0,0,67,0,0,0,115,4,0, + 0,0,100,1,0,83,41,2,122,53,82,101,116,117,114,110, + 32,78,111,110,101,32,97,115,32,101,120,116,101,110,115,105, + 111,110,32,109,111,100,117,108,101,115,32,104,97,118,101,32, + 110,111,32,115,111,117,114,99,101,32,99,111,100,101,46,78, + 114,4,0,0,0,41,2,114,110,0,0,0,114,128,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, + 114,204,0,0,0,191,3,0,0,115,2,0,0,0,0,2, + 122,30,69,120,116,101,110,115,105,111,110,70,105,108,101,76, + 111,97,100,101,114,46,103,101,116,95,115,111,117,114,99,101, + 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,7,0,0,0,124,0,0,106,0,0, + 83,41,1,122,58,82,101,116,117,114,110,32,116,104,101,32, + 112,97,116,104,32,116,111,32,116,104,101,32,115,111,117,114, + 99,101,32,102,105,108,101,32,97,115,32,102,111,117,110,100, + 32,98,121,32,116,104,101,32,102,105,110,100,101,114,46,41, + 1,114,37,0,0,0,41,2,114,110,0,0,0,114,128,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,188,0,0,0,163,3,0,0,115,2,0,0,0,0, - 2,122,28,69,120,116,101,110,115,105,111,110,70,105,108,101, - 76,111,97,100,101,114,46,103,101,116,95,99,111,100,101,99, - 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, - 67,0,0,0,115,4,0,0,0,100,1,0,83,41,2,122, - 53,82,101,116,117,114,110,32,78,111,110,101,32,97,115,32, - 101,120,116,101,110,115,105,111,110,32,109,111,100,117,108,101, - 115,32,104,97,118,101,32,110,111,32,115,111,117,114,99,101, - 32,99,111,100,101,46,78,114,4,0,0,0,41,2,114,110, - 0,0,0,114,128,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,114,203,0,0,0,167,3,0,0, - 115,2,0,0,0,0,2,122,30,69,120,116,101,110,115,105, - 111,110,70,105,108,101,76,111,97,100,101,114,46,103,101,116, - 95,115,111,117,114,99,101,99,2,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,7,0,0, - 0,124,0,0,106,0,0,83,41,1,122,58,82,101,116,117, - 114,110,32,116,104,101,32,112,97,116,104,32,116,111,32,116, - 104,101,32,115,111,117,114,99,101,32,102,105,108,101,32,97, - 115,32,102,111,117,110,100,32,98,121,32,116,104,101,32,102, - 105,110,100,101,114,46,41,1,114,37,0,0,0,41,2,114, - 110,0,0,0,114,128,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,114,159,0,0,0,171,3,0, - 0,115,2,0,0,0,0,3,122,32,69,120,116,101,110,115, - 105,111,110,70,105,108,101,76,111,97,100,101,114,46,103,101, - 116,95,102,105,108,101,110,97,109,101,78,41,14,114,114,0, - 0,0,114,113,0,0,0,114,115,0,0,0,114,116,0,0, - 0,114,186,0,0,0,114,214,0,0,0,114,216,0,0,0, - 114,187,0,0,0,114,192,0,0,0,114,161,0,0,0,114, - 188,0,0,0,114,203,0,0,0,114,125,0,0,0,114,159, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,114,225,0,0,0,124,3,0,0, - 115,20,0,0,0,12,6,6,2,12,4,12,4,12,3,12, - 8,12,6,12,6,12,4,12,4,114,225,0,0,0,99,0, - 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, - 0,0,0,115,130,0,0,0,101,0,0,90,1,0,100,0, - 0,90,2,0,100,1,0,90,3,0,100,2,0,100,3,0, - 132,0,0,90,4,0,100,4,0,100,5,0,132,0,0,90, - 5,0,100,6,0,100,7,0,132,0,0,90,6,0,100,8, - 0,100,9,0,132,0,0,90,7,0,100,10,0,100,11,0, - 132,0,0,90,8,0,100,12,0,100,13,0,132,0,0,90, - 9,0,100,14,0,100,15,0,132,0,0,90,10,0,100,16, - 0,100,17,0,132,0,0,90,11,0,100,18,0,100,19,0, - 132,0,0,90,12,0,100,20,0,83,41,21,218,14,95,78, - 97,109,101,115,112,97,99,101,80,97,116,104,97,38,1,0, - 0,82,101,112,114,101,115,101,110,116,115,32,97,32,110,97, - 109,101,115,112,97,99,101,32,112,97,99,107,97,103,101,39, - 115,32,112,97,116,104,46,32,32,73,116,32,117,115,101,115, - 32,116,104,101,32,109,111,100,117,108,101,32,110,97,109,101, - 10,32,32,32,32,116,111,32,102,105,110,100,32,105,116,115, - 32,112,97,114,101,110,116,32,109,111,100,117,108,101,44,32, - 97,110,100,32,102,114,111,109,32,116,104,101,114,101,32,105, - 116,32,108,111,111,107,115,32,117,112,32,116,104,101,32,112, - 97,114,101,110,116,39,115,10,32,32,32,32,95,95,112,97, - 116,104,95,95,46,32,32,87,104,101,110,32,116,104,105,115, - 32,99,104,97,110,103,101,115,44,32,116,104,101,32,109,111, - 100,117,108,101,39,115,32,111,119,110,32,112,97,116,104,32, - 105,115,32,114,101,99,111,109,112,117,116,101,100,44,10,32, - 32,32,32,117,115,105,110,103,32,112,97,116,104,95,102,105, - 110,100,101,114,46,32,32,70,111,114,32,116,111,112,45,108, - 101,118,101,108,32,109,111,100,117,108,101,115,44,32,116,104, - 101,32,112,97,114,101,110,116,32,109,111,100,117,108,101,39, - 115,32,112,97,116,104,10,32,32,32,32,105,115,32,115,121, - 115,46,112,97,116,104,46,99,4,0,0,0,0,0,0,0, - 4,0,0,0,2,0,0,0,67,0,0,0,115,52,0,0, - 0,124,1,0,124,0,0,95,0,0,124,2,0,124,0,0, - 95,1,0,116,2,0,124,0,0,106,3,0,131,0,0,131, - 1,0,124,0,0,95,4,0,124,3,0,124,0,0,95,5, - 0,100,0,0,83,41,1,78,41,6,218,5,95,110,97,109, - 101,218,5,95,112,97,116,104,114,95,0,0,0,218,16,95, - 103,101,116,95,112,97,114,101,110,116,95,112,97,116,104,218, - 17,95,108,97,115,116,95,112,97,114,101,110,116,95,112,97, - 116,104,218,12,95,112,97,116,104,95,102,105,110,100,101,114, - 41,4,114,110,0,0,0,114,108,0,0,0,114,37,0,0, - 0,218,11,112,97,116,104,95,102,105,110,100,101,114,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,114,186,0, - 0,0,184,3,0,0,115,8,0,0,0,0,1,9,1,9, - 1,21,1,122,23,95,78,97,109,101,115,112,97,99,101,80, - 97,116,104,46,95,95,105,110,105,116,95,95,99,1,0,0, - 0,0,0,0,0,4,0,0,0,3,0,0,0,67,0,0, - 0,115,53,0,0,0,124,0,0,106,0,0,106,1,0,100, - 1,0,131,1,0,92,3,0,125,1,0,125,2,0,125,3, - 0,124,2,0,100,2,0,107,2,0,114,43,0,100,6,0, - 83,124,1,0,100,5,0,102,2,0,83,41,7,122,62,82, - 101,116,117,114,110,115,32,97,32,116,117,112,108,101,32,111, - 102,32,40,112,97,114,101,110,116,45,109,111,100,117,108,101, - 45,110,97,109,101,44,32,112,97,114,101,110,116,45,112,97, - 116,104,45,97,116,116,114,45,110,97,109,101,41,114,60,0, - 0,0,114,32,0,0,0,114,8,0,0,0,114,37,0,0, - 0,90,8,95,95,112,97,116,104,95,95,41,2,114,8,0, - 0,0,114,37,0,0,0,41,2,114,232,0,0,0,114,34, - 0,0,0,41,4,114,110,0,0,0,114,223,0,0,0,218, - 3,100,111,116,90,2,109,101,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,218,23,95,102,105,110,100,95,112, - 97,114,101,110,116,95,112,97,116,104,95,110,97,109,101,115, - 190,3,0,0,115,8,0,0,0,0,2,27,1,12,2,4, - 3,122,38,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,102,105,110,100,95,112,97,114,101,110,116,95,112, - 97,116,104,95,110,97,109,101,115,99,1,0,0,0,0,0, - 0,0,3,0,0,0,3,0,0,0,67,0,0,0,115,38, - 0,0,0,124,0,0,106,0,0,131,0,0,92,2,0,125, - 1,0,125,2,0,116,1,0,116,2,0,106,3,0,124,1, - 0,25,124,2,0,131,2,0,83,41,1,78,41,4,114,239, - 0,0,0,114,119,0,0,0,114,8,0,0,0,218,7,109, - 111,100,117,108,101,115,41,3,114,110,0,0,0,90,18,112, - 97,114,101,110,116,95,109,111,100,117,108,101,95,110,97,109, - 101,90,14,112,97,116,104,95,97,116,116,114,95,110,97,109, + 0,114,160,0,0,0,195,3,0,0,115,2,0,0,0,0, + 3,122,32,69,120,116,101,110,115,105,111,110,70,105,108,101, + 76,111,97,100,101,114,46,103,101,116,95,102,105,108,101,110, + 97,109,101,78,41,14,114,114,0,0,0,114,113,0,0,0, + 114,115,0,0,0,114,116,0,0,0,114,187,0,0,0,114, + 215,0,0,0,114,217,0,0,0,114,188,0,0,0,114,193, + 0,0,0,114,162,0,0,0,114,189,0,0,0,114,204,0, + 0,0,114,125,0,0,0,114,160,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, + 114,226,0,0,0,148,3,0,0,115,20,0,0,0,12,6, + 6,2,12,4,12,4,12,3,12,8,12,6,12,6,12,4, + 12,4,114,226,0,0,0,99,0,0,0,0,0,0,0,0, + 0,0,0,0,2,0,0,0,64,0,0,0,115,130,0,0, + 0,101,0,0,90,1,0,100,0,0,90,2,0,100,1,0, + 90,3,0,100,2,0,100,3,0,132,0,0,90,4,0,100, + 4,0,100,5,0,132,0,0,90,5,0,100,6,0,100,7, + 0,132,0,0,90,6,0,100,8,0,100,9,0,132,0,0, + 90,7,0,100,10,0,100,11,0,132,0,0,90,8,0,100, + 12,0,100,13,0,132,0,0,90,9,0,100,14,0,100,15, + 0,132,0,0,90,10,0,100,16,0,100,17,0,132,0,0, + 90,11,0,100,18,0,100,19,0,132,0,0,90,12,0,100, + 20,0,83,41,21,218,14,95,78,97,109,101,115,112,97,99, + 101,80,97,116,104,97,38,1,0,0,82,101,112,114,101,115, + 101,110,116,115,32,97,32,110,97,109,101,115,112,97,99,101, + 32,112,97,99,107,97,103,101,39,115,32,112,97,116,104,46, + 32,32,73,116,32,117,115,101,115,32,116,104,101,32,109,111, + 100,117,108,101,32,110,97,109,101,10,32,32,32,32,116,111, + 32,102,105,110,100,32,105,116,115,32,112,97,114,101,110,116, + 32,109,111,100,117,108,101,44,32,97,110,100,32,102,114,111, + 109,32,116,104,101,114,101,32,105,116,32,108,111,111,107,115, + 32,117,112,32,116,104,101,32,112,97,114,101,110,116,39,115, + 10,32,32,32,32,95,95,112,97,116,104,95,95,46,32,32, + 87,104,101,110,32,116,104,105,115,32,99,104,97,110,103,101, + 115,44,32,116,104,101,32,109,111,100,117,108,101,39,115,32, + 111,119,110,32,112,97,116,104,32,105,115,32,114,101,99,111, + 109,112,117,116,101,100,44,10,32,32,32,32,117,115,105,110, + 103,32,112,97,116,104,95,102,105,110,100,101,114,46,32,32, + 70,111,114,32,116,111,112,45,108,101,118,101,108,32,109,111, + 100,117,108,101,115,44,32,116,104,101,32,112,97,114,101,110, + 116,32,109,111,100,117,108,101,39,115,32,112,97,116,104,10, + 32,32,32,32,105,115,32,115,121,115,46,112,97,116,104,46, + 99,4,0,0,0,0,0,0,0,4,0,0,0,2,0,0, + 0,67,0,0,0,115,52,0,0,0,124,1,0,124,0,0, + 95,0,0,124,2,0,124,0,0,95,1,0,116,2,0,124, + 0,0,106,3,0,131,0,0,131,1,0,124,0,0,95,4, + 0,124,3,0,124,0,0,95,5,0,100,0,0,83,41,1, + 78,41,6,218,5,95,110,97,109,101,218,5,95,112,97,116, + 104,114,95,0,0,0,218,16,95,103,101,116,95,112,97,114, + 101,110,116,95,112,97,116,104,218,17,95,108,97,115,116,95, + 112,97,114,101,110,116,95,112,97,116,104,218,12,95,112,97, + 116,104,95,102,105,110,100,101,114,41,4,114,110,0,0,0, + 114,108,0,0,0,114,37,0,0,0,218,11,112,97,116,104, + 95,102,105,110,100,101,114,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,114,187,0,0,0,208,3,0,0,115, + 8,0,0,0,0,1,9,1,9,1,21,1,122,23,95,78, + 97,109,101,115,112,97,99,101,80,97,116,104,46,95,95,105, + 110,105,116,95,95,99,1,0,0,0,0,0,0,0,4,0, + 0,0,3,0,0,0,67,0,0,0,115,53,0,0,0,124, + 0,0,106,0,0,106,1,0,100,1,0,131,1,0,92,3, + 0,125,1,0,125,2,0,125,3,0,124,2,0,100,2,0, + 107,2,0,114,43,0,100,6,0,83,124,1,0,100,5,0, + 102,2,0,83,41,7,122,62,82,101,116,117,114,110,115,32, + 97,32,116,117,112,108,101,32,111,102,32,40,112,97,114,101, + 110,116,45,109,111,100,117,108,101,45,110,97,109,101,44,32, + 112,97,114,101,110,116,45,112,97,116,104,45,97,116,116,114, + 45,110,97,109,101,41,114,60,0,0,0,114,32,0,0,0, + 114,8,0,0,0,114,37,0,0,0,90,8,95,95,112,97, + 116,104,95,95,41,2,114,8,0,0,0,114,37,0,0,0, + 41,2,114,233,0,0,0,114,34,0,0,0,41,4,114,110, + 0,0,0,114,224,0,0,0,218,3,100,111,116,90,2,109, 101,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,234,0,0,0,200,3,0,0,115,4,0,0,0,0,1, - 18,1,122,31,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,46,95,103,101,116,95,112,97,114,101,110,116,95,112, - 97,116,104,99,1,0,0,0,0,0,0,0,3,0,0,0, - 3,0,0,0,67,0,0,0,115,118,0,0,0,116,0,0, - 124,0,0,106,1,0,131,0,0,131,1,0,125,1,0,124, - 1,0,124,0,0,106,2,0,107,3,0,114,111,0,124,0, - 0,106,3,0,124,0,0,106,4,0,124,1,0,131,2,0, - 125,2,0,124,2,0,100,0,0,107,9,0,114,102,0,124, - 2,0,106,5,0,100,0,0,107,8,0,114,102,0,124,2, - 0,106,6,0,114,102,0,124,2,0,106,6,0,124,0,0, - 95,7,0,124,1,0,124,0,0,95,2,0,124,0,0,106, - 7,0,83,41,1,78,41,8,114,95,0,0,0,114,234,0, - 0,0,114,235,0,0,0,114,236,0,0,0,114,232,0,0, - 0,114,129,0,0,0,114,158,0,0,0,114,233,0,0,0, - 41,3,114,110,0,0,0,90,11,112,97,114,101,110,116,95, - 112,97,116,104,114,166,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,12,95,114,101,99,97,108, - 99,117,108,97,116,101,204,3,0,0,115,16,0,0,0,0, - 2,18,1,15,1,21,3,27,1,9,1,12,1,9,1,122, - 27,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,114,101,99,97,108,99,117,108,97,116,101,99,1,0,0, - 0,0,0,0,0,1,0,0,0,2,0,0,0,67,0,0, - 0,115,16,0,0,0,116,0,0,124,0,0,106,1,0,131, - 0,0,131,1,0,83,41,1,78,41,2,218,4,105,116,101, - 114,114,241,0,0,0,41,1,114,110,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,6,0,0,0,218,8,95,95, - 105,116,101,114,95,95,217,3,0,0,115,2,0,0,0,0, - 1,122,23,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,105,116,101,114,95,95,99,1,0,0,0,0, - 0,0,0,1,0,0,0,2,0,0,0,67,0,0,0,115, - 16,0,0,0,116,0,0,124,0,0,106,1,0,131,0,0, - 131,1,0,83,41,1,78,41,2,114,33,0,0,0,114,241, - 0,0,0,41,1,114,110,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,218,7,95,95,108,101,110, - 95,95,220,3,0,0,115,2,0,0,0,0,1,122,22,95, - 78,97,109,101,115,112,97,99,101,80,97,116,104,46,95,95, - 108,101,110,95,95,99,1,0,0,0,0,0,0,0,1,0, - 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,100, - 1,0,106,0,0,124,0,0,106,1,0,131,1,0,83,41, - 2,78,122,20,95,78,97,109,101,115,112,97,99,101,80,97, - 116,104,40,123,33,114,125,41,41,2,114,49,0,0,0,114, - 233,0,0,0,41,1,114,110,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,8,95,95,114,101, - 112,114,95,95,223,3,0,0,115,2,0,0,0,0,1,122, - 23,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, - 95,95,114,101,112,114,95,95,99,2,0,0,0,0,0,0, - 0,2,0,0,0,2,0,0,0,67,0,0,0,115,16,0, - 0,0,124,1,0,124,0,0,106,0,0,131,0,0,107,6, - 0,83,41,1,78,41,1,114,241,0,0,0,41,2,114,110, - 0,0,0,218,4,105,116,101,109,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,12,95,95,99,111,110,116, - 97,105,110,115,95,95,226,3,0,0,115,2,0,0,0,0, - 1,122,27,95,78,97,109,101,115,112,97,99,101,80,97,116, - 104,46,95,95,99,111,110,116,97,105,110,115,95,95,99,2, - 0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,67, - 0,0,0,115,20,0,0,0,124,0,0,106,0,0,106,1, - 0,124,1,0,131,1,0,1,100,0,0,83,41,1,78,41, - 2,114,233,0,0,0,114,165,0,0,0,41,2,114,110,0, - 0,0,114,246,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,6,0,0,0,114,165,0,0,0,229,3,0,0,115, - 2,0,0,0,0,1,122,21,95,78,97,109,101,115,112,97, - 99,101,80,97,116,104,46,97,112,112,101,110,100,78,41,13, - 114,114,0,0,0,114,113,0,0,0,114,115,0,0,0,114, - 116,0,0,0,114,186,0,0,0,114,239,0,0,0,114,234, - 0,0,0,114,241,0,0,0,114,243,0,0,0,114,244,0, - 0,0,114,245,0,0,0,114,247,0,0,0,114,165,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,231,0,0,0,177,3,0,0,115,20, - 0,0,0,12,5,6,2,12,6,12,10,12,4,12,13,12, - 3,12,3,12,3,12,3,114,231,0,0,0,99,0,0,0, - 0,0,0,0,0,0,0,0,0,3,0,0,0,64,0,0, - 0,115,118,0,0,0,101,0,0,90,1,0,100,0,0,90, - 2,0,100,1,0,100,2,0,132,0,0,90,3,0,101,4, - 0,100,3,0,100,4,0,132,0,0,131,1,0,90,5,0, - 100,5,0,100,6,0,132,0,0,90,6,0,100,7,0,100, - 8,0,132,0,0,90,7,0,100,9,0,100,10,0,132,0, - 0,90,8,0,100,11,0,100,12,0,132,0,0,90,9,0, - 100,13,0,100,14,0,132,0,0,90,10,0,100,15,0,100, - 16,0,132,0,0,90,11,0,100,17,0,83,41,18,218,16, - 95,78,97,109,101,115,112,97,99,101,76,111,97,100,101,114, - 99,4,0,0,0,0,0,0,0,4,0,0,0,4,0,0, - 0,67,0,0,0,115,25,0,0,0,116,0,0,124,1,0, - 124,2,0,124,3,0,131,3,0,124,0,0,95,1,0,100, - 0,0,83,41,1,78,41,2,114,231,0,0,0,114,233,0, - 0,0,41,4,114,110,0,0,0,114,108,0,0,0,114,37, - 0,0,0,114,237,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,6,0,0,0,114,186,0,0,0,235,3,0,0, - 115,2,0,0,0,0,1,122,25,95,78,97,109,101,115,112, - 97,99,101,76,111,97,100,101,114,46,95,95,105,110,105,116, - 95,95,99,2,0,0,0,0,0,0,0,2,0,0,0,2, - 0,0,0,67,0,0,0,115,16,0,0,0,100,1,0,106, - 0,0,124,1,0,106,1,0,131,1,0,83,41,2,122,115, - 82,101,116,117,114,110,32,114,101,112,114,32,102,111,114,32, - 116,104,101,32,109,111,100,117,108,101,46,10,10,32,32,32, - 32,32,32,32,32,84,104,101,32,109,101,116,104,111,100,32, - 105,115,32,100,101,112,114,101,99,97,116,101,100,46,32,32, - 84,104,101,32,105,109,112,111,114,116,32,109,97,99,104,105, - 110,101,114,121,32,100,111,101,115,32,116,104,101,32,106,111, - 98,32,105,116,115,101,108,102,46,10,10,32,32,32,32,32, - 32,32,32,122,25,60,109,111,100,117,108,101,32,123,33,114, - 125,32,40,110,97,109,101,115,112,97,99,101,41,62,41,2, - 114,49,0,0,0,114,114,0,0,0,41,2,114,172,0,0, - 0,114,191,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,218,11,109,111,100,117,108,101,95,114,101, - 112,114,238,3,0,0,115,2,0,0,0,0,7,122,28,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 109,111,100,117,108,101,95,114,101,112,114,99,2,0,0,0, - 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, - 115,4,0,0,0,100,1,0,83,41,2,78,84,114,4,0, - 0,0,41,2,114,110,0,0,0,114,128,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,114,161,0, - 0,0,247,3,0,0,115,2,0,0,0,0,1,122,27,95, - 78,97,109,101,115,112,97,99,101,76,111,97,100,101,114,46, - 105,115,95,112,97,99,107,97,103,101,99,2,0,0,0,0, - 0,0,0,2,0,0,0,1,0,0,0,67,0,0,0,115, - 4,0,0,0,100,1,0,83,41,2,78,114,32,0,0,0, - 114,4,0,0,0,41,2,114,110,0,0,0,114,128,0,0, + 218,23,95,102,105,110,100,95,112,97,114,101,110,116,95,112, + 97,116,104,95,110,97,109,101,115,214,3,0,0,115,8,0, + 0,0,0,2,27,1,12,2,4,3,122,38,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,102,105,110,100, + 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, + 101,115,99,1,0,0,0,0,0,0,0,3,0,0,0,3, + 0,0,0,67,0,0,0,115,38,0,0,0,124,0,0,106, + 0,0,131,0,0,92,2,0,125,1,0,125,2,0,116,1, + 0,116,2,0,106,3,0,124,1,0,25,124,2,0,131,2, + 0,83,41,1,78,41,4,114,240,0,0,0,114,119,0,0, + 0,114,8,0,0,0,218,7,109,111,100,117,108,101,115,41, + 3,114,110,0,0,0,90,18,112,97,114,101,110,116,95,109, + 111,100,117,108,101,95,110,97,109,101,90,14,112,97,116,104, + 95,97,116,116,114,95,110,97,109,101,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,114,235,0,0,0,224,3, + 0,0,115,4,0,0,0,0,1,18,1,122,31,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,46,95,103,101,116, + 95,112,97,114,101,110,116,95,112,97,116,104,99,1,0,0, + 0,0,0,0,0,3,0,0,0,3,0,0,0,67,0,0, + 0,115,118,0,0,0,116,0,0,124,0,0,106,1,0,131, + 0,0,131,1,0,125,1,0,124,1,0,124,0,0,106,2, + 0,107,3,0,114,111,0,124,0,0,106,3,0,124,0,0, + 106,4,0,124,1,0,131,2,0,125,2,0,124,2,0,100, + 0,0,107,9,0,114,102,0,124,2,0,106,5,0,100,0, + 0,107,8,0,114,102,0,124,2,0,106,6,0,114,102,0, + 124,2,0,106,6,0,124,0,0,95,7,0,124,1,0,124, + 0,0,95,2,0,124,0,0,106,7,0,83,41,1,78,41, + 8,114,95,0,0,0,114,235,0,0,0,114,236,0,0,0, + 114,237,0,0,0,114,233,0,0,0,114,129,0,0,0,114, + 159,0,0,0,114,234,0,0,0,41,3,114,110,0,0,0, + 90,11,112,97,114,101,110,116,95,112,97,116,104,114,167,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,12,95,114,101,99,97,108,99,117,108,97,116,101,228, + 3,0,0,115,16,0,0,0,0,2,18,1,15,1,21,3, + 27,1,9,1,12,1,9,1,122,27,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,114,101,99,97,108,99, + 117,108,97,116,101,99,1,0,0,0,0,0,0,0,1,0, + 0,0,2,0,0,0,67,0,0,0,115,16,0,0,0,116, + 0,0,124,0,0,106,1,0,131,0,0,131,1,0,83,41, + 1,78,41,2,218,4,105,116,101,114,114,242,0,0,0,41, + 1,114,110,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,6,0,0,0,218,8,95,95,105,116,101,114,95,95,241, + 3,0,0,115,2,0,0,0,0,1,122,23,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,105,116,101, + 114,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, + 2,0,0,0,67,0,0,0,115,16,0,0,0,116,0,0, + 124,0,0,106,1,0,131,0,0,131,1,0,83,41,1,78, + 41,2,114,33,0,0,0,114,242,0,0,0,41,1,114,110, + 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, + 0,0,218,7,95,95,108,101,110,95,95,244,3,0,0,115, + 2,0,0,0,0,1,122,22,95,78,97,109,101,115,112,97, + 99,101,80,97,116,104,46,95,95,108,101,110,95,95,99,1, + 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, + 0,0,0,115,16,0,0,0,100,1,0,106,0,0,124,0, + 0,106,1,0,131,1,0,83,41,2,78,122,20,95,78,97, + 109,101,115,112,97,99,101,80,97,116,104,40,123,33,114,125, + 41,41,2,114,49,0,0,0,114,234,0,0,0,41,1,114, + 110,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,8,95,95,114,101,112,114,95,95,247,3,0, + 0,115,2,0,0,0,0,1,122,23,95,78,97,109,101,115, + 112,97,99,101,80,97,116,104,46,95,95,114,101,112,114,95, + 95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, + 0,0,67,0,0,0,115,16,0,0,0,124,1,0,124,0, + 0,106,0,0,131,0,0,107,6,0,83,41,1,78,41,1, + 114,242,0,0,0,41,2,114,110,0,0,0,218,4,105,116, + 101,109,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,250, + 3,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, + 101,115,112,97,99,101,80,97,116,104,46,95,95,99,111,110, + 116,97,105,110,115,95,95,99,2,0,0,0,0,0,0,0, + 2,0,0,0,2,0,0,0,67,0,0,0,115,20,0,0, + 0,124,0,0,106,0,0,106,1,0,124,1,0,131,1,0, + 1,100,0,0,83,41,1,78,41,2,114,234,0,0,0,114, + 166,0,0,0,41,2,114,110,0,0,0,114,247,0,0,0, + 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,114, + 166,0,0,0,253,3,0,0,115,2,0,0,0,0,1,122, + 21,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, + 97,112,112,101,110,100,78,41,13,114,114,0,0,0,114,113, + 0,0,0,114,115,0,0,0,114,116,0,0,0,114,187,0, + 0,0,114,240,0,0,0,114,235,0,0,0,114,242,0,0, + 0,114,244,0,0,0,114,245,0,0,0,114,246,0,0,0, + 114,248,0,0,0,114,166,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,232, + 0,0,0,201,3,0,0,115,20,0,0,0,12,5,6,2, + 12,6,12,10,12,4,12,13,12,3,12,3,12,3,12,3, + 114,232,0,0,0,99,0,0,0,0,0,0,0,0,0,0, + 0,0,3,0,0,0,64,0,0,0,115,118,0,0,0,101, + 0,0,90,1,0,100,0,0,90,2,0,100,1,0,100,2, + 0,132,0,0,90,3,0,101,4,0,100,3,0,100,4,0, + 132,0,0,131,1,0,90,5,0,100,5,0,100,6,0,132, + 0,0,90,6,0,100,7,0,100,8,0,132,0,0,90,7, + 0,100,9,0,100,10,0,132,0,0,90,8,0,100,11,0, + 100,12,0,132,0,0,90,9,0,100,13,0,100,14,0,132, + 0,0,90,10,0,100,15,0,100,16,0,132,0,0,90,11, + 0,100,17,0,83,41,18,218,16,95,78,97,109,101,115,112, + 97,99,101,76,111,97,100,101,114,99,4,0,0,0,0,0, + 0,0,4,0,0,0,4,0,0,0,67,0,0,0,115,25, + 0,0,0,116,0,0,124,1,0,124,2,0,124,3,0,131, + 3,0,124,0,0,95,1,0,100,0,0,83,41,1,78,41, + 2,114,232,0,0,0,114,234,0,0,0,41,4,114,110,0, + 0,0,114,108,0,0,0,114,37,0,0,0,114,238,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,203,0,0,0,250,3,0,0,115,2,0,0,0,0,1, - 122,27,95,78,97,109,101,115,112,97,99,101,76,111,97,100, - 101,114,46,103,101,116,95,115,111,117,114,99,101,99,2,0, - 0,0,0,0,0,0,2,0,0,0,6,0,0,0,67,0, - 0,0,115,22,0,0,0,116,0,0,100,1,0,100,2,0, - 100,3,0,100,4,0,100,5,0,131,3,1,83,41,6,78, - 114,32,0,0,0,122,8,60,115,116,114,105,110,103,62,114, - 190,0,0,0,114,205,0,0,0,84,41,1,114,206,0,0, - 0,41,2,114,110,0,0,0,114,128,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,6,0,0,0,114,188,0,0, - 0,253,3,0,0,115,2,0,0,0,0,1,122,25,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,103, - 101,116,95,99,111,100,101,99,2,0,0,0,0,0,0,0, - 2,0,0,0,1,0,0,0,67,0,0,0,115,4,0,0, - 0,100,1,0,83,41,2,122,42,85,115,101,32,100,101,102, - 97,117,108,116,32,115,101,109,97,110,116,105,99,115,32,102, - 111,114,32,109,111,100,117,108,101,32,99,114,101,97,116,105, - 111,110,46,78,114,4,0,0,0,41,2,114,110,0,0,0, - 114,166,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,114,187,0,0,0,0,4,0,0,115,0,0, - 0,0,122,30,95,78,97,109,101,115,112,97,99,101,76,111, - 97,100,101,114,46,99,114,101,97,116,101,95,109,111,100,117, - 108,101,99,2,0,0,0,0,0,0,0,2,0,0,0,1, - 0,0,0,67,0,0,0,115,4,0,0,0,100,0,0,83, - 41,1,78,114,4,0,0,0,41,2,114,110,0,0,0,114, - 191,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,192,0,0,0,3,4,0,0,115,2,0,0, - 0,0,1,122,28,95,78,97,109,101,115,112,97,99,101,76, - 111,97,100,101,114,46,101,120,101,99,95,109,111,100,117,108, - 101,99,2,0,0,0,0,0,0,0,2,0,0,0,3,0, - 0,0,67,0,0,0,115,32,0,0,0,116,0,0,100,1, - 0,124,0,0,106,1,0,131,2,0,1,116,2,0,106,3, - 0,124,0,0,124,1,0,131,2,0,83,41,2,122,98,76, - 111,97,100,32,97,32,110,97,109,101,115,112,97,99,101,32, - 109,111,100,117,108,101,46,10,10,32,32,32,32,32,32,32, - 32,84,104,105,115,32,109,101,116,104,111,100,32,105,115,32, - 100,101,112,114,101,99,97,116,101,100,46,32,32,85,115,101, - 32,101,120,101,99,95,109,111,100,117,108,101,40,41,32,105, - 110,115,116,101,97,100,46,10,10,32,32,32,32,32,32,32, - 32,122,38,110,97,109,101,115,112,97,99,101,32,109,111,100, - 117,108,101,32,108,111,97,100,101,100,32,119,105,116,104,32, - 112,97,116,104,32,123,33,114,125,41,4,114,107,0,0,0, - 114,233,0,0,0,114,123,0,0,0,114,193,0,0,0,41, - 2,114,110,0,0,0,114,128,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,114,194,0,0,0,6, - 4,0,0,115,4,0,0,0,0,7,16,1,122,28,95,78, - 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,108, - 111,97,100,95,109,111,100,117,108,101,78,41,12,114,114,0, - 0,0,114,113,0,0,0,114,115,0,0,0,114,186,0,0, - 0,114,184,0,0,0,114,249,0,0,0,114,161,0,0,0, - 114,203,0,0,0,114,188,0,0,0,114,187,0,0,0,114, - 192,0,0,0,114,194,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,114,248,0, - 0,0,234,3,0,0,115,16,0,0,0,12,1,12,3,18, - 9,12,3,12,3,12,3,12,3,12,3,114,248,0,0,0, - 99,0,0,0,0,0,0,0,0,0,0,0,0,5,0,0, - 0,64,0,0,0,115,160,0,0,0,101,0,0,90,1,0, - 100,0,0,90,2,0,100,1,0,90,3,0,101,4,0,100, - 2,0,100,3,0,132,0,0,131,1,0,90,5,0,101,4, - 0,100,4,0,100,5,0,132,0,0,131,1,0,90,6,0, - 101,4,0,100,6,0,100,7,0,132,0,0,131,1,0,90, - 7,0,101,4,0,100,8,0,100,9,0,132,0,0,131,1, - 0,90,8,0,101,4,0,100,10,0,100,11,0,100,12,0, - 132,1,0,131,1,0,90,9,0,101,4,0,100,10,0,100, - 10,0,100,13,0,100,14,0,132,2,0,131,1,0,90,10, - 0,101,4,0,100,10,0,100,15,0,100,16,0,132,1,0, - 131,1,0,90,11,0,100,10,0,83,41,17,218,10,80,97, - 116,104,70,105,110,100,101,114,122,62,77,101,116,97,32,112, - 97,116,104,32,102,105,110,100,101,114,32,102,111,114,32,115, - 121,115,46,112,97,116,104,32,97,110,100,32,112,97,99,107, - 97,103,101,32,95,95,112,97,116,104,95,95,32,97,116,116, - 114,105,98,117,116,101,115,46,99,1,0,0,0,0,0,0, - 0,2,0,0,0,4,0,0,0,67,0,0,0,115,55,0, - 0,0,120,48,0,116,0,0,106,1,0,106,2,0,131,0, - 0,68,93,31,0,125,1,0,116,3,0,124,1,0,100,1, - 0,131,2,0,114,16,0,124,1,0,106,4,0,131,0,0, - 1,113,16,0,87,100,2,0,83,41,3,122,125,67,97,108, - 108,32,116,104,101,32,105,110,118,97,108,105,100,97,116,101, - 95,99,97,99,104,101,115,40,41,32,109,101,116,104,111,100, - 32,111,110,32,97,108,108,32,112,97,116,104,32,101,110,116, - 114,121,32,102,105,110,100,101,114,115,10,32,32,32,32,32, - 32,32,32,115,116,111,114,101,100,32,105,110,32,115,121,115, - 46,112,97,116,104,95,105,109,112,111,114,116,101,114,95,99, - 97,99,104,101,115,32,40,119,104,101,114,101,32,105,109,112, - 108,101,109,101,110,116,101,100,41,46,218,17,105,110,118,97, - 108,105,100,97,116,101,95,99,97,99,104,101,115,78,41,5, - 114,8,0,0,0,218,19,112,97,116,104,95,105,109,112,111, - 114,116,101,114,95,99,97,99,104,101,218,6,118,97,108,117, - 101,115,114,117,0,0,0,114,251,0,0,0,41,2,114,172, - 0,0,0,218,6,102,105,110,100,101,114,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,114,251,0,0,0,23, - 4,0,0,115,6,0,0,0,0,4,22,1,15,1,122,28, - 80,97,116,104,70,105,110,100,101,114,46,105,110,118,97,108, - 105,100,97,116,101,95,99,97,99,104,101,115,99,2,0,0, - 0,0,0,0,0,3,0,0,0,12,0,0,0,67,0,0, - 0,115,107,0,0,0,116,0,0,106,1,0,100,1,0,107, - 9,0,114,41,0,116,0,0,106,1,0,12,114,41,0,116, - 2,0,106,3,0,100,2,0,116,4,0,131,2,0,1,120, - 59,0,116,0,0,106,1,0,68,93,44,0,125,2,0,121, - 14,0,124,2,0,124,1,0,131,1,0,83,87,113,51,0, - 4,116,5,0,107,10,0,114,94,0,1,1,1,119,51,0, - 89,113,51,0,88,113,51,0,87,100,1,0,83,100,1,0, - 83,41,3,122,113,83,101,97,114,99,104,32,115,101,113,117, - 101,110,99,101,32,111,102,32,104,111,111,107,115,32,102,111, - 114,32,97,32,102,105,110,100,101,114,32,102,111,114,32,39, - 112,97,116,104,39,46,10,10,32,32,32,32,32,32,32,32, - 73,102,32,39,104,111,111,107,115,39,32,105,115,32,102,97, - 108,115,101,32,116,104,101,110,32,117,115,101,32,115,121,115, - 46,112,97,116,104,95,104,111,111,107,115,46,10,10,32,32, - 32,32,32,32,32,32,78,122,23,115,121,115,46,112,97,116, - 104,95,104,111,111,107,115,32,105,115,32,101,109,112,116,121, - 41,6,114,8,0,0,0,218,10,112,97,116,104,95,104,111, - 111,107,115,114,62,0,0,0,114,63,0,0,0,114,127,0, - 0,0,114,109,0,0,0,41,3,114,172,0,0,0,114,37, - 0,0,0,90,4,104,111,111,107,114,4,0,0,0,114,4, - 0,0,0,114,6,0,0,0,218,11,95,112,97,116,104,95, - 104,111,111,107,115,31,4,0,0,115,16,0,0,0,0,7, - 25,1,16,1,16,1,3,1,14,1,13,1,12,2,122,22, - 80,97,116,104,70,105,110,100,101,114,46,95,112,97,116,104, - 95,104,111,111,107,115,99,2,0,0,0,0,0,0,0,3, - 0,0,0,19,0,0,0,67,0,0,0,115,123,0,0,0, - 124,1,0,100,1,0,107,2,0,114,53,0,121,16,0,116, - 0,0,106,1,0,131,0,0,125,1,0,87,110,22,0,4, - 116,2,0,107,10,0,114,52,0,1,1,1,100,2,0,83, - 89,110,1,0,88,121,17,0,116,3,0,106,4,0,124,1, - 0,25,125,2,0,87,110,46,0,4,116,5,0,107,10,0, - 114,118,0,1,1,1,124,0,0,106,6,0,124,1,0,131, - 1,0,125,2,0,124,2,0,116,3,0,106,4,0,124,1, - 0,60,89,110,1,0,88,124,2,0,83,41,3,122,210,71, - 101,116,32,116,104,101,32,102,105,110,100,101,114,32,102,111, - 114,32,116,104,101,32,112,97,116,104,32,101,110,116,114,121, - 32,102,114,111,109,32,115,121,115,46,112,97,116,104,95,105, - 109,112,111,114,116,101,114,95,99,97,99,104,101,46,10,10, - 32,32,32,32,32,32,32,32,73,102,32,116,104,101,32,112, - 97,116,104,32,101,110,116,114,121,32,105,115,32,110,111,116, - 32,105,110,32,116,104,101,32,99,97,99,104,101,44,32,102, - 105,110,100,32,116,104,101,32,97,112,112,114,111,112,114,105, - 97,116,101,32,102,105,110,100,101,114,10,32,32,32,32,32, - 32,32,32,97,110,100,32,99,97,99,104,101,32,105,116,46, - 32,73,102,32,110,111,32,102,105,110,100,101,114,32,105,115, - 32,97,118,97,105,108,97,98,108,101,44,32,115,116,111,114, - 101,32,78,111,110,101,46,10,10,32,32,32,32,32,32,32, - 32,114,32,0,0,0,78,41,7,114,3,0,0,0,114,47, - 0,0,0,218,17,70,105,108,101,78,111,116,70,111,117,110, - 100,69,114,114,111,114,114,8,0,0,0,114,252,0,0,0, - 114,139,0,0,0,114,0,1,0,0,41,3,114,172,0,0, - 0,114,37,0,0,0,114,254,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,6,0,0,0,218,20,95,112,97,116, - 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 48,4,0,0,115,22,0,0,0,0,8,12,1,3,1,16, - 1,13,3,9,1,3,1,17,1,13,1,15,1,18,1,122, - 31,80,97,116,104,70,105,110,100,101,114,46,95,112,97,116, - 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 99,3,0,0,0,0,0,0,0,6,0,0,0,3,0,0, - 0,67,0,0,0,115,119,0,0,0,116,0,0,124,2,0, - 100,1,0,131,2,0,114,39,0,124,2,0,106,1,0,124, - 1,0,131,1,0,92,2,0,125,3,0,125,4,0,110,21, - 0,124,2,0,106,2,0,124,1,0,131,1,0,125,3,0, - 103,0,0,125,4,0,124,3,0,100,0,0,107,9,0,114, - 88,0,116,3,0,106,4,0,124,1,0,124,3,0,131,2, - 0,83,116,3,0,106,5,0,124,1,0,100,0,0,131,2, - 0,125,5,0,124,4,0,124,5,0,95,6,0,124,5,0, - 83,41,2,78,114,126,0,0,0,41,7,114,117,0,0,0, - 114,126,0,0,0,114,183,0,0,0,114,123,0,0,0,114, - 180,0,0,0,114,162,0,0,0,114,158,0,0,0,41,6, - 114,172,0,0,0,114,128,0,0,0,114,254,0,0,0,114, - 129,0,0,0,114,130,0,0,0,114,166,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,6,0,0,0,218,16,95, - 108,101,103,97,99,121,95,103,101,116,95,115,112,101,99,70, - 4,0,0,115,18,0,0,0,0,4,15,1,24,2,15,1, - 6,1,12,1,16,1,18,1,9,1,122,27,80,97,116,104, - 70,105,110,100,101,114,46,95,108,101,103,97,99,121,95,103, - 101,116,95,115,112,101,99,78,99,4,0,0,0,0,0,0, - 0,9,0,0,0,5,0,0,0,67,0,0,0,115,243,0, - 0,0,103,0,0,125,4,0,120,230,0,124,2,0,68,93, - 191,0,125,5,0,116,0,0,124,5,0,116,1,0,116,2, - 0,102,2,0,131,2,0,115,43,0,113,13,0,124,0,0, - 106,3,0,124,5,0,131,1,0,125,6,0,124,6,0,100, - 1,0,107,9,0,114,13,0,116,4,0,124,6,0,100,2, - 0,131,2,0,114,106,0,124,6,0,106,5,0,124,1,0, - 124,3,0,131,2,0,125,7,0,110,18,0,124,0,0,106, - 6,0,124,1,0,124,6,0,131,2,0,125,7,0,124,7, - 0,100,1,0,107,8,0,114,139,0,113,13,0,124,7,0, - 106,7,0,100,1,0,107,9,0,114,158,0,124,7,0,83, - 124,7,0,106,8,0,125,8,0,124,8,0,100,1,0,107, - 8,0,114,191,0,116,9,0,100,3,0,131,1,0,130,1, - 0,124,4,0,106,10,0,124,8,0,131,1,0,1,113,13, - 0,87,116,11,0,106,12,0,124,1,0,100,1,0,131,2, - 0,125,7,0,124,4,0,124,7,0,95,8,0,124,7,0, - 83,100,1,0,83,41,4,122,63,70,105,110,100,32,116,104, - 101,32,108,111,97,100,101,114,32,111,114,32,110,97,109,101, - 115,112,97,99,101,95,112,97,116,104,32,102,111,114,32,116, - 104,105,115,32,109,111,100,117,108,101,47,112,97,99,107,97, - 103,101,32,110,97,109,101,46,78,114,182,0,0,0,122,19, - 115,112,101,99,32,109,105,115,115,105,110,103,32,108,111,97, - 100,101,114,41,13,114,145,0,0,0,114,71,0,0,0,218, - 5,98,121,116,101,115,114,2,1,0,0,114,117,0,0,0, - 114,182,0,0,0,114,3,1,0,0,114,129,0,0,0,114, - 158,0,0,0,114,109,0,0,0,114,151,0,0,0,114,123, - 0,0,0,114,162,0,0,0,41,9,114,172,0,0,0,114, - 128,0,0,0,114,37,0,0,0,114,181,0,0,0,218,14, - 110,97,109,101,115,112,97,99,101,95,112,97,116,104,90,5, - 101,110,116,114,121,114,254,0,0,0,114,166,0,0,0,114, - 130,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,218,9,95,103,101,116,95,115,112,101,99,85,4, - 0,0,115,40,0,0,0,0,5,6,1,13,1,21,1,3, - 1,15,1,12,1,15,1,21,2,18,1,12,1,3,1,15, - 1,4,1,9,1,12,1,12,5,17,2,18,1,9,1,122, - 20,80,97,116,104,70,105,110,100,101,114,46,95,103,101,116, - 95,115,112,101,99,99,4,0,0,0,0,0,0,0,6,0, - 0,0,4,0,0,0,67,0,0,0,115,140,0,0,0,124, - 2,0,100,1,0,107,8,0,114,21,0,116,0,0,106,1, - 0,125,2,0,124,0,0,106,2,0,124,1,0,124,2,0, - 124,3,0,131,3,0,125,4,0,124,4,0,100,1,0,107, - 8,0,114,58,0,100,1,0,83,124,4,0,106,3,0,100, - 1,0,107,8,0,114,132,0,124,4,0,106,4,0,125,5, - 0,124,5,0,114,125,0,100,2,0,124,4,0,95,5,0, - 116,6,0,124,1,0,124,5,0,124,0,0,106,2,0,131, - 3,0,124,4,0,95,4,0,124,4,0,83,100,1,0,83, - 110,4,0,124,4,0,83,100,1,0,83,41,3,122,98,102, + 114,187,0,0,0,3,4,0,0,115,2,0,0,0,0,1, + 122,25,95,78,97,109,101,115,112,97,99,101,76,111,97,100, + 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, + 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, + 115,16,0,0,0,100,1,0,106,0,0,124,1,0,106,1, + 0,131,1,0,83,41,2,122,115,82,101,116,117,114,110,32, + 114,101,112,114,32,102,111,114,32,116,104,101,32,109,111,100, + 117,108,101,46,10,10,32,32,32,32,32,32,32,32,84,104, + 101,32,109,101,116,104,111,100,32,105,115,32,100,101,112,114, + 101,99,97,116,101,100,46,32,32,84,104,101,32,105,109,112, + 111,114,116,32,109,97,99,104,105,110,101,114,121,32,100,111, + 101,115,32,116,104,101,32,106,111,98,32,105,116,115,101,108, + 102,46,10,10,32,32,32,32,32,32,32,32,122,25,60,109, + 111,100,117,108,101,32,123,33,114,125,32,40,110,97,109,101, + 115,112,97,99,101,41,62,41,2,114,49,0,0,0,114,114, + 0,0,0,41,2,114,173,0,0,0,114,192,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,218,11, + 109,111,100,117,108,101,95,114,101,112,114,6,4,0,0,115, + 2,0,0,0,0,7,122,28,95,78,97,109,101,115,112,97, + 99,101,76,111,97,100,101,114,46,109,111,100,117,108,101,95, + 114,101,112,114,99,2,0,0,0,0,0,0,0,2,0,0, + 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, + 0,83,41,2,78,84,114,4,0,0,0,41,2,114,110,0, + 0,0,114,128,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,114,162,0,0,0,15,4,0,0,115, + 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, + 99,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, + 97,103,101,99,2,0,0,0,0,0,0,0,2,0,0,0, + 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,0, + 83,41,2,78,114,32,0,0,0,114,4,0,0,0,41,2, + 114,110,0,0,0,114,128,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,114,204,0,0,0,18,4, + 0,0,115,2,0,0,0,0,1,122,27,95,78,97,109,101, + 115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95, + 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,2, + 0,0,0,6,0,0,0,67,0,0,0,115,22,0,0,0, + 116,0,0,100,1,0,100,2,0,100,3,0,100,4,0,100, + 5,0,131,3,1,83,41,6,78,114,32,0,0,0,122,8, + 60,115,116,114,105,110,103,62,114,191,0,0,0,114,206,0, + 0,0,84,41,1,114,207,0,0,0,41,2,114,110,0,0, + 0,114,128,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,6,0,0,0,114,189,0,0,0,21,4,0,0,115,2, + 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, + 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, + 0,67,0,0,0,115,4,0,0,0,100,1,0,83,41,2, + 122,42,85,115,101,32,100,101,102,97,117,108,116,32,115,101, + 109,97,110,116,105,99,115,32,102,111,114,32,109,111,100,117, + 108,101,32,99,114,101,97,116,105,111,110,46,78,114,4,0, + 0,0,41,2,114,110,0,0,0,114,167,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,6,0,0,0,114,188,0, + 0,0,24,4,0,0,115,0,0,0,0,122,30,95,78,97, + 109,101,115,112,97,99,101,76,111,97,100,101,114,46,99,114, + 101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,0, + 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, + 115,4,0,0,0,100,0,0,83,41,1,78,114,4,0,0, + 0,41,2,114,110,0,0,0,114,192,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,114,193,0,0, + 0,27,4,0,0,115,2,0,0,0,0,1,122,28,95,78, + 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, + 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, + 32,0,0,0,116,0,0,100,1,0,124,0,0,106,1,0, + 131,2,0,1,116,2,0,106,3,0,124,0,0,124,1,0, + 131,2,0,83,41,2,122,98,76,111,97,100,32,97,32,110, + 97,109,101,115,112,97,99,101,32,109,111,100,117,108,101,46, + 10,10,32,32,32,32,32,32,32,32,84,104,105,115,32,109, + 101,116,104,111,100,32,105,115,32,100,101,112,114,101,99,97, + 116,101,100,46,32,32,85,115,101,32,101,120,101,99,95,109, + 111,100,117,108,101,40,41,32,105,110,115,116,101,97,100,46, + 10,10,32,32,32,32,32,32,32,32,122,38,110,97,109,101, + 115,112,97,99,101,32,109,111,100,117,108,101,32,108,111,97, + 100,101,100,32,119,105,116,104,32,112,97,116,104,32,123,33, + 114,125,41,4,114,107,0,0,0,114,234,0,0,0,114,123, + 0,0,0,114,194,0,0,0,41,2,114,110,0,0,0,114, + 128,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,114,195,0,0,0,30,4,0,0,115,4,0,0, + 0,0,7,16,1,122,28,95,78,97,109,101,115,112,97,99, + 101,76,111,97,100,101,114,46,108,111,97,100,95,109,111,100, + 117,108,101,78,41,12,114,114,0,0,0,114,113,0,0,0, + 114,115,0,0,0,114,187,0,0,0,114,185,0,0,0,114, + 250,0,0,0,114,162,0,0,0,114,204,0,0,0,114,189, + 0,0,0,114,188,0,0,0,114,193,0,0,0,114,195,0, + 0,0,114,4,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,114,249,0,0,0,2,4,0,0,115, + 16,0,0,0,12,1,12,3,18,9,12,3,12,3,12,3, + 12,3,12,3,114,249,0,0,0,99,0,0,0,0,0,0, + 0,0,0,0,0,0,5,0,0,0,64,0,0,0,115,160, + 0,0,0,101,0,0,90,1,0,100,0,0,90,2,0,100, + 1,0,90,3,0,101,4,0,100,2,0,100,3,0,132,0, + 0,131,1,0,90,5,0,101,4,0,100,4,0,100,5,0, + 132,0,0,131,1,0,90,6,0,101,4,0,100,6,0,100, + 7,0,132,0,0,131,1,0,90,7,0,101,4,0,100,8, + 0,100,9,0,132,0,0,131,1,0,90,8,0,101,4,0, + 100,10,0,100,11,0,100,12,0,132,1,0,131,1,0,90, + 9,0,101,4,0,100,10,0,100,10,0,100,13,0,100,14, + 0,132,2,0,131,1,0,90,10,0,101,4,0,100,10,0, + 100,15,0,100,16,0,132,1,0,131,1,0,90,11,0,100, + 10,0,83,41,17,218,10,80,97,116,104,70,105,110,100,101, + 114,122,62,77,101,116,97,32,112,97,116,104,32,102,105,110, + 100,101,114,32,102,111,114,32,115,121,115,46,112,97,116,104, + 32,97,110,100,32,112,97,99,107,97,103,101,32,95,95,112, + 97,116,104,95,95,32,97,116,116,114,105,98,117,116,101,115, + 46,99,1,0,0,0,0,0,0,0,2,0,0,0,4,0, + 0,0,67,0,0,0,115,55,0,0,0,120,48,0,116,0, + 0,106,1,0,106,2,0,131,0,0,68,93,31,0,125,1, + 0,116,3,0,124,1,0,100,1,0,131,2,0,114,16,0, + 124,1,0,106,4,0,131,0,0,1,113,16,0,87,100,2, + 0,83,41,3,122,125,67,97,108,108,32,116,104,101,32,105, + 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, + 40,41,32,109,101,116,104,111,100,32,111,110,32,97,108,108, + 32,112,97,116,104,32,101,110,116,114,121,32,102,105,110,100, + 101,114,115,10,32,32,32,32,32,32,32,32,115,116,111,114, + 101,100,32,105,110,32,115,121,115,46,112,97,116,104,95,105, + 109,112,111,114,116,101,114,95,99,97,99,104,101,115,32,40, + 119,104,101,114,101,32,105,109,112,108,101,109,101,110,116,101, + 100,41,46,218,17,105,110,118,97,108,105,100,97,116,101,95, + 99,97,99,104,101,115,78,41,5,114,8,0,0,0,218,19, + 112,97,116,104,95,105,109,112,111,114,116,101,114,95,99,97, + 99,104,101,218,6,118,97,108,117,101,115,114,117,0,0,0, + 114,252,0,0,0,41,2,114,173,0,0,0,218,6,102,105, + 110,100,101,114,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,114,252,0,0,0,47,4,0,0,115,6,0,0, + 0,0,4,22,1,15,1,122,28,80,97,116,104,70,105,110, + 100,101,114,46,105,110,118,97,108,105,100,97,116,101,95,99, + 97,99,104,101,115,99,2,0,0,0,0,0,0,0,3,0, + 0,0,12,0,0,0,67,0,0,0,115,107,0,0,0,116, + 0,0,106,1,0,100,1,0,107,9,0,114,41,0,116,0, + 0,106,1,0,12,114,41,0,116,2,0,106,3,0,100,2, + 0,116,4,0,131,2,0,1,120,59,0,116,0,0,106,1, + 0,68,93,44,0,125,2,0,121,14,0,124,2,0,124,1, + 0,131,1,0,83,87,113,51,0,4,116,5,0,107,10,0, + 114,94,0,1,1,1,119,51,0,89,113,51,0,88,113,51, + 0,87,100,1,0,83,100,1,0,83,41,3,122,113,83,101, + 97,114,99,104,32,115,101,113,117,101,110,99,101,32,111,102, + 32,104,111,111,107,115,32,102,111,114,32,97,32,102,105,110, + 100,101,114,32,102,111,114,32,39,112,97,116,104,39,46,10, + 10,32,32,32,32,32,32,32,32,73,102,32,39,104,111,111, + 107,115,39,32,105,115,32,102,97,108,115,101,32,116,104,101, + 110,32,117,115,101,32,115,121,115,46,112,97,116,104,95,104, + 111,111,107,115,46,10,10,32,32,32,32,32,32,32,32,78, + 122,23,115,121,115,46,112,97,116,104,95,104,111,111,107,115, + 32,105,115,32,101,109,112,116,121,41,6,114,8,0,0,0, + 218,10,112,97,116,104,95,104,111,111,107,115,114,62,0,0, + 0,114,63,0,0,0,114,127,0,0,0,114,109,0,0,0, + 41,3,114,173,0,0,0,114,37,0,0,0,90,4,104,111, + 111,107,114,4,0,0,0,114,4,0,0,0,114,6,0,0, + 0,218,11,95,112,97,116,104,95,104,111,111,107,115,55,4, + 0,0,115,16,0,0,0,0,7,25,1,16,1,16,1,3, + 1,14,1,13,1,12,2,122,22,80,97,116,104,70,105,110, + 100,101,114,46,95,112,97,116,104,95,104,111,111,107,115,99, + 2,0,0,0,0,0,0,0,3,0,0,0,19,0,0,0, + 67,0,0,0,115,123,0,0,0,124,1,0,100,1,0,107, + 2,0,114,53,0,121,16,0,116,0,0,106,1,0,131,0, + 0,125,1,0,87,110,22,0,4,116,2,0,107,10,0,114, + 52,0,1,1,1,100,2,0,83,89,110,1,0,88,121,17, + 0,116,3,0,106,4,0,124,1,0,25,125,2,0,87,110, + 46,0,4,116,5,0,107,10,0,114,118,0,1,1,1,124, + 0,0,106,6,0,124,1,0,131,1,0,125,2,0,124,2, + 0,116,3,0,106,4,0,124,1,0,60,89,110,1,0,88, + 124,2,0,83,41,3,122,210,71,101,116,32,116,104,101,32, + 102,105,110,100,101,114,32,102,111,114,32,116,104,101,32,112, + 97,116,104,32,101,110,116,114,121,32,102,114,111,109,32,115, + 121,115,46,112,97,116,104,95,105,109,112,111,114,116,101,114, + 95,99,97,99,104,101,46,10,10,32,32,32,32,32,32,32, + 32,73,102,32,116,104,101,32,112,97,116,104,32,101,110,116, + 114,121,32,105,115,32,110,111,116,32,105,110,32,116,104,101, + 32,99,97,99,104,101,44,32,102,105,110,100,32,116,104,101, + 32,97,112,112,114,111,112,114,105,97,116,101,32,102,105,110, + 100,101,114,10,32,32,32,32,32,32,32,32,97,110,100,32, + 99,97,99,104,101,32,105,116,46,32,73,102,32,110,111,32, + 102,105,110,100,101,114,32,105,115,32,97,118,97,105,108,97, + 98,108,101,44,32,115,116,111,114,101,32,78,111,110,101,46, + 10,10,32,32,32,32,32,32,32,32,114,32,0,0,0,78, + 41,7,114,3,0,0,0,114,47,0,0,0,218,17,70,105, + 108,101,78,111,116,70,111,117,110,100,69,114,114,111,114,114, + 8,0,0,0,114,253,0,0,0,114,140,0,0,0,114,1, + 1,0,0,41,3,114,173,0,0,0,114,37,0,0,0,114, + 255,0,0,0,114,4,0,0,0,114,4,0,0,0,114,6, + 0,0,0,218,20,95,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,72,4,0,0,115,22,0, + 0,0,0,8,12,1,3,1,16,1,13,3,9,1,3,1, + 17,1,13,1,15,1,18,1,122,31,80,97,116,104,70,105, + 110,100,101,114,46,95,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,99,3,0,0,0,0,0, + 0,0,6,0,0,0,3,0,0,0,67,0,0,0,115,119, + 0,0,0,116,0,0,124,2,0,100,1,0,131,2,0,114, + 39,0,124,2,0,106,1,0,124,1,0,131,1,0,92,2, + 0,125,3,0,125,4,0,110,21,0,124,2,0,106,2,0, + 124,1,0,131,1,0,125,3,0,103,0,0,125,4,0,124, + 3,0,100,0,0,107,9,0,114,88,0,116,3,0,106,4, + 0,124,1,0,124,3,0,131,2,0,83,116,3,0,106,5, + 0,124,1,0,100,0,0,131,2,0,125,5,0,124,4,0, + 124,5,0,95,6,0,124,5,0,83,41,2,78,114,126,0, + 0,0,41,7,114,117,0,0,0,114,126,0,0,0,114,184, + 0,0,0,114,123,0,0,0,114,181,0,0,0,114,163,0, + 0,0,114,159,0,0,0,41,6,114,173,0,0,0,114,128, + 0,0,0,114,255,0,0,0,114,129,0,0,0,114,130,0, + 0,0,114,167,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,6,0,0,0,218,16,95,108,101,103,97,99,121,95, + 103,101,116,95,115,112,101,99,94,4,0,0,115,18,0,0, + 0,0,4,15,1,24,2,15,1,6,1,12,1,16,1,18, + 1,9,1,122,27,80,97,116,104,70,105,110,100,101,114,46, + 95,108,101,103,97,99,121,95,103,101,116,95,115,112,101,99, + 78,99,4,0,0,0,0,0,0,0,9,0,0,0,5,0, + 0,0,67,0,0,0,115,243,0,0,0,103,0,0,125,4, + 0,120,230,0,124,2,0,68,93,191,0,125,5,0,116,0, + 0,124,5,0,116,1,0,116,2,0,102,2,0,131,2,0, + 115,43,0,113,13,0,124,0,0,106,3,0,124,5,0,131, + 1,0,125,6,0,124,6,0,100,1,0,107,9,0,114,13, + 0,116,4,0,124,6,0,100,2,0,131,2,0,114,106,0, + 124,6,0,106,5,0,124,1,0,124,3,0,131,2,0,125, + 7,0,110,18,0,124,0,0,106,6,0,124,1,0,124,6, + 0,131,2,0,125,7,0,124,7,0,100,1,0,107,8,0, + 114,139,0,113,13,0,124,7,0,106,7,0,100,1,0,107, + 9,0,114,158,0,124,7,0,83,124,7,0,106,8,0,125, + 8,0,124,8,0,100,1,0,107,8,0,114,191,0,116,9, + 0,100,3,0,131,1,0,130,1,0,124,4,0,106,10,0, + 124,8,0,131,1,0,1,113,13,0,87,116,11,0,106,12, + 0,124,1,0,100,1,0,131,2,0,125,7,0,124,4,0, + 124,7,0,95,8,0,124,7,0,83,100,1,0,83,41,4, + 122,63,70,105,110,100,32,116,104,101,32,108,111,97,100,101, + 114,32,111,114,32,110,97,109,101,115,112,97,99,101,95,112, + 97,116,104,32,102,111,114,32,116,104,105,115,32,109,111,100, + 117,108,101,47,112,97,99,107,97,103,101,32,110,97,109,101, + 46,78,114,183,0,0,0,122,19,115,112,101,99,32,109,105, + 115,115,105,110,103,32,108,111,97,100,101,114,41,13,114,146, + 0,0,0,114,71,0,0,0,218,5,98,121,116,101,115,114, + 3,1,0,0,114,117,0,0,0,114,183,0,0,0,114,4, + 1,0,0,114,129,0,0,0,114,159,0,0,0,114,109,0, + 0,0,114,152,0,0,0,114,123,0,0,0,114,163,0,0, + 0,41,9,114,173,0,0,0,114,128,0,0,0,114,37,0, + 0,0,114,182,0,0,0,218,14,110,97,109,101,115,112,97, + 99,101,95,112,97,116,104,90,5,101,110,116,114,121,114,255, + 0,0,0,114,167,0,0,0,114,130,0,0,0,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,218,9,95,103, + 101,116,95,115,112,101,99,109,4,0,0,115,40,0,0,0, + 0,5,6,1,13,1,21,1,3,1,15,1,12,1,15,1, + 21,2,18,1,12,1,3,1,15,1,4,1,9,1,12,1, + 12,5,17,2,18,1,9,1,122,20,80,97,116,104,70,105, + 110,100,101,114,46,95,103,101,116,95,115,112,101,99,99,4, + 0,0,0,0,0,0,0,6,0,0,0,4,0,0,0,67, + 0,0,0,115,140,0,0,0,124,2,0,100,1,0,107,8, + 0,114,21,0,116,0,0,106,1,0,125,2,0,124,0,0, + 106,2,0,124,1,0,124,2,0,124,3,0,131,3,0,125, + 4,0,124,4,0,100,1,0,107,8,0,114,58,0,100,1, + 0,83,124,4,0,106,3,0,100,1,0,107,8,0,114,132, + 0,124,4,0,106,4,0,125,5,0,124,5,0,114,125,0, + 100,2,0,124,4,0,95,5,0,116,6,0,124,1,0,124, + 5,0,124,0,0,106,2,0,131,3,0,124,4,0,95,4, + 0,124,4,0,83,100,1,0,83,110,4,0,124,4,0,83, + 100,1,0,83,41,3,122,98,102,105,110,100,32,116,104,101, + 32,109,111,100,117,108,101,32,111,110,32,115,121,115,46,112, + 97,116,104,32,111,114,32,39,112,97,116,104,39,32,98,97, + 115,101,100,32,111,110,32,115,121,115,46,112,97,116,104,95, + 104,111,111,107,115,32,97,110,100,10,32,32,32,32,32,32, + 32,32,115,121,115,46,112,97,116,104,95,105,109,112,111,114, + 116,101,114,95,99,97,99,104,101,46,78,90,9,110,97,109, + 101,115,112,97,99,101,41,7,114,8,0,0,0,114,37,0, + 0,0,114,7,1,0,0,114,129,0,0,0,114,159,0,0, + 0,114,161,0,0,0,114,232,0,0,0,41,6,114,173,0, + 0,0,114,128,0,0,0,114,37,0,0,0,114,182,0,0, + 0,114,167,0,0,0,114,6,1,0,0,114,4,0,0,0, + 114,4,0,0,0,114,6,0,0,0,114,183,0,0,0,141, + 4,0,0,115,26,0,0,0,0,4,12,1,9,1,21,1, + 12,1,4,1,15,1,9,1,6,3,9,1,24,1,4,2, + 7,2,122,20,80,97,116,104,70,105,110,100,101,114,46,102, + 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, + 0,4,0,0,0,3,0,0,0,67,0,0,0,115,41,0, + 0,0,124,0,0,106,0,0,124,1,0,124,2,0,131,2, + 0,125,3,0,124,3,0,100,1,0,107,8,0,114,34,0, + 100,1,0,83,124,3,0,106,1,0,83,41,2,122,170,102, 105,110,100,32,116,104,101,32,109,111,100,117,108,101,32,111, 110,32,115,121,115,46,112,97,116,104,32,111,114,32,39,112, 97,116,104,39,32,98,97,115,101,100,32,111,110,32,115,121, 115,46,112,97,116,104,95,104,111,111,107,115,32,97,110,100, 10,32,32,32,32,32,32,32,32,115,121,115,46,112,97,116, 104,95,105,109,112,111,114,116,101,114,95,99,97,99,104,101, - 46,78,90,9,110,97,109,101,115,112,97,99,101,41,7,114, - 8,0,0,0,114,37,0,0,0,114,6,1,0,0,114,129, - 0,0,0,114,158,0,0,0,114,160,0,0,0,114,231,0, - 0,0,41,6,114,172,0,0,0,114,128,0,0,0,114,37, - 0,0,0,114,181,0,0,0,114,166,0,0,0,114,5,1, - 0,0,114,4,0,0,0,114,4,0,0,0,114,6,0,0, - 0,114,182,0,0,0,117,4,0,0,115,26,0,0,0,0, - 4,12,1,9,1,21,1,12,1,4,1,15,1,9,1,6, - 3,9,1,24,1,4,2,7,2,122,20,80,97,116,104,70, - 105,110,100,101,114,46,102,105,110,100,95,115,112,101,99,99, - 3,0,0,0,0,0,0,0,4,0,0,0,3,0,0,0, - 67,0,0,0,115,41,0,0,0,124,0,0,106,0,0,124, - 1,0,124,2,0,131,2,0,125,3,0,124,3,0,100,1, - 0,107,8,0,114,34,0,100,1,0,83,124,3,0,106,1, - 0,83,41,2,122,170,102,105,110,100,32,116,104,101,32,109, - 111,100,117,108,101,32,111,110,32,115,121,115,46,112,97,116, - 104,32,111,114,32,39,112,97,116,104,39,32,98,97,115,101, - 100,32,111,110,32,115,121,115,46,112,97,116,104,95,104,111, - 111,107,115,32,97,110,100,10,32,32,32,32,32,32,32,32, - 115,121,115,46,112,97,116,104,95,105,109,112,111,114,116,101, - 114,95,99,97,99,104,101,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 78,41,2,114,182,0,0,0,114,129,0,0,0,41,4,114, - 172,0,0,0,114,128,0,0,0,114,37,0,0,0,114,166, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,183,0,0,0,139,4,0,0,115,8,0,0,0, - 0,8,18,1,12,1,4,1,122,22,80,97,116,104,70,105, - 110,100,101,114,46,102,105,110,100,95,109,111,100,117,108,101, - 41,12,114,114,0,0,0,114,113,0,0,0,114,115,0,0, - 0,114,116,0,0,0,114,184,0,0,0,114,251,0,0,0, - 114,0,1,0,0,114,2,1,0,0,114,3,1,0,0,114, - 6,1,0,0,114,182,0,0,0,114,183,0,0,0,114,4, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,250,0,0,0,19,4,0,0,115,22,0,0,0, - 12,2,6,2,18,8,18,17,18,22,18,15,3,1,18,31, - 3,1,21,21,3,1,114,250,0,0,0,99,0,0,0,0, - 0,0,0,0,0,0,0,0,3,0,0,0,64,0,0,0, - 115,133,0,0,0,101,0,0,90,1,0,100,0,0,90,2, - 0,100,1,0,90,3,0,100,2,0,100,3,0,132,0,0, - 90,4,0,100,4,0,100,5,0,132,0,0,90,5,0,101, - 6,0,90,7,0,100,6,0,100,7,0,132,0,0,90,8, - 0,100,8,0,100,9,0,132,0,0,90,9,0,100,10,0, - 100,11,0,100,12,0,132,1,0,90,10,0,100,13,0,100, - 14,0,132,0,0,90,11,0,101,12,0,100,15,0,100,16, - 0,132,0,0,131,1,0,90,13,0,100,17,0,100,18,0, - 132,0,0,90,14,0,100,10,0,83,41,19,218,10,70,105, - 108,101,70,105,110,100,101,114,122,172,70,105,108,101,45,98, - 97,115,101,100,32,102,105,110,100,101,114,46,10,10,32,32, - 32,32,73,110,116,101,114,97,99,116,105,111,110,115,32,119, - 105,116,104,32,116,104,101,32,102,105,108,101,32,115,121,115, - 116,101,109,32,97,114,101,32,99,97,99,104,101,100,32,102, - 111,114,32,112,101,114,102,111,114,109,97,110,99,101,44,32, - 98,101,105,110,103,10,32,32,32,32,114,101,102,114,101,115, - 104,101,100,32,119,104,101,110,32,116,104,101,32,100,105,114, - 101,99,116,111,114,121,32,116,104,101,32,102,105,110,100,101, - 114,32,105,115,32,104,97,110,100,108,105,110,103,32,104,97, - 115,32,98,101,101,110,32,109,111,100,105,102,105,101,100,46, - 10,10,32,32,32,32,99,2,0,0,0,0,0,0,0,5, - 0,0,0,5,0,0,0,7,0,0,0,115,122,0,0,0, - 103,0,0,125,3,0,120,52,0,124,2,0,68,93,44,0, - 92,2,0,137,0,0,125,4,0,124,3,0,106,0,0,135, - 0,0,102,1,0,100,1,0,100,2,0,134,0,0,124,4, - 0,68,131,1,0,131,1,0,1,113,13,0,87,124,3,0, - 124,0,0,95,1,0,124,1,0,112,79,0,100,3,0,124, - 0,0,95,2,0,100,6,0,124,0,0,95,3,0,116,4, - 0,131,0,0,124,0,0,95,5,0,116,4,0,131,0,0, - 124,0,0,95,6,0,100,5,0,83,41,7,122,154,73,110, - 105,116,105,97,108,105,122,101,32,119,105,116,104,32,116,104, - 101,32,112,97,116,104,32,116,111,32,115,101,97,114,99,104, - 32,111,110,32,97,110,100,32,97,32,118,97,114,105,97,98, - 108,101,32,110,117,109,98,101,114,32,111,102,10,32,32,32, - 32,32,32,32,32,50,45,116,117,112,108,101,115,32,99,111, - 110,116,97,105,110,105,110,103,32,116,104,101,32,108,111,97, - 100,101,114,32,97,110,100,32,116,104,101,32,102,105,108,101, - 32,115,117,102,102,105,120,101,115,32,116,104,101,32,108,111, - 97,100,101,114,10,32,32,32,32,32,32,32,32,114,101,99, - 111,103,110,105,122,101,115,46,99,1,0,0,0,0,0,0, - 0,2,0,0,0,3,0,0,0,51,0,0,0,115,27,0, - 0,0,124,0,0,93,17,0,125,1,0,124,1,0,136,0, - 0,102,2,0,86,1,113,3,0,100,0,0,83,41,1,78, - 114,4,0,0,0,41,2,114,24,0,0,0,114,226,0,0, - 0,41,1,114,129,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,228,0,0,0,168,4,0,0,115,2,0,0,0, - 6,0,122,38,70,105,108,101,70,105,110,100,101,114,46,95, - 95,105,110,105,116,95,95,46,60,108,111,99,97,108,115,62, - 46,60,103,101,110,101,120,112,114,62,114,60,0,0,0,114, - 31,0,0,0,78,114,89,0,0,0,41,7,114,151,0,0, - 0,218,8,95,108,111,97,100,101,114,115,114,37,0,0,0, - 218,11,95,112,97,116,104,95,109,116,105,109,101,218,3,115, - 101,116,218,11,95,112,97,116,104,95,99,97,99,104,101,218, - 19,95,114,101,108,97,120,101,100,95,112,97,116,104,95,99, - 97,99,104,101,41,5,114,110,0,0,0,114,37,0,0,0, - 218,14,108,111,97,100,101,114,95,100,101,116,97,105,108,115, - 90,7,108,111,97,100,101,114,115,114,168,0,0,0,114,4, - 0,0,0,41,1,114,129,0,0,0,114,6,0,0,0,114, - 186,0,0,0,162,4,0,0,115,16,0,0,0,0,4,6, - 1,19,1,36,1,9,2,15,1,9,1,12,1,122,19,70, - 105,108,101,70,105,110,100,101,114,46,95,95,105,110,105,116, - 95,95,99,1,0,0,0,0,0,0,0,1,0,0,0,2, - 0,0,0,67,0,0,0,115,13,0,0,0,100,3,0,124, - 0,0,95,0,0,100,2,0,83,41,4,122,31,73,110,118, - 97,108,105,100,97,116,101,32,116,104,101,32,100,105,114,101, - 99,116,111,114,121,32,109,116,105,109,101,46,114,31,0,0, - 0,78,114,89,0,0,0,41,1,114,9,1,0,0,41,1, - 114,110,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 6,0,0,0,114,251,0,0,0,176,4,0,0,115,2,0, - 0,0,0,2,122,28,70,105,108,101,70,105,110,100,101,114, - 46,105,110,118,97,108,105,100,97,116,101,95,99,97,99,104, - 101,115,99,2,0,0,0,0,0,0,0,3,0,0,0,2, - 0,0,0,67,0,0,0,115,59,0,0,0,124,0,0,106, - 0,0,124,1,0,131,1,0,125,2,0,124,2,0,100,1, - 0,107,8,0,114,37,0,100,1,0,103,0,0,102,2,0, - 83,124,2,0,106,1,0,124,2,0,106,2,0,112,55,0, - 103,0,0,102,2,0,83,41,2,122,197,84,114,121,32,116, - 111,32,102,105,110,100,32,97,32,108,111,97,100,101,114,32, - 102,111,114,32,116,104,101,32,115,112,101,99,105,102,105,101, - 100,32,109,111,100,117,108,101,44,32,111,114,32,116,104,101, - 32,110,97,109,101,115,112,97,99,101,10,32,32,32,32,32, - 32,32,32,112,97,99,107,97,103,101,32,112,111,114,116,105, - 111,110,115,46,32,82,101,116,117,114,110,115,32,40,108,111, - 97,100,101,114,44,32,108,105,115,116,45,111,102,45,112,111, - 114,116,105,111,110,115,41,46,10,10,32,32,32,32,32,32, - 32,32,84,104,105,115,32,109,101,116,104,111,100,32,105,115, - 32,100,101,112,114,101,99,97,116,101,100,46,32,32,85,115, - 101,32,102,105,110,100,95,115,112,101,99,40,41,32,105,110, - 115,116,101,97,100,46,10,10,32,32,32,32,32,32,32,32, - 78,41,3,114,182,0,0,0,114,129,0,0,0,114,158,0, - 0,0,41,3,114,110,0,0,0,114,128,0,0,0,114,166, - 0,0,0,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,114,126,0,0,0,182,4,0,0,115,8,0,0,0, - 0,7,15,1,12,1,10,1,122,22,70,105,108,101,70,105, - 110,100,101,114,46,102,105,110,100,95,108,111,97,100,101,114, - 99,6,0,0,0,0,0,0,0,7,0,0,0,7,0,0, - 0,67,0,0,0,115,40,0,0,0,124,1,0,124,2,0, - 124,3,0,131,2,0,125,6,0,116,0,0,124,2,0,124, - 3,0,100,1,0,124,6,0,100,2,0,124,4,0,131,2, - 2,83,41,3,78,114,129,0,0,0,114,158,0,0,0,41, - 1,114,169,0,0,0,41,7,114,110,0,0,0,114,167,0, - 0,0,114,128,0,0,0,114,37,0,0,0,90,4,115,109, - 115,108,114,181,0,0,0,114,129,0,0,0,114,4,0,0, - 0,114,4,0,0,0,114,6,0,0,0,114,6,1,0,0, - 194,4,0,0,115,6,0,0,0,0,1,15,1,18,1,122, - 20,70,105,108,101,70,105,110,100,101,114,46,95,103,101,116, - 95,115,112,101,99,78,99,3,0,0,0,0,0,0,0,14, - 0,0,0,15,0,0,0,67,0,0,0,115,234,1,0,0, - 100,1,0,125,3,0,124,1,0,106,0,0,100,2,0,131, - 1,0,100,3,0,25,125,4,0,121,34,0,116,1,0,124, - 0,0,106,2,0,112,49,0,116,3,0,106,4,0,131,0, - 0,131,1,0,106,5,0,125,5,0,87,110,24,0,4,116, - 6,0,107,10,0,114,85,0,1,1,1,100,10,0,125,5, - 0,89,110,1,0,88,124,5,0,124,0,0,106,7,0,107, - 3,0,114,120,0,124,0,0,106,8,0,131,0,0,1,124, - 5,0,124,0,0,95,7,0,116,9,0,131,0,0,114,153, - 0,124,0,0,106,10,0,125,6,0,124,4,0,106,11,0, - 131,0,0,125,7,0,110,15,0,124,0,0,106,12,0,125, - 6,0,124,4,0,125,7,0,124,7,0,124,6,0,107,6, - 0,114,45,1,116,13,0,124,0,0,106,2,0,124,4,0, - 131,2,0,125,8,0,120,100,0,124,0,0,106,14,0,68, - 93,77,0,92,2,0,125,9,0,125,10,0,100,5,0,124, - 9,0,23,125,11,0,116,13,0,124,8,0,124,11,0,131, - 2,0,125,12,0,116,15,0,124,12,0,131,1,0,114,208, - 0,124,0,0,106,16,0,124,10,0,124,1,0,124,12,0, - 124,8,0,103,1,0,124,2,0,131,5,0,83,113,208,0, - 87,116,17,0,124,8,0,131,1,0,125,3,0,120,123,0, - 124,0,0,106,14,0,68,93,112,0,92,2,0,125,9,0, - 125,10,0,116,13,0,124,0,0,106,2,0,124,4,0,124, - 9,0,23,131,2,0,125,12,0,116,18,0,100,6,0,106, - 19,0,124,12,0,131,1,0,100,7,0,100,3,0,131,1, - 1,1,124,7,0,124,9,0,23,124,6,0,107,6,0,114, - 55,1,116,15,0,124,12,0,131,1,0,114,55,1,124,0, - 0,106,16,0,124,10,0,124,1,0,124,12,0,100,8,0, - 124,2,0,131,5,0,83,113,55,1,87,124,3,0,114,230, - 1,116,18,0,100,9,0,106,19,0,124,8,0,131,1,0, - 131,1,0,1,116,20,0,106,21,0,124,1,0,100,8,0, - 131,2,0,125,13,0,124,8,0,103,1,0,124,13,0,95, - 22,0,124,13,0,83,100,8,0,83,41,11,122,102,84,114, - 121,32,116,111,32,102,105,110,100,32,97,32,115,112,101,99, - 32,102,111,114,32,116,104,101,32,115,112,101,99,105,102,105, - 101,100,32,109,111,100,117,108,101,46,32,32,82,101,116,117, - 114,110,115,32,116,104,101,10,32,32,32,32,32,32,32,32, - 109,97,116,99,104,105,110,103,32,115,112,101,99,44,32,111, - 114,32,78,111,110,101,32,105,102,32,110,111,116,32,102,111, - 117,110,100,46,70,114,60,0,0,0,114,58,0,0,0,114, - 31,0,0,0,114,186,0,0,0,122,9,116,114,121,105,110, - 103,32,123,125,114,100,0,0,0,78,122,25,112,111,115,115, - 105,98,108,101,32,110,97,109,101,115,112,97,99,101,32,102, - 111,114,32,123,125,114,89,0,0,0,41,23,114,34,0,0, - 0,114,41,0,0,0,114,37,0,0,0,114,3,0,0,0, - 114,47,0,0,0,114,220,0,0,0,114,42,0,0,0,114, - 9,1,0,0,218,11,95,102,105,108,108,95,99,97,99,104, - 101,114,7,0,0,0,114,12,1,0,0,114,90,0,0,0, - 114,11,1,0,0,114,30,0,0,0,114,8,1,0,0,114, - 46,0,0,0,114,6,1,0,0,114,48,0,0,0,114,107, - 0,0,0,114,49,0,0,0,114,123,0,0,0,114,162,0, - 0,0,114,158,0,0,0,41,14,114,110,0,0,0,114,128, - 0,0,0,114,181,0,0,0,90,12,105,115,95,110,97,109, - 101,115,112,97,99,101,90,11,116,97,105,108,95,109,111,100, - 117,108,101,114,135,0,0,0,90,5,99,97,99,104,101,90, - 12,99,97,99,104,101,95,109,111,100,117,108,101,90,9,98, - 97,115,101,95,112,97,116,104,114,226,0,0,0,114,167,0, - 0,0,90,13,105,110,105,116,95,102,105,108,101,110,97,109, - 101,90,9,102,117,108,108,95,112,97,116,104,114,166,0,0, + 46,10,10,32,32,32,32,32,32,32,32,84,104,105,115,32, + 109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,46,32,32,85,115,101,32,102,105,110,100,95, + 115,112,101,99,40,41,32,105,110,115,116,101,97,100,46,10, + 10,32,32,32,32,32,32,32,32,78,41,2,114,183,0,0, + 0,114,129,0,0,0,41,4,114,173,0,0,0,114,128,0, + 0,0,114,37,0,0,0,114,167,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,114,184,0,0,0, + 163,4,0,0,115,8,0,0,0,0,8,18,1,12,1,4, + 1,122,22,80,97,116,104,70,105,110,100,101,114,46,102,105, + 110,100,95,109,111,100,117,108,101,41,12,114,114,0,0,0, + 114,113,0,0,0,114,115,0,0,0,114,116,0,0,0,114, + 185,0,0,0,114,252,0,0,0,114,1,1,0,0,114,3, + 1,0,0,114,4,1,0,0,114,7,1,0,0,114,183,0, + 0,0,114,184,0,0,0,114,4,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,114,251,0,0,0, + 43,4,0,0,115,22,0,0,0,12,2,6,2,18,8,18, + 17,18,22,18,15,3,1,18,31,3,1,21,21,3,1,114, + 251,0,0,0,99,0,0,0,0,0,0,0,0,0,0,0, + 0,3,0,0,0,64,0,0,0,115,133,0,0,0,101,0, + 0,90,1,0,100,0,0,90,2,0,100,1,0,90,3,0, + 100,2,0,100,3,0,132,0,0,90,4,0,100,4,0,100, + 5,0,132,0,0,90,5,0,101,6,0,90,7,0,100,6, + 0,100,7,0,132,0,0,90,8,0,100,8,0,100,9,0, + 132,0,0,90,9,0,100,10,0,100,11,0,100,12,0,132, + 1,0,90,10,0,100,13,0,100,14,0,132,0,0,90,11, + 0,101,12,0,100,15,0,100,16,0,132,0,0,131,1,0, + 90,13,0,100,17,0,100,18,0,132,0,0,90,14,0,100, + 10,0,83,41,19,218,10,70,105,108,101,70,105,110,100,101, + 114,122,172,70,105,108,101,45,98,97,115,101,100,32,102,105, + 110,100,101,114,46,10,10,32,32,32,32,73,110,116,101,114, + 97,99,116,105,111,110,115,32,119,105,116,104,32,116,104,101, + 32,102,105,108,101,32,115,121,115,116,101,109,32,97,114,101, + 32,99,97,99,104,101,100,32,102,111,114,32,112,101,114,102, + 111,114,109,97,110,99,101,44,32,98,101,105,110,103,10,32, + 32,32,32,114,101,102,114,101,115,104,101,100,32,119,104,101, + 110,32,116,104,101,32,100,105,114,101,99,116,111,114,121,32, + 116,104,101,32,102,105,110,100,101,114,32,105,115,32,104,97, + 110,100,108,105,110,103,32,104,97,115,32,98,101,101,110,32, + 109,111,100,105,102,105,101,100,46,10,10,32,32,32,32,99, + 2,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0, + 7,0,0,0,115,122,0,0,0,103,0,0,125,3,0,120, + 52,0,124,2,0,68,93,44,0,92,2,0,137,0,0,125, + 4,0,124,3,0,106,0,0,135,0,0,102,1,0,100,1, + 0,100,2,0,134,0,0,124,4,0,68,131,1,0,131,1, + 0,1,113,13,0,87,124,3,0,124,0,0,95,1,0,124, + 1,0,112,79,0,100,3,0,124,0,0,95,2,0,100,6, + 0,124,0,0,95,3,0,116,4,0,131,0,0,124,0,0, + 95,5,0,116,4,0,131,0,0,124,0,0,95,6,0,100, + 5,0,83,41,7,122,154,73,110,105,116,105,97,108,105,122, + 101,32,119,105,116,104,32,116,104,101,32,112,97,116,104,32, + 116,111,32,115,101,97,114,99,104,32,111,110,32,97,110,100, + 32,97,32,118,97,114,105,97,98,108,101,32,110,117,109,98, + 101,114,32,111,102,10,32,32,32,32,32,32,32,32,50,45, + 116,117,112,108,101,115,32,99,111,110,116,97,105,110,105,110, + 103,32,116,104,101,32,108,111,97,100,101,114,32,97,110,100, + 32,116,104,101,32,102,105,108,101,32,115,117,102,102,105,120, + 101,115,32,116,104,101,32,108,111,97,100,101,114,10,32,32, + 32,32,32,32,32,32,114,101,99,111,103,110,105,122,101,115, + 46,99,1,0,0,0,0,0,0,0,2,0,0,0,3,0, + 0,0,51,0,0,0,115,27,0,0,0,124,0,0,93,17, + 0,125,1,0,124,1,0,136,0,0,102,2,0,86,1,113, + 3,0,100,0,0,83,41,1,78,114,4,0,0,0,41,2, + 114,24,0,0,0,114,227,0,0,0,41,1,114,129,0,0, + 0,114,4,0,0,0,114,6,0,0,0,114,229,0,0,0, + 192,4,0,0,115,2,0,0,0,6,0,122,38,70,105,108, + 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, + 46,60,108,111,99,97,108,115,62,46,60,103,101,110,101,120, + 112,114,62,114,60,0,0,0,114,31,0,0,0,78,114,89, + 0,0,0,41,7,114,152,0,0,0,218,8,95,108,111,97, + 100,101,114,115,114,37,0,0,0,218,11,95,112,97,116,104, + 95,109,116,105,109,101,218,3,115,101,116,218,11,95,112,97, + 116,104,95,99,97,99,104,101,218,19,95,114,101,108,97,120, + 101,100,95,112,97,116,104,95,99,97,99,104,101,41,5,114, + 110,0,0,0,114,37,0,0,0,218,14,108,111,97,100,101, + 114,95,100,101,116,97,105,108,115,90,7,108,111,97,100,101, + 114,115,114,169,0,0,0,114,4,0,0,0,41,1,114,129, + 0,0,0,114,6,0,0,0,114,187,0,0,0,186,4,0, + 0,115,16,0,0,0,0,4,6,1,19,1,36,1,9,2, + 15,1,9,1,12,1,122,19,70,105,108,101,70,105,110,100, + 101,114,46,95,95,105,110,105,116,95,95,99,1,0,0,0, + 0,0,0,0,1,0,0,0,2,0,0,0,67,0,0,0, + 115,13,0,0,0,100,3,0,124,0,0,95,0,0,100,2, + 0,83,41,4,122,31,73,110,118,97,108,105,100,97,116,101, + 32,116,104,101,32,100,105,114,101,99,116,111,114,121,32,109, + 116,105,109,101,46,114,31,0,0,0,78,114,89,0,0,0, + 41,1,114,10,1,0,0,41,1,114,110,0,0,0,114,4, + 0,0,0,114,4,0,0,0,114,6,0,0,0,114,252,0, + 0,0,200,4,0,0,115,2,0,0,0,0,2,122,28,70, + 105,108,101,70,105,110,100,101,114,46,105,110,118,97,108,105, + 100,97,116,101,95,99,97,99,104,101,115,99,2,0,0,0, + 0,0,0,0,3,0,0,0,2,0,0,0,67,0,0,0, + 115,59,0,0,0,124,0,0,106,0,0,124,1,0,131,1, + 0,125,2,0,124,2,0,100,1,0,107,8,0,114,37,0, + 100,1,0,103,0,0,102,2,0,83,124,2,0,106,1,0, + 124,2,0,106,2,0,112,55,0,103,0,0,102,2,0,83, + 41,2,122,197,84,114,121,32,116,111,32,102,105,110,100,32, + 97,32,108,111,97,100,101,114,32,102,111,114,32,116,104,101, + 32,115,112,101,99,105,102,105,101,100,32,109,111,100,117,108, + 101,44,32,111,114,32,116,104,101,32,110,97,109,101,115,112, + 97,99,101,10,32,32,32,32,32,32,32,32,112,97,99,107, + 97,103,101,32,112,111,114,116,105,111,110,115,46,32,82,101, + 116,117,114,110,115,32,40,108,111,97,100,101,114,44,32,108, + 105,115,116,45,111,102,45,112,111,114,116,105,111,110,115,41, + 46,10,10,32,32,32,32,32,32,32,32,84,104,105,115,32, + 109,101,116,104,111,100,32,105,115,32,100,101,112,114,101,99, + 97,116,101,100,46,32,32,85,115,101,32,102,105,110,100,95, + 115,112,101,99,40,41,32,105,110,115,116,101,97,100,46,10, + 10,32,32,32,32,32,32,32,32,78,41,3,114,183,0,0, + 0,114,129,0,0,0,114,159,0,0,0,41,3,114,110,0, + 0,0,114,128,0,0,0,114,167,0,0,0,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,114,126,0,0,0, + 206,4,0,0,115,8,0,0,0,0,7,15,1,12,1,10, + 1,122,22,70,105,108,101,70,105,110,100,101,114,46,102,105, + 110,100,95,108,111,97,100,101,114,99,6,0,0,0,0,0, + 0,0,7,0,0,0,7,0,0,0,67,0,0,0,115,40, + 0,0,0,124,1,0,124,2,0,124,3,0,131,2,0,125, + 6,0,116,0,0,124,2,0,124,3,0,100,1,0,124,6, + 0,100,2,0,124,4,0,131,2,2,83,41,3,78,114,129, + 0,0,0,114,159,0,0,0,41,1,114,170,0,0,0,41, + 7,114,110,0,0,0,114,168,0,0,0,114,128,0,0,0, + 114,37,0,0,0,90,4,115,109,115,108,114,182,0,0,0, + 114,129,0,0,0,114,4,0,0,0,114,4,0,0,0,114, + 6,0,0,0,114,7,1,0,0,218,4,0,0,115,6,0, + 0,0,0,1,15,1,18,1,122,20,70,105,108,101,70,105, + 110,100,101,114,46,95,103,101,116,95,115,112,101,99,78,99, + 3,0,0,0,0,0,0,0,14,0,0,0,15,0,0,0, + 67,0,0,0,115,234,1,0,0,100,1,0,125,3,0,124, + 1,0,106,0,0,100,2,0,131,1,0,100,3,0,25,125, + 4,0,121,34,0,116,1,0,124,0,0,106,2,0,112,49, + 0,116,3,0,106,4,0,131,0,0,131,1,0,106,5,0, + 125,5,0,87,110,24,0,4,116,6,0,107,10,0,114,85, + 0,1,1,1,100,10,0,125,5,0,89,110,1,0,88,124, + 5,0,124,0,0,106,7,0,107,3,0,114,120,0,124,0, + 0,106,8,0,131,0,0,1,124,5,0,124,0,0,95,7, + 0,116,9,0,131,0,0,114,153,0,124,0,0,106,10,0, + 125,6,0,124,4,0,106,11,0,131,0,0,125,7,0,110, + 15,0,124,0,0,106,12,0,125,6,0,124,4,0,125,7, + 0,124,7,0,124,6,0,107,6,0,114,45,1,116,13,0, + 124,0,0,106,2,0,124,4,0,131,2,0,125,8,0,120, + 100,0,124,0,0,106,14,0,68,93,77,0,92,2,0,125, + 9,0,125,10,0,100,5,0,124,9,0,23,125,11,0,116, + 13,0,124,8,0,124,11,0,131,2,0,125,12,0,116,15, + 0,124,12,0,131,1,0,114,208,0,124,0,0,106,16,0, + 124,10,0,124,1,0,124,12,0,124,8,0,103,1,0,124, + 2,0,131,5,0,83,113,208,0,87,116,17,0,124,8,0, + 131,1,0,125,3,0,120,123,0,124,0,0,106,14,0,68, + 93,112,0,92,2,0,125,9,0,125,10,0,116,13,0,124, + 0,0,106,2,0,124,4,0,124,9,0,23,131,2,0,125, + 12,0,116,18,0,100,6,0,106,19,0,124,12,0,131,1, + 0,100,7,0,100,3,0,131,1,1,1,124,7,0,124,9, + 0,23,124,6,0,107,6,0,114,55,1,116,15,0,124,12, + 0,131,1,0,114,55,1,124,0,0,106,16,0,124,10,0, + 124,1,0,124,12,0,100,8,0,124,2,0,131,5,0,83, + 113,55,1,87,124,3,0,114,230,1,116,18,0,100,9,0, + 106,19,0,124,8,0,131,1,0,131,1,0,1,116,20,0, + 106,21,0,124,1,0,100,8,0,131,2,0,125,13,0,124, + 8,0,103,1,0,124,13,0,95,22,0,124,13,0,83,100, + 8,0,83,41,11,122,102,84,114,121,32,116,111,32,102,105, + 110,100,32,97,32,115,112,101,99,32,102,111,114,32,116,104, + 101,32,115,112,101,99,105,102,105,101,100,32,109,111,100,117, + 108,101,46,32,32,82,101,116,117,114,110,115,32,116,104,101, + 10,32,32,32,32,32,32,32,32,109,97,116,99,104,105,110, + 103,32,115,112,101,99,44,32,111,114,32,78,111,110,101,32, + 105,102,32,110,111,116,32,102,111,117,110,100,46,70,114,60, + 0,0,0,114,58,0,0,0,114,31,0,0,0,114,187,0, + 0,0,122,9,116,114,121,105,110,103,32,123,125,114,100,0, + 0,0,78,122,25,112,111,115,115,105,98,108,101,32,110,97, + 109,101,115,112,97,99,101,32,102,111,114,32,123,125,114,89, + 0,0,0,41,23,114,34,0,0,0,114,41,0,0,0,114, + 37,0,0,0,114,3,0,0,0,114,47,0,0,0,114,221, + 0,0,0,114,42,0,0,0,114,10,1,0,0,218,11,95, + 102,105,108,108,95,99,97,99,104,101,114,7,0,0,0,114, + 13,1,0,0,114,90,0,0,0,114,12,1,0,0,114,30, + 0,0,0,114,9,1,0,0,114,46,0,0,0,114,7,1, + 0,0,114,48,0,0,0,114,107,0,0,0,114,49,0,0, + 0,114,123,0,0,0,114,163,0,0,0,114,159,0,0,0, + 41,14,114,110,0,0,0,114,128,0,0,0,114,182,0,0, + 0,90,12,105,115,95,110,97,109,101,115,112,97,99,101,90, + 11,116,97,105,108,95,109,111,100,117,108,101,114,135,0,0, + 0,90,5,99,97,99,104,101,90,12,99,97,99,104,101,95, + 109,111,100,117,108,101,90,9,98,97,115,101,95,112,97,116, + 104,114,227,0,0,0,114,168,0,0,0,90,13,105,110,105, + 116,95,102,105,108,101,110,97,109,101,90,9,102,117,108,108, + 95,112,97,116,104,114,167,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,6,0,0,0,114,183,0,0,0,223,4, + 0,0,115,68,0,0,0,0,3,6,1,19,1,3,1,34, + 1,13,1,11,1,15,1,10,1,9,2,9,1,9,1,15, + 2,9,1,6,2,12,1,18,1,22,1,10,1,15,1,12, + 1,32,4,12,2,22,1,22,1,25,1,16,1,12,1,29, + 1,6,1,19,1,18,1,12,1,4,1,122,20,70,105,108, + 101,70,105,110,100,101,114,46,102,105,110,100,95,115,112,101, + 99,99,1,0,0,0,0,0,0,0,9,0,0,0,13,0, + 0,0,67,0,0,0,115,11,1,0,0,124,0,0,106,0, + 0,125,1,0,121,31,0,116,1,0,106,2,0,124,1,0, + 112,33,0,116,1,0,106,3,0,131,0,0,131,1,0,125, + 2,0,87,110,33,0,4,116,4,0,116,5,0,116,6,0, + 102,3,0,107,10,0,114,75,0,1,1,1,103,0,0,125, + 2,0,89,110,1,0,88,116,7,0,106,8,0,106,9,0, + 100,1,0,131,1,0,115,112,0,116,10,0,124,2,0,131, + 1,0,124,0,0,95,11,0,110,111,0,116,10,0,131,0, + 0,125,3,0,120,90,0,124,2,0,68,93,82,0,125,4, + 0,124,4,0,106,12,0,100,2,0,131,1,0,92,3,0, + 125,5,0,125,6,0,125,7,0,124,6,0,114,191,0,100, + 3,0,106,13,0,124,5,0,124,7,0,106,14,0,131,0, + 0,131,2,0,125,8,0,110,6,0,124,5,0,125,8,0, + 124,3,0,106,15,0,124,8,0,131,1,0,1,113,128,0, + 87,124,3,0,124,0,0,95,11,0,116,7,0,106,8,0, + 106,9,0,116,16,0,131,1,0,114,7,1,100,4,0,100, + 5,0,132,0,0,124,2,0,68,131,1,0,124,0,0,95, + 17,0,100,6,0,83,41,7,122,68,70,105,108,108,32,116, + 104,101,32,99,97,99,104,101,32,111,102,32,112,111,116,101, + 110,116,105,97,108,32,109,111,100,117,108,101,115,32,97,110, + 100,32,112,97,99,107,97,103,101,115,32,102,111,114,32,116, + 104,105,115,32,100,105,114,101,99,116,111,114,121,46,114,0, + 0,0,0,114,60,0,0,0,122,5,123,125,46,123,125,99, + 1,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0, + 83,0,0,0,115,28,0,0,0,104,0,0,124,0,0,93, + 18,0,125,1,0,124,1,0,106,0,0,131,0,0,146,2, + 0,113,6,0,83,114,4,0,0,0,41,1,114,90,0,0, + 0,41,2,114,24,0,0,0,90,2,102,110,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,250,9,60,115,101, + 116,99,111,109,112,62,41,5,0,0,115,2,0,0,0,9, + 0,122,41,70,105,108,101,70,105,110,100,101,114,46,95,102, + 105,108,108,95,99,97,99,104,101,46,60,108,111,99,97,108, + 115,62,46,60,115,101,116,99,111,109,112,62,78,41,18,114, + 37,0,0,0,114,3,0,0,0,90,7,108,105,115,116,100, + 105,114,114,47,0,0,0,114,2,1,0,0,218,15,80,101, + 114,109,105,115,115,105,111,110,69,114,114,111,114,218,18,78, + 111,116,65,68,105,114,101,99,116,111,114,121,69,114,114,111, + 114,114,8,0,0,0,114,9,0,0,0,114,10,0,0,0, + 114,11,1,0,0,114,12,1,0,0,114,85,0,0,0,114, + 49,0,0,0,114,90,0,0,0,218,3,97,100,100,114,11, + 0,0,0,114,13,1,0,0,41,9,114,110,0,0,0,114, + 37,0,0,0,90,8,99,111,110,116,101,110,116,115,90,21, + 108,111,119,101,114,95,115,117,102,102,105,120,95,99,111,110, + 116,101,110,116,115,114,247,0,0,0,114,108,0,0,0,114, + 239,0,0,0,114,227,0,0,0,90,8,110,101,119,95,110, + 97,109,101,114,4,0,0,0,114,4,0,0,0,114,6,0, + 0,0,114,15,1,0,0,12,5,0,0,115,34,0,0,0, + 0,2,9,1,3,1,31,1,22,3,11,3,18,1,18,7, + 9,1,13,1,24,1,6,1,27,2,6,1,17,1,9,1, + 18,1,122,22,70,105,108,101,70,105,110,100,101,114,46,95, + 102,105,108,108,95,99,97,99,104,101,99,1,0,0,0,0, + 0,0,0,3,0,0,0,3,0,0,0,7,0,0,0,115, + 25,0,0,0,135,0,0,135,1,0,102,2,0,100,1,0, + 100,2,0,134,0,0,125,2,0,124,2,0,83,41,3,97, + 20,1,0,0,65,32,99,108,97,115,115,32,109,101,116,104, + 111,100,32,119,104,105,99,104,32,114,101,116,117,114,110,115, + 32,97,32,99,108,111,115,117,114,101,32,116,111,32,117,115, + 101,32,111,110,32,115,121,115,46,112,97,116,104,95,104,111, + 111,107,10,32,32,32,32,32,32,32,32,119,104,105,99,104, + 32,119,105,108,108,32,114,101,116,117,114,110,32,97,110,32, + 105,110,115,116,97,110,99,101,32,117,115,105,110,103,32,116, + 104,101,32,115,112,101,99,105,102,105,101,100,32,108,111,97, + 100,101,114,115,32,97,110,100,32,116,104,101,32,112,97,116, + 104,10,32,32,32,32,32,32,32,32,99,97,108,108,101,100, + 32,111,110,32,116,104,101,32,99,108,111,115,117,114,101,46, + 10,10,32,32,32,32,32,32,32,32,73,102,32,116,104,101, + 32,112,97,116,104,32,99,97,108,108,101,100,32,111,110,32, + 116,104,101,32,99,108,111,115,117,114,101,32,105,115,32,110, + 111,116,32,97,32,100,105,114,101,99,116,111,114,121,44,32, + 73,109,112,111,114,116,69,114,114,111,114,32,105,115,10,32, + 32,32,32,32,32,32,32,114,97,105,115,101,100,46,10,10, + 32,32,32,32,32,32,32,32,99,1,0,0,0,0,0,0, + 0,1,0,0,0,4,0,0,0,19,0,0,0,115,43,0, + 0,0,116,0,0,124,0,0,131,1,0,115,30,0,116,1, + 0,100,1,0,100,2,0,124,0,0,131,1,1,130,1,0, + 136,0,0,124,0,0,136,1,0,140,1,0,83,41,3,122, + 45,80,97,116,104,32,104,111,111,107,32,102,111,114,32,105, + 109,112,111,114,116,108,105,98,46,109,97,99,104,105,110,101, + 114,121,46,70,105,108,101,70,105,110,100,101,114,46,122,30, + 111,110,108,121,32,100,105,114,101,99,116,111,114,105,101,115, + 32,97,114,101,32,115,117,112,112,111,114,116,101,100,114,37, + 0,0,0,41,2,114,48,0,0,0,114,109,0,0,0,41, + 1,114,37,0,0,0,41,2,114,173,0,0,0,114,14,1, + 0,0,114,4,0,0,0,114,6,0,0,0,218,24,112,97, + 116,104,95,104,111,111,107,95,102,111,114,95,70,105,108,101, + 70,105,110,100,101,114,53,5,0,0,115,6,0,0,0,0, + 2,12,1,18,1,122,54,70,105,108,101,70,105,110,100,101, + 114,46,112,97,116,104,95,104,111,111,107,46,60,108,111,99, + 97,108,115,62,46,112,97,116,104,95,104,111,111,107,95,102, + 111,114,95,70,105,108,101,70,105,110,100,101,114,114,4,0, + 0,0,41,3,114,173,0,0,0,114,14,1,0,0,114,20, + 1,0,0,114,4,0,0,0,41,2,114,173,0,0,0,114, + 14,1,0,0,114,6,0,0,0,218,9,112,97,116,104,95, + 104,111,111,107,43,5,0,0,115,4,0,0,0,0,10,21, + 6,122,20,70,105,108,101,70,105,110,100,101,114,46,112,97, + 116,104,95,104,111,111,107,99,1,0,0,0,0,0,0,0, + 1,0,0,0,2,0,0,0,67,0,0,0,115,16,0,0, + 0,100,1,0,106,0,0,124,0,0,106,1,0,131,1,0, + 83,41,2,78,122,16,70,105,108,101,70,105,110,100,101,114, + 40,123,33,114,125,41,41,2,114,49,0,0,0,114,37,0, + 0,0,41,1,114,110,0,0,0,114,4,0,0,0,114,4, + 0,0,0,114,6,0,0,0,114,246,0,0,0,61,5,0, + 0,115,2,0,0,0,0,1,122,19,70,105,108,101,70,105, + 110,100,101,114,46,95,95,114,101,112,114,95,95,41,15,114, + 114,0,0,0,114,113,0,0,0,114,115,0,0,0,114,116, + 0,0,0,114,187,0,0,0,114,252,0,0,0,114,132,0, + 0,0,114,184,0,0,0,114,126,0,0,0,114,7,1,0, + 0,114,183,0,0,0,114,15,1,0,0,114,185,0,0,0, + 114,21,1,0,0,114,246,0,0,0,114,4,0,0,0,114, + 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,8, + 1,0,0,177,4,0,0,115,20,0,0,0,12,7,6,2, + 12,14,12,4,6,2,12,12,12,5,15,45,12,31,18,18, + 114,8,1,0,0,99,4,0,0,0,0,0,0,0,6,0, + 0,0,11,0,0,0,67,0,0,0,115,195,0,0,0,124, + 0,0,106,0,0,100,1,0,131,1,0,125,4,0,124,0, + 0,106,0,0,100,2,0,131,1,0,125,5,0,124,4,0, + 115,99,0,124,5,0,114,54,0,124,5,0,106,1,0,125, + 4,0,110,45,0,124,2,0,124,3,0,107,2,0,114,84, + 0,116,2,0,124,1,0,124,2,0,131,2,0,125,4,0, + 110,15,0,116,3,0,124,1,0,124,2,0,131,2,0,125, + 4,0,124,5,0,115,126,0,116,4,0,124,1,0,124,2, + 0,100,3,0,124,4,0,131,2,1,125,5,0,121,44,0, + 124,5,0,124,0,0,100,2,0,60,124,4,0,124,0,0, + 100,1,0,60,124,2,0,124,0,0,100,4,0,60,124,3, + 0,124,0,0,100,5,0,60,87,110,18,0,4,116,5,0, + 107,10,0,114,190,0,1,1,1,89,110,1,0,88,100,0, + 0,83,41,6,78,218,10,95,95,108,111,97,100,101,114,95, + 95,218,8,95,95,115,112,101,99,95,95,114,129,0,0,0, + 90,8,95,95,102,105,108,101,95,95,90,10,95,95,99,97, + 99,104,101,100,95,95,41,6,218,3,103,101,116,114,129,0, + 0,0,114,225,0,0,0,114,220,0,0,0,114,170,0,0, + 0,218,9,69,120,99,101,112,116,105,111,110,41,6,90,2, + 110,115,114,108,0,0,0,90,8,112,97,116,104,110,97,109, + 101,90,9,99,112,97,116,104,110,97,109,101,114,129,0,0, + 0,114,167,0,0,0,114,4,0,0,0,114,4,0,0,0, + 114,6,0,0,0,218,14,95,102,105,120,95,117,112,95,109, + 111,100,117,108,101,67,5,0,0,115,34,0,0,0,0,2, + 15,1,15,1,6,1,6,1,12,1,12,1,18,2,15,1, + 6,1,21,1,3,1,10,1,10,1,10,1,14,1,13,2, + 114,26,1,0,0,99,0,0,0,0,0,0,0,0,3,0, + 0,0,3,0,0,0,67,0,0,0,115,55,0,0,0,116, + 0,0,116,1,0,106,2,0,131,0,0,102,2,0,125,0, + 0,116,3,0,116,4,0,102,2,0,125,1,0,116,5,0, + 116,6,0,102,2,0,125,2,0,124,0,0,124,1,0,124, + 2,0,103,3,0,83,41,1,122,95,82,101,116,117,114,110, + 115,32,97,32,108,105,115,116,32,111,102,32,102,105,108,101, + 45,98,97,115,101,100,32,109,111,100,117,108,101,32,108,111, + 97,100,101,114,115,46,10,10,32,32,32,32,69,97,99,104, + 32,105,116,101,109,32,105,115,32,97,32,116,117,112,108,101, + 32,40,108,111,97,100,101,114,44,32,115,117,102,102,105,120, + 101,115,41,46,10,32,32,32,32,41,7,114,226,0,0,0, + 114,148,0,0,0,218,18,101,120,116,101,110,115,105,111,110, + 95,115,117,102,102,105,120,101,115,114,220,0,0,0,114,86, + 0,0,0,114,225,0,0,0,114,76,0,0,0,41,3,90, + 10,101,120,116,101,110,115,105,111,110,115,90,6,115,111,117, + 114,99,101,90,8,98,121,116,101,99,111,100,101,114,4,0, + 0,0,114,4,0,0,0,114,6,0,0,0,114,164,0,0, + 0,90,5,0,0,115,8,0,0,0,0,5,18,1,12,1, + 12,1,114,164,0,0,0,99,1,0,0,0,0,0,0,0, + 12,0,0,0,12,0,0,0,67,0,0,0,115,70,2,0, + 0,124,0,0,97,0,0,116,0,0,106,1,0,97,1,0, + 116,0,0,106,2,0,97,2,0,116,1,0,106,3,0,116, + 4,0,25,125,1,0,120,76,0,100,26,0,68,93,68,0, + 125,2,0,124,2,0,116,1,0,106,3,0,107,7,0,114, + 83,0,116,0,0,106,5,0,124,2,0,131,1,0,125,3, + 0,110,13,0,116,1,0,106,3,0,124,2,0,25,125,3, + 0,116,6,0,124,1,0,124,2,0,124,3,0,131,3,0, + 1,113,44,0,87,100,5,0,100,6,0,103,1,0,102,2, + 0,100,7,0,100,8,0,100,6,0,103,2,0,102,2,0, + 102,2,0,125,4,0,120,149,0,124,4,0,68,93,129,0, + 92,2,0,125,5,0,125,6,0,116,7,0,100,9,0,100, + 10,0,132,0,0,124,6,0,68,131,1,0,131,1,0,115, + 199,0,116,8,0,130,1,0,124,6,0,100,11,0,25,125, + 7,0,124,5,0,116,1,0,106,3,0,107,6,0,114,241, + 0,116,1,0,106,3,0,124,5,0,25,125,8,0,80,113, + 156,0,121,20,0,116,0,0,106,5,0,124,5,0,131,1, + 0,125,8,0,80,87,113,156,0,4,116,9,0,107,10,0, + 114,28,1,1,1,1,119,156,0,89,113,156,0,88,113,156, + 0,87,116,9,0,100,12,0,131,1,0,130,1,0,116,6, + 0,124,1,0,100,13,0,124,8,0,131,3,0,1,116,6, + 0,124,1,0,100,14,0,124,7,0,131,3,0,1,116,6, + 0,124,1,0,100,15,0,100,16,0,106,10,0,124,6,0, + 131,1,0,131,3,0,1,121,19,0,116,0,0,106,5,0, + 100,17,0,131,1,0,125,9,0,87,110,24,0,4,116,9, + 0,107,10,0,114,147,1,1,1,1,100,18,0,125,9,0, + 89,110,1,0,88,116,6,0,124,1,0,100,17,0,124,9, + 0,131,3,0,1,116,0,0,106,5,0,100,19,0,131,1, + 0,125,10,0,116,6,0,124,1,0,100,19,0,124,10,0, + 131,3,0,1,124,5,0,100,7,0,107,2,0,114,238,1, + 116,0,0,106,5,0,100,20,0,131,1,0,125,11,0,116, + 6,0,124,1,0,100,21,0,124,11,0,131,3,0,1,116, + 6,0,124,1,0,100,22,0,116,11,0,131,0,0,131,3, + 0,1,116,12,0,106,13,0,116,2,0,106,14,0,131,0, + 0,131,1,0,1,124,5,0,100,7,0,107,2,0,114,66, + 2,116,15,0,106,16,0,100,23,0,131,1,0,1,100,24, + 0,116,12,0,107,6,0,114,66,2,100,25,0,116,17,0, + 95,18,0,100,18,0,83,41,27,122,205,83,101,116,117,112, + 32,116,104,101,32,112,97,116,104,45,98,97,115,101,100,32, + 105,109,112,111,114,116,101,114,115,32,102,111,114,32,105,109, + 112,111,114,116,108,105,98,32,98,121,32,105,109,112,111,114, + 116,105,110,103,32,110,101,101,100,101,100,10,32,32,32,32, + 98,117,105,108,116,45,105,110,32,109,111,100,117,108,101,115, + 32,97,110,100,32,105,110,106,101,99,116,105,110,103,32,116, + 104,101,109,32,105,110,116,111,32,116,104,101,32,103,108,111, + 98,97,108,32,110,97,109,101,115,112,97,99,101,46,10,10, + 32,32,32,32,79,116,104,101,114,32,99,111,109,112,111,110, + 101,110,116,115,32,97,114,101,32,101,120,116,114,97,99,116, + 101,100,32,102,114,111,109,32,116,104,101,32,99,111,114,101, + 32,98,111,111,116,115,116,114,97,112,32,109,111,100,117,108, + 101,46,10,10,32,32,32,32,114,51,0,0,0,114,62,0, + 0,0,218,8,98,117,105,108,116,105,110,115,114,145,0,0, + 0,90,5,112,111,115,105,120,250,1,47,218,2,110,116,250, + 1,92,99,1,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,115,0,0,0,115,33,0,0,0,124,0,0,93, + 23,0,125,1,0,116,0,0,124,1,0,131,1,0,100,0, + 0,107,2,0,86,1,113,3,0,100,1,0,83,41,2,114, + 31,0,0,0,78,41,1,114,33,0,0,0,41,2,114,24, + 0,0,0,114,79,0,0,0,114,4,0,0,0,114,4,0, + 0,0,114,6,0,0,0,114,229,0,0,0,126,5,0,0, + 115,2,0,0,0,6,0,122,25,95,115,101,116,117,112,46, + 60,108,111,99,97,108,115,62,46,60,103,101,110,101,120,112, + 114,62,114,61,0,0,0,122,30,105,109,112,111,114,116,108, + 105,98,32,114,101,113,117,105,114,101,115,32,112,111,115,105, + 120,32,111,114,32,110,116,114,3,0,0,0,114,27,0,0, + 0,114,23,0,0,0,114,32,0,0,0,90,7,95,116,104, + 114,101,97,100,78,90,8,95,119,101,97,107,114,101,102,90, + 6,119,105,110,114,101,103,114,172,0,0,0,114,7,0,0, + 0,122,4,46,112,121,119,122,6,95,100,46,112,121,100,84, + 41,4,114,51,0,0,0,114,62,0,0,0,114,28,1,0, + 0,114,145,0,0,0,41,19,114,123,0,0,0,114,8,0, + 0,0,114,148,0,0,0,114,241,0,0,0,114,114,0,0, + 0,90,18,95,98,117,105,108,116,105,110,95,102,114,111,109, + 95,110,97,109,101,114,118,0,0,0,218,3,97,108,108,218, + 14,65,115,115,101,114,116,105,111,110,69,114,114,111,114,114, + 109,0,0,0,114,28,0,0,0,114,13,0,0,0,114,231, + 0,0,0,114,152,0,0,0,114,27,1,0,0,114,86,0, + 0,0,114,166,0,0,0,114,171,0,0,0,114,175,0,0, + 0,41,12,218,17,95,98,111,111,116,115,116,114,97,112,95, + 109,111,100,117,108,101,90,11,115,101,108,102,95,109,111,100, + 117,108,101,90,12,98,117,105,108,116,105,110,95,110,97,109, + 101,90,14,98,117,105,108,116,105,110,95,109,111,100,117,108, + 101,90,10,111,115,95,100,101,116,97,105,108,115,90,10,98, + 117,105,108,116,105,110,95,111,115,114,23,0,0,0,114,27, + 0,0,0,90,9,111,115,95,109,111,100,117,108,101,90,13, + 116,104,114,101,97,100,95,109,111,100,117,108,101,90,14,119, + 101,97,107,114,101,102,95,109,111,100,117,108,101,90,13,119, + 105,110,114,101,103,95,109,111,100,117,108,101,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,218,6,95,115,101, + 116,117,112,101,5,0,0,115,82,0,0,0,0,8,6,1, + 9,1,9,3,13,1,13,1,15,1,18,2,13,1,20,3, + 33,1,19,2,31,1,10,1,15,1,13,1,4,2,3,1, + 15,1,5,1,13,1,12,2,12,1,16,1,16,1,25,3, + 3,1,19,1,13,2,11,1,16,3,15,1,16,3,12,1, + 15,1,16,3,19,1,19,1,12,1,13,1,12,1,114,35, + 1,0,0,99,1,0,0,0,0,0,0,0,2,0,0,0, + 3,0,0,0,67,0,0,0,115,116,0,0,0,116,0,0, + 124,0,0,131,1,0,1,116,1,0,131,0,0,125,1,0, + 116,2,0,106,3,0,106,4,0,116,5,0,106,6,0,124, + 1,0,140,0,0,103,1,0,131,1,0,1,116,7,0,106, + 8,0,100,1,0,107,2,0,114,78,0,116,2,0,106,9, + 0,106,10,0,116,11,0,131,1,0,1,116,2,0,106,9, + 0,106,10,0,116,12,0,131,1,0,1,116,5,0,124,0, + 0,95,5,0,116,13,0,124,0,0,95,13,0,100,2,0, + 83,41,3,122,41,73,110,115,116,97,108,108,32,116,104,101, + 32,112,97,116,104,45,98,97,115,101,100,32,105,109,112,111, + 114,116,32,99,111,109,112,111,110,101,110,116,115,46,114,30, + 1,0,0,78,41,14,114,35,1,0,0,114,164,0,0,0, + 114,8,0,0,0,114,0,1,0,0,114,152,0,0,0,114, + 8,1,0,0,114,21,1,0,0,114,3,0,0,0,114,114, + 0,0,0,218,9,109,101,116,97,95,112,97,116,104,114,166, + 0,0,0,114,171,0,0,0,114,251,0,0,0,114,220,0, + 0,0,41,2,114,34,1,0,0,90,17,115,117,112,112,111, + 114,116,101,100,95,108,111,97,100,101,114,115,114,4,0,0, + 0,114,4,0,0,0,114,6,0,0,0,218,8,95,105,110, + 115,116,97,108,108,169,5,0,0,115,16,0,0,0,0,2, + 10,1,9,1,28,1,15,1,16,1,16,4,9,1,114,37, + 1,0,0,41,1,114,0,0,0,0,41,2,114,1,0,0, + 0,114,2,0,0,0,41,62,114,116,0,0,0,114,12,0, + 0,0,90,37,95,67,65,83,69,95,73,78,83,69,78,83, + 73,84,73,86,69,95,80,76,65,84,70,79,82,77,83,95, + 66,89,84,69,83,95,75,69,89,114,11,0,0,0,114,13, + 0,0,0,114,19,0,0,0,114,21,0,0,0,114,30,0, + 0,0,114,40,0,0,0,114,41,0,0,0,114,45,0,0, + 0,114,46,0,0,0,114,48,0,0,0,114,57,0,0,0, + 218,4,116,121,112,101,218,8,95,95,99,111,100,101,95,95, + 114,147,0,0,0,114,17,0,0,0,114,137,0,0,0,114, + 16,0,0,0,114,20,0,0,0,90,17,95,82,65,87,95, + 77,65,71,73,67,95,78,85,77,66,69,82,90,4,95,109, + 115,103,218,11,83,121,115,116,101,109,69,114,114,111,114,114, + 138,0,0,0,114,75,0,0,0,114,74,0,0,0,114,86, + 0,0,0,114,76,0,0,0,90,23,68,69,66,85,71,95, + 66,89,84,69,67,79,68,69,95,83,85,70,70,73,88,69, + 83,90,27,79,80,84,73,77,73,90,69,68,95,66,89,84, + 69,67,79,68,69,95,83,85,70,70,73,88,69,83,114,81, + 0,0,0,114,87,0,0,0,114,93,0,0,0,114,97,0, + 0,0,114,99,0,0,0,114,107,0,0,0,114,125,0,0, + 0,114,132,0,0,0,114,144,0,0,0,114,150,0,0,0, + 114,153,0,0,0,114,158,0,0,0,218,6,111,98,106,101, + 99,116,114,165,0,0,0,114,170,0,0,0,114,171,0,0, + 0,114,186,0,0,0,114,196,0,0,0,114,212,0,0,0, + 114,220,0,0,0,114,225,0,0,0,114,231,0,0,0,114, + 226,0,0,0,114,232,0,0,0,114,249,0,0,0,114,251, + 0,0,0,114,8,1,0,0,114,26,1,0,0,114,164,0, + 0,0,114,35,1,0,0,114,37,1,0,0,114,4,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,6,0,0,0, - 114,182,0,0,0,199,4,0,0,115,68,0,0,0,0,3, - 6,1,19,1,3,1,34,1,13,1,11,1,15,1,10,1, - 9,2,9,1,9,1,15,2,9,1,6,2,12,1,18,1, - 22,1,10,1,15,1,12,1,32,4,12,2,22,1,22,1, - 25,1,16,1,12,1,29,1,6,1,19,1,18,1,12,1, - 4,1,122,20,70,105,108,101,70,105,110,100,101,114,46,102, - 105,110,100,95,115,112,101,99,99,1,0,0,0,0,0,0, - 0,9,0,0,0,13,0,0,0,67,0,0,0,115,11,1, - 0,0,124,0,0,106,0,0,125,1,0,121,31,0,116,1, - 0,106,2,0,124,1,0,112,33,0,116,1,0,106,3,0, - 131,0,0,131,1,0,125,2,0,87,110,33,0,4,116,4, - 0,116,5,0,116,6,0,102,3,0,107,10,0,114,75,0, - 1,1,1,103,0,0,125,2,0,89,110,1,0,88,116,7, - 0,106,8,0,106,9,0,100,1,0,131,1,0,115,112,0, - 116,10,0,124,2,0,131,1,0,124,0,0,95,11,0,110, - 111,0,116,10,0,131,0,0,125,3,0,120,90,0,124,2, - 0,68,93,82,0,125,4,0,124,4,0,106,12,0,100,2, - 0,131,1,0,92,3,0,125,5,0,125,6,0,125,7,0, - 124,6,0,114,191,0,100,3,0,106,13,0,124,5,0,124, - 7,0,106,14,0,131,0,0,131,2,0,125,8,0,110,6, - 0,124,5,0,125,8,0,124,3,0,106,15,0,124,8,0, - 131,1,0,1,113,128,0,87,124,3,0,124,0,0,95,11, - 0,116,7,0,106,8,0,106,9,0,116,16,0,131,1,0, - 114,7,1,100,4,0,100,5,0,132,0,0,124,2,0,68, - 131,1,0,124,0,0,95,17,0,100,6,0,83,41,7,122, - 68,70,105,108,108,32,116,104,101,32,99,97,99,104,101,32, - 111,102,32,112,111,116,101,110,116,105,97,108,32,109,111,100, - 117,108,101,115,32,97,110,100,32,112,97,99,107,97,103,101, - 115,32,102,111,114,32,116,104,105,115,32,100,105,114,101,99, - 116,111,114,121,46,114,0,0,0,0,114,60,0,0,0,122, - 5,123,125,46,123,125,99,1,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,83,0,0,0,115,28,0,0,0, - 104,0,0,124,0,0,93,18,0,125,1,0,124,1,0,106, - 0,0,131,0,0,146,2,0,113,6,0,83,114,4,0,0, - 0,41,1,114,90,0,0,0,41,2,114,24,0,0,0,90, - 2,102,110,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,250,9,60,115,101,116,99,111,109,112,62,17,5,0, - 0,115,2,0,0,0,9,0,122,41,70,105,108,101,70,105, - 110,100,101,114,46,95,102,105,108,108,95,99,97,99,104,101, - 46,60,108,111,99,97,108,115,62,46,60,115,101,116,99,111, - 109,112,62,78,41,18,114,37,0,0,0,114,3,0,0,0, - 90,7,108,105,115,116,100,105,114,114,47,0,0,0,114,1, - 1,0,0,218,15,80,101,114,109,105,115,115,105,111,110,69, - 114,114,111,114,218,18,78,111,116,65,68,105,114,101,99,116, - 111,114,121,69,114,114,111,114,114,8,0,0,0,114,9,0, - 0,0,114,10,0,0,0,114,10,1,0,0,114,11,1,0, - 0,114,85,0,0,0,114,49,0,0,0,114,90,0,0,0, - 218,3,97,100,100,114,11,0,0,0,114,12,1,0,0,41, - 9,114,110,0,0,0,114,37,0,0,0,90,8,99,111,110, - 116,101,110,116,115,90,21,108,111,119,101,114,95,115,117,102, - 102,105,120,95,99,111,110,116,101,110,116,115,114,246,0,0, - 0,114,108,0,0,0,114,238,0,0,0,114,226,0,0,0, - 90,8,110,101,119,95,110,97,109,101,114,4,0,0,0,114, - 4,0,0,0,114,6,0,0,0,114,14,1,0,0,244,4, - 0,0,115,34,0,0,0,0,2,9,1,3,1,31,1,22, - 3,11,3,18,1,18,7,9,1,13,1,24,1,6,1,27, - 2,6,1,17,1,9,1,18,1,122,22,70,105,108,101,70, - 105,110,100,101,114,46,95,102,105,108,108,95,99,97,99,104, - 101,99,1,0,0,0,0,0,0,0,3,0,0,0,3,0, - 0,0,7,0,0,0,115,25,0,0,0,135,0,0,135,1, - 0,102,2,0,100,1,0,100,2,0,134,0,0,125,2,0, - 124,2,0,83,41,3,97,20,1,0,0,65,32,99,108,97, - 115,115,32,109,101,116,104,111,100,32,119,104,105,99,104,32, - 114,101,116,117,114,110,115,32,97,32,99,108,111,115,117,114, - 101,32,116,111,32,117,115,101,32,111,110,32,115,121,115,46, - 112,97,116,104,95,104,111,111,107,10,32,32,32,32,32,32, - 32,32,119,104,105,99,104,32,119,105,108,108,32,114,101,116, - 117,114,110,32,97,110,32,105,110,115,116,97,110,99,101,32, - 117,115,105,110,103,32,116,104,101,32,115,112,101,99,105,102, - 105,101,100,32,108,111,97,100,101,114,115,32,97,110,100,32, - 116,104,101,32,112,97,116,104,10,32,32,32,32,32,32,32, - 32,99,97,108,108,101,100,32,111,110,32,116,104,101,32,99, - 108,111,115,117,114,101,46,10,10,32,32,32,32,32,32,32, - 32,73,102,32,116,104,101,32,112,97,116,104,32,99,97,108, - 108,101,100,32,111,110,32,116,104,101,32,99,108,111,115,117, - 114,101,32,105,115,32,110,111,116,32,97,32,100,105,114,101, - 99,116,111,114,121,44,32,73,109,112,111,114,116,69,114,114, - 111,114,32,105,115,10,32,32,32,32,32,32,32,32,114,97, - 105,115,101,100,46,10,10,32,32,32,32,32,32,32,32,99, - 1,0,0,0,0,0,0,0,1,0,0,0,4,0,0,0, - 19,0,0,0,115,43,0,0,0,116,0,0,124,0,0,131, - 1,0,115,30,0,116,1,0,100,1,0,100,2,0,124,0, - 0,131,1,1,130,1,0,136,0,0,124,0,0,136,1,0, - 140,1,0,83,41,3,122,45,80,97,116,104,32,104,111,111, - 107,32,102,111,114,32,105,109,112,111,114,116,108,105,98,46, - 109,97,99,104,105,110,101,114,121,46,70,105,108,101,70,105, - 110,100,101,114,46,122,30,111,110,108,121,32,100,105,114,101, - 99,116,111,114,105,101,115,32,97,114,101,32,115,117,112,112, - 111,114,116,101,100,114,37,0,0,0,41,2,114,48,0,0, - 0,114,109,0,0,0,41,1,114,37,0,0,0,41,2,114, - 172,0,0,0,114,13,1,0,0,114,4,0,0,0,114,6, - 0,0,0,218,24,112,97,116,104,95,104,111,111,107,95,102, - 111,114,95,70,105,108,101,70,105,110,100,101,114,29,5,0, - 0,115,6,0,0,0,0,2,12,1,18,1,122,54,70,105, - 108,101,70,105,110,100,101,114,46,112,97,116,104,95,104,111, - 111,107,46,60,108,111,99,97,108,115,62,46,112,97,116,104, - 95,104,111,111,107,95,102,111,114,95,70,105,108,101,70,105, - 110,100,101,114,114,4,0,0,0,41,3,114,172,0,0,0, - 114,13,1,0,0,114,19,1,0,0,114,4,0,0,0,41, - 2,114,172,0,0,0,114,13,1,0,0,114,6,0,0,0, - 218,9,112,97,116,104,95,104,111,111,107,19,5,0,0,115, - 4,0,0,0,0,10,21,6,122,20,70,105,108,101,70,105, - 110,100,101,114,46,112,97,116,104,95,104,111,111,107,99,1, - 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, - 0,0,0,115,16,0,0,0,100,1,0,106,0,0,124,0, - 0,106,1,0,131,1,0,83,41,2,78,122,16,70,105,108, - 101,70,105,110,100,101,114,40,123,33,114,125,41,41,2,114, - 49,0,0,0,114,37,0,0,0,41,1,114,110,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,114, - 245,0,0,0,37,5,0,0,115,2,0,0,0,0,1,122, - 19,70,105,108,101,70,105,110,100,101,114,46,95,95,114,101, - 112,114,95,95,41,15,114,114,0,0,0,114,113,0,0,0, - 114,115,0,0,0,114,116,0,0,0,114,186,0,0,0,114, - 251,0,0,0,114,132,0,0,0,114,183,0,0,0,114,126, - 0,0,0,114,6,1,0,0,114,182,0,0,0,114,14,1, - 0,0,114,184,0,0,0,114,20,1,0,0,114,245,0,0, - 0,114,4,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,6,0,0,0,114,7,1,0,0,153,4,0,0,115,20, - 0,0,0,12,7,6,2,12,14,12,4,6,2,12,12,12, - 5,15,45,12,31,18,18,114,7,1,0,0,99,4,0,0, - 0,0,0,0,0,6,0,0,0,11,0,0,0,67,0,0, - 0,115,195,0,0,0,124,0,0,106,0,0,100,1,0,131, - 1,0,125,4,0,124,0,0,106,0,0,100,2,0,131,1, - 0,125,5,0,124,4,0,115,99,0,124,5,0,114,54,0, - 124,5,0,106,1,0,125,4,0,110,45,0,124,2,0,124, - 3,0,107,2,0,114,84,0,116,2,0,124,1,0,124,2, - 0,131,2,0,125,4,0,110,15,0,116,3,0,124,1,0, - 124,2,0,131,2,0,125,4,0,124,5,0,115,126,0,116, - 4,0,124,1,0,124,2,0,100,3,0,124,4,0,131,2, - 1,125,5,0,121,44,0,124,5,0,124,0,0,100,2,0, - 60,124,4,0,124,0,0,100,1,0,60,124,2,0,124,0, - 0,100,4,0,60,124,3,0,124,0,0,100,5,0,60,87, - 110,18,0,4,116,5,0,107,10,0,114,190,0,1,1,1, - 89,110,1,0,88,100,0,0,83,41,6,78,218,10,95,95, - 108,111,97,100,101,114,95,95,218,8,95,95,115,112,101,99, - 95,95,114,129,0,0,0,90,8,95,95,102,105,108,101,95, - 95,90,10,95,95,99,97,99,104,101,100,95,95,41,6,218, - 3,103,101,116,114,129,0,0,0,114,224,0,0,0,114,219, - 0,0,0,114,169,0,0,0,218,9,69,120,99,101,112,116, - 105,111,110,41,6,90,2,110,115,114,108,0,0,0,90,8, - 112,97,116,104,110,97,109,101,90,9,99,112,97,116,104,110, - 97,109,101,114,129,0,0,0,114,166,0,0,0,114,4,0, - 0,0,114,4,0,0,0,114,6,0,0,0,218,14,95,102, - 105,120,95,117,112,95,109,111,100,117,108,101,43,5,0,0, - 115,34,0,0,0,0,2,15,1,15,1,6,1,6,1,12, - 1,12,1,18,2,15,1,6,1,21,1,3,1,10,1,10, - 1,10,1,14,1,13,2,114,25,1,0,0,99,0,0,0, - 0,0,0,0,0,3,0,0,0,3,0,0,0,67,0,0, - 0,115,55,0,0,0,116,0,0,116,1,0,106,2,0,131, - 0,0,102,2,0,125,0,0,116,3,0,116,4,0,102,2, - 0,125,1,0,116,5,0,116,6,0,102,2,0,125,2,0, - 124,0,0,124,1,0,124,2,0,103,3,0,83,41,1,122, - 95,82,101,116,117,114,110,115,32,97,32,108,105,115,116,32, - 111,102,32,102,105,108,101,45,98,97,115,101,100,32,109,111, - 100,117,108,101,32,108,111,97,100,101,114,115,46,10,10,32, - 32,32,32,69,97,99,104,32,105,116,101,109,32,105,115,32, - 97,32,116,117,112,108,101,32,40,108,111,97,100,101,114,44, - 32,115,117,102,102,105,120,101,115,41,46,10,32,32,32,32, - 41,7,114,225,0,0,0,114,147,0,0,0,218,18,101,120, - 116,101,110,115,105,111,110,95,115,117,102,102,105,120,101,115, - 114,219,0,0,0,114,86,0,0,0,114,224,0,0,0,114, - 76,0,0,0,41,3,90,10,101,120,116,101,110,115,105,111, - 110,115,90,6,115,111,117,114,99,101,90,8,98,121,116,101, - 99,111,100,101,114,4,0,0,0,114,4,0,0,0,114,6, - 0,0,0,114,163,0,0,0,66,5,0,0,115,8,0,0, - 0,0,5,18,1,12,1,12,1,114,163,0,0,0,99,1, - 0,0,0,0,0,0,0,12,0,0,0,12,0,0,0,67, - 0,0,0,115,70,2,0,0,124,0,0,97,0,0,116,0, - 0,106,1,0,97,1,0,116,0,0,106,2,0,97,2,0, - 116,1,0,106,3,0,116,4,0,25,125,1,0,120,76,0, - 100,26,0,68,93,68,0,125,2,0,124,2,0,116,1,0, - 106,3,0,107,7,0,114,83,0,116,0,0,106,5,0,124, - 2,0,131,1,0,125,3,0,110,13,0,116,1,0,106,3, - 0,124,2,0,25,125,3,0,116,6,0,124,1,0,124,2, - 0,124,3,0,131,3,0,1,113,44,0,87,100,5,0,100, - 6,0,103,1,0,102,2,0,100,7,0,100,8,0,100,6, - 0,103,2,0,102,2,0,102,2,0,125,4,0,120,149,0, - 124,4,0,68,93,129,0,92,2,0,125,5,0,125,6,0, - 116,7,0,100,9,0,100,10,0,132,0,0,124,6,0,68, - 131,1,0,131,1,0,115,199,0,116,8,0,130,1,0,124, - 6,0,100,11,0,25,125,7,0,124,5,0,116,1,0,106, - 3,0,107,6,0,114,241,0,116,1,0,106,3,0,124,5, - 0,25,125,8,0,80,113,156,0,121,20,0,116,0,0,106, - 5,0,124,5,0,131,1,0,125,8,0,80,87,113,156,0, - 4,116,9,0,107,10,0,114,28,1,1,1,1,119,156,0, - 89,113,156,0,88,113,156,0,87,116,9,0,100,12,0,131, - 1,0,130,1,0,116,6,0,124,1,0,100,13,0,124,8, - 0,131,3,0,1,116,6,0,124,1,0,100,14,0,124,7, - 0,131,3,0,1,116,6,0,124,1,0,100,15,0,100,16, - 0,106,10,0,124,6,0,131,1,0,131,3,0,1,121,19, - 0,116,0,0,106,5,0,100,17,0,131,1,0,125,9,0, - 87,110,24,0,4,116,9,0,107,10,0,114,147,1,1,1, - 1,100,18,0,125,9,0,89,110,1,0,88,116,6,0,124, - 1,0,100,17,0,124,9,0,131,3,0,1,116,0,0,106, - 5,0,100,19,0,131,1,0,125,10,0,116,6,0,124,1, - 0,100,19,0,124,10,0,131,3,0,1,124,5,0,100,7, - 0,107,2,0,114,238,1,116,0,0,106,5,0,100,20,0, - 131,1,0,125,11,0,116,6,0,124,1,0,100,21,0,124, - 11,0,131,3,0,1,116,6,0,124,1,0,100,22,0,116, - 11,0,131,0,0,131,3,0,1,116,12,0,106,13,0,116, - 2,0,106,14,0,131,0,0,131,1,0,1,124,5,0,100, - 7,0,107,2,0,114,66,2,116,15,0,106,16,0,100,23, - 0,131,1,0,1,100,24,0,116,12,0,107,6,0,114,66, - 2,100,25,0,116,17,0,95,18,0,100,18,0,83,41,27, - 122,205,83,101,116,117,112,32,116,104,101,32,112,97,116,104, - 45,98,97,115,101,100,32,105,109,112,111,114,116,101,114,115, - 32,102,111,114,32,105,109,112,111,114,116,108,105,98,32,98, - 121,32,105,109,112,111,114,116,105,110,103,32,110,101,101,100, - 101,100,10,32,32,32,32,98,117,105,108,116,45,105,110,32, - 109,111,100,117,108,101,115,32,97,110,100,32,105,110,106,101, - 99,116,105,110,103,32,116,104,101,109,32,105,110,116,111,32, - 116,104,101,32,103,108,111,98,97,108,32,110,97,109,101,115, - 112,97,99,101,46,10,10,32,32,32,32,79,116,104,101,114, - 32,99,111,109,112,111,110,101,110,116,115,32,97,114,101,32, - 101,120,116,114,97,99,116,101,100,32,102,114,111,109,32,116, - 104,101,32,99,111,114,101,32,98,111,111,116,115,116,114,97, - 112,32,109,111,100,117,108,101,46,10,10,32,32,32,32,114, - 51,0,0,0,114,62,0,0,0,218,8,98,117,105,108,116, - 105,110,115,114,144,0,0,0,90,5,112,111,115,105,120,250, - 1,47,218,2,110,116,250,1,92,99,1,0,0,0,0,0, - 0,0,2,0,0,0,3,0,0,0,115,0,0,0,115,33, - 0,0,0,124,0,0,93,23,0,125,1,0,116,0,0,124, - 1,0,131,1,0,100,0,0,107,2,0,86,1,113,3,0, - 100,1,0,83,41,2,114,31,0,0,0,78,41,1,114,33, - 0,0,0,41,2,114,24,0,0,0,114,79,0,0,0,114, - 4,0,0,0,114,4,0,0,0,114,6,0,0,0,114,228, - 0,0,0,102,5,0,0,115,2,0,0,0,6,0,122,25, - 95,115,101,116,117,112,46,60,108,111,99,97,108,115,62,46, - 60,103,101,110,101,120,112,114,62,114,61,0,0,0,122,30, - 105,109,112,111,114,116,108,105,98,32,114,101,113,117,105,114, - 101,115,32,112,111,115,105,120,32,111,114,32,110,116,114,3, - 0,0,0,114,27,0,0,0,114,23,0,0,0,114,32,0, - 0,0,90,7,95,116,104,114,101,97,100,78,90,8,95,119, - 101,97,107,114,101,102,90,6,119,105,110,114,101,103,114,171, - 0,0,0,114,7,0,0,0,122,4,46,112,121,119,122,6, - 95,100,46,112,121,100,84,41,4,114,51,0,0,0,114,62, - 0,0,0,114,27,1,0,0,114,144,0,0,0,41,19,114, - 123,0,0,0,114,8,0,0,0,114,147,0,0,0,114,240, - 0,0,0,114,114,0,0,0,90,18,95,98,117,105,108,116, - 105,110,95,102,114,111,109,95,110,97,109,101,114,118,0,0, - 0,218,3,97,108,108,218,14,65,115,115,101,114,116,105,111, - 110,69,114,114,111,114,114,109,0,0,0,114,28,0,0,0, - 114,13,0,0,0,114,230,0,0,0,114,151,0,0,0,114, - 26,1,0,0,114,86,0,0,0,114,165,0,0,0,114,170, - 0,0,0,114,174,0,0,0,41,12,218,17,95,98,111,111, - 116,115,116,114,97,112,95,109,111,100,117,108,101,90,11,115, - 101,108,102,95,109,111,100,117,108,101,90,12,98,117,105,108, - 116,105,110,95,110,97,109,101,90,14,98,117,105,108,116,105, - 110,95,109,111,100,117,108,101,90,10,111,115,95,100,101,116, - 97,105,108,115,90,10,98,117,105,108,116,105,110,95,111,115, - 114,23,0,0,0,114,27,0,0,0,90,9,111,115,95,109, - 111,100,117,108,101,90,13,116,104,114,101,97,100,95,109,111, - 100,117,108,101,90,14,119,101,97,107,114,101,102,95,109,111, - 100,117,108,101,90,13,119,105,110,114,101,103,95,109,111,100, - 117,108,101,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,6,95,115,101,116,117,112,77,5,0,0,115,82, - 0,0,0,0,8,6,1,9,1,9,3,13,1,13,1,15, - 1,18,2,13,1,20,3,33,1,19,2,31,1,10,1,15, - 1,13,1,4,2,3,1,15,1,5,1,13,1,12,2,12, - 1,16,1,16,1,25,3,3,1,19,1,13,2,11,1,16, - 3,15,1,16,3,12,1,15,1,16,3,19,1,19,1,12, - 1,13,1,12,1,114,34,1,0,0,99,1,0,0,0,0, - 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, - 116,0,0,0,116,0,0,124,0,0,131,1,0,1,116,1, - 0,131,0,0,125,1,0,116,2,0,106,3,0,106,4,0, - 116,5,0,106,6,0,124,1,0,140,0,0,103,1,0,131, - 1,0,1,116,7,0,106,8,0,100,1,0,107,2,0,114, - 78,0,116,2,0,106,9,0,106,10,0,116,11,0,131,1, - 0,1,116,2,0,106,9,0,106,10,0,116,12,0,131,1, - 0,1,116,5,0,124,0,0,95,5,0,116,13,0,124,0, - 0,95,13,0,100,2,0,83,41,3,122,41,73,110,115,116, - 97,108,108,32,116,104,101,32,112,97,116,104,45,98,97,115, - 101,100,32,105,109,112,111,114,116,32,99,111,109,112,111,110, - 101,110,116,115,46,114,29,1,0,0,78,41,14,114,34,1, - 0,0,114,163,0,0,0,114,8,0,0,0,114,255,0,0, - 0,114,151,0,0,0,114,7,1,0,0,114,20,1,0,0, - 114,3,0,0,0,114,114,0,0,0,218,9,109,101,116,97, - 95,112,97,116,104,114,165,0,0,0,114,170,0,0,0,114, - 250,0,0,0,114,219,0,0,0,41,2,114,33,1,0,0, - 90,17,115,117,112,112,111,114,116,101,100,95,108,111,97,100, - 101,114,115,114,4,0,0,0,114,4,0,0,0,114,6,0, - 0,0,218,8,95,105,110,115,116,97,108,108,145,5,0,0, - 115,16,0,0,0,0,2,10,1,9,1,28,1,15,1,16, - 1,16,4,9,1,114,36,1,0,0,41,1,114,0,0,0, - 0,41,2,114,1,0,0,0,114,2,0,0,0,41,59,114, - 116,0,0,0,114,12,0,0,0,90,37,95,67,65,83,69, - 95,73,78,83,69,78,83,73,84,73,86,69,95,80,76,65, - 84,70,79,82,77,83,95,66,89,84,69,83,95,75,69,89, - 114,11,0,0,0,114,13,0,0,0,114,19,0,0,0,114, - 21,0,0,0,114,30,0,0,0,114,40,0,0,0,114,41, - 0,0,0,114,45,0,0,0,114,46,0,0,0,114,48,0, - 0,0,114,57,0,0,0,218,4,116,121,112,101,218,8,95, - 95,99,111,100,101,95,95,114,146,0,0,0,114,17,0,0, - 0,114,137,0,0,0,114,16,0,0,0,114,20,0,0,0, - 90,17,95,82,65,87,95,77,65,71,73,67,95,78,85,77, - 66,69,82,114,75,0,0,0,114,74,0,0,0,114,86,0, - 0,0,114,76,0,0,0,90,23,68,69,66,85,71,95,66, - 89,84,69,67,79,68,69,95,83,85,70,70,73,88,69,83, - 90,27,79,80,84,73,77,73,90,69,68,95,66,89,84,69, - 67,79,68,69,95,83,85,70,70,73,88,69,83,114,81,0, - 0,0,114,87,0,0,0,114,93,0,0,0,114,97,0,0, - 0,114,99,0,0,0,114,107,0,0,0,114,125,0,0,0, - 114,132,0,0,0,114,143,0,0,0,114,149,0,0,0,114, - 152,0,0,0,114,157,0,0,0,218,6,111,98,106,101,99, - 116,114,164,0,0,0,114,169,0,0,0,114,170,0,0,0, - 114,185,0,0,0,114,195,0,0,0,114,211,0,0,0,114, - 219,0,0,0,114,224,0,0,0,114,230,0,0,0,114,225, - 0,0,0,114,231,0,0,0,114,248,0,0,0,114,250,0, - 0,0,114,7,1,0,0,114,25,1,0,0,114,163,0,0, - 0,114,34,1,0,0,114,36,1,0,0,114,4,0,0,0, - 114,4,0,0,0,114,4,0,0,0,114,6,0,0,0,218, - 8,60,109,111,100,117,108,101,62,8,0,0,0,115,106,0, - 0,0,6,16,6,1,6,1,3,1,7,3,12,17,12,5, - 12,5,12,6,12,12,12,10,12,9,12,5,12,7,15,22, - 15,114,22,1,18,2,6,1,6,2,9,2,9,2,10,2, - 21,44,12,33,12,19,12,12,12,12,18,8,12,28,12,17, - 21,55,21,12,18,10,12,14,9,3,12,1,15,65,19,64, - 19,28,22,110,19,41,25,43,25,16,6,3,25,53,19,57, - 19,41,19,134,19,146,15,23,12,11,12,68, + 218,8,60,109,111,100,117,108,101,62,8,0,0,0,115,114, + 0,0,0,6,16,6,1,6,1,3,1,7,3,12,17,12, + 5,12,5,12,6,12,12,12,10,12,9,12,5,12,7,15, + 22,15,114,22,1,18,19,12,1,6,1,12,1,22,2,6, + 1,6,2,9,2,9,2,10,2,21,44,12,33,12,19,12, + 12,12,12,18,8,12,28,12,17,21,57,21,12,18,10,12, + 14,9,3,12,1,15,65,19,64,19,28,22,110,19,41,25, + 43,25,16,6,3,25,53,19,57,19,41,19,134,19,146,15, + 23,12,11,12,68, }; diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 90cb2de27ca234..dd41a3a3def716 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -259,6 +259,21 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename_str, PyCompilerFlags *f } +/* Issue #29537: handle issue27286 bytecode incompatibility + * See Lib/importlib/_bootstrap_external.py for general discussion + */ +extern PY_UINT32_T _Py_BACKCOMPAT_HALF_MAGIC; +static int +_check_half_magic(unsigned int read_value, unsigned int halfmagic) { + return (read_value == halfmagic || read_value == _Py_BACKCOMPAT_HALF_MAGIC); +} + +extern PY_UINT32_T _Py_BACKCOMPAT_MAGIC_NUMBER; +static int +_check_magic(long read_value, long magic) { + return (read_value == magic || read_value == _Py_BACKCOMPAT_MAGIC_NUMBER); +} + /* Check whether a file maybe a pyc file: Look at the extension, the file type, and, if we may close it, at the first few bytes. */ @@ -290,7 +305,7 @@ maybe_pyc_file(FILE *fp, const char* filename, const char* ext, int closeit) int ispyc = 0; if (ftell(fp) == 0) { if (fread(buf, 1, 2, fp) == 2 && - ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) + _check_half_magic(((unsigned int)buf[1]<<8 | buf[0]), halfmagic)) ispyc = 1; rewind(fp); } @@ -988,7 +1003,7 @@ run_pyc_file(FILE *fp, const char *filename, PyObject *globals, long PyImport_GetMagicNumber(void); magic = PyMarshal_ReadLongFromFile(fp); - if (magic != PyImport_GetMagicNumber()) { + if (!_check_magic(magic, PyImport_GetMagicNumber())) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_RuntimeError, "Bad magic number in .pyc file"); From 312f7dfb7c669fcfc43020951b7f8ff521200ad7 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 7 Mar 2017 23:56:52 -0800 Subject: [PATCH 064/340] Revert "bpo-29571: Use correct locale encoding in test_re (#149)" (#554) (#556) This reverts commit ace5c0fdd9b962e6e886c29dbcea72c53f051dc4. --- Lib/test/test_re.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 407f3468e86671..9acd5abbfd7776 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1334,7 +1334,7 @@ def test_ascii_and_unicode_flag(self): def test_locale_flag(self): import locale - enc = locale.getpreferredencoding(False) + _, enc = locale.getlocale(locale.LC_CTYPE) # Search non-ASCII letter for i in range(128, 256): try: From 0410bee6e6c87f37e91f6cae3627d8e3704075f1 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Wed, 8 Mar 2017 21:03:04 +1000 Subject: [PATCH 065/340] bpo-29537: Also cover 3.5.2 in NEWS entry --- Misc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS b/Misc/NEWS index 82f9f9a1f58b07..42a3b026bb74c1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,7 +11,7 @@ Core and Builtins ----------------- - Issue #29537: Restore runtime compatibility with bytecode files generated by - CPython 3.5.0 and 3.5.1, and adjust the eval loop to avoid the problems that + CPython 3.5.0 to 3.5.2, and adjust the eval loop to avoid the problems that could be caused by the malformed variant of the BUILD_MAP_UNPACK_WITH_CALL opcode that they may contain. Patch by Petr Viktorin, Serhiy Storchaka, and Nick Coghlan. From 952b7cb78046f4bc3bf28cb7de84d1c6bcec45d7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 10:52:19 +0200 Subject: [PATCH 066/340] bpo-29768: Fixed compile-time check for expat version. (#574) (#578) (cherry picked from commit 22e707fa04476710ba5cc7e2206e4ac66743931b) --- Modules/pyexpat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 00c96a16c7895a..3a6e590ef21ba6 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1190,7 +1190,7 @@ newxmlparseobject(const char *encoding, const char *namespace_separator, PyObjec Py_DECREF(self); return NULL; } -#if ((XML_MAJOR_VERSION >= 2) && (XML_MINOR_VERSION >= 1)) || defined(XML_HAS_SET_HASH_SALT) +#if XML_COMBINED_VERSION >= 20100 || defined(XML_HAS_SET_HASH_SALT) /* This feature was added upstream in libexpat 2.1.0. Our expat copy * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT * to indicate that we can still use it. */ From 5fad493dc6634635bc6ba951b39b4d1bf552ef84 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 9 Mar 2017 21:02:15 +0200 Subject: [PATCH 067/340] [3.5] bpo-29773: Add more cases for testing string to float conversion errors. (#587) (cherry picked from commit 9e6ac83acae31de2b072e665e177db9fcdf7c049) --- Lib/test/test_float.py | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py index cb1f6db8fc7627..28b6954c4d5923 100644 --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -98,15 +98,27 @@ def test_float_memoryview(self): self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) def test_error_message(self): - testlist = ('\xbd', '123\xbd', ' 123 456 ') - for s in testlist: - try: + def check(s): + with self.assertRaises(ValueError, msg='float(%r)' % (s,)) as cm: float(s) - except ValueError as e: - self.assertIn(s.strip(), e.args[0]) - else: - self.fail("Expected int(%r) to raise a ValueError", s) - + self.assertEqual(str(cm.exception), + 'could not convert string to float: %r' % (s,)) + + check('\xbd') + check('123\xbd') + check(' 123 456 ') + check(b' 123 456 ') + + # non-ascii digits (error came from non-digit '!') + check('\u0663\u0661\u0664!') + # embedded NUL + check('123\x00') + check('123\x00 245') + check('123\x00245') + # byte string with embedded NUL + check(b'123\x00') + # non-UTF-8 byte string + check(b'123\xa0') @support.run_with_locale('LC_NUMERIC', 'fr_FR', 'de_DE') def test_float_with_comma(self): From e2c88bdd6bb3efbc81389958d62daf6dd0d6eda7 Mon Sep 17 00:00:00 2001 From: orenmn Date: Thu, 9 Mar 2017 21:29:22 +0200 Subject: [PATCH 068/340] bpo-28298: make array 'Q', 'L' and 'I' accept big intables as elements --- Lib/test/test_array.py | 25 +++++++++- Misc/NEWS | 3 ++ Modules/arraymodule.c | 108 +++++++++++++++++++++++------------------ 3 files changed, 88 insertions(+), 48 deletions(-) diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py index 2a21e745b1bcd2..cbc6b6d686341c 100644 --- a/Lib/test/test_array.py +++ b/Lib/test/test_array.py @@ -1225,7 +1225,26 @@ def test_frombytearray(self): b = array.array(self.typecode, a) self.assertEqual(a, b) -class SignedNumberTest(NumberTest): +class IntegerNumberTest(NumberTest): + def test_type_error(self): + a = array.array(self.typecode) + a.append(42) + with self.assertRaises(TypeError): + a.append(42.0) + with self.assertRaises(TypeError): + a[0] = 42.0 + +class Intable: + def __init__(self, num): + self._num = num + def __int__(self): + return self._num + def __sub__(self, other): + return Intable(int(self) - int(other)) + def __add__(self, other): + return Intable(int(self) + int(other)) + +class SignedNumberTest(IntegerNumberTest): example = [-1, 0, 1, 42, 0x7f] smallerexample = [-1, 0, 1, 42, 0x7e] biggerexample = [-1, 0, 1, 43, 0x7f] @@ -1236,8 +1255,9 @@ def test_overflow(self): lower = -1 * int(pow(2, a.itemsize * 8 - 1)) upper = int(pow(2, a.itemsize * 8 - 1)) - 1 self.check_overflow(lower, upper) + self.check_overflow(Intable(lower), Intable(upper)) -class UnsignedNumberTest(NumberTest): +class UnsignedNumberTest(IntegerNumberTest): example = [0, 1, 17, 23, 42, 0xff] smallerexample = [0, 1, 17, 23, 42, 0xfe] biggerexample = [0, 1, 17, 23, 43, 0xff] @@ -1248,6 +1268,7 @@ def test_overflow(self): lower = 0 upper = int(pow(2, a.itemsize * 8)) - 1 self.check_overflow(lower, upper) + self.check_overflow(Intable(lower), Intable(upper)) def test_bytes_extend(self): s = bytes(self.example) diff --git a/Misc/NEWS b/Misc/NEWS index 42a3b026bb74c1..df0975a4d5ea22 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -41,6 +41,9 @@ Extension Modules Library ------- +- bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big + intables (objects that have __int__) as elements. Patch by Oren Milman. + - bpo-29615: SimpleXMLRPCDispatcher no longer chains KeyError (or any other exception) to exception(s) raised in the dispatched methods. Patch by Petr Motejlek. diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index a4966b4bddb53a..8612847fcafe81 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -331,35 +331,51 @@ II_getitem(arrayobject *ap, Py_ssize_t i) (unsigned long) ((unsigned int *)ap->ob_item)[i]); } +static PyObject * +get_int_unless_float(PyObject *v) +{ + if (PyFloat_Check(v)) { + PyErr_SetString(PyExc_TypeError, + "array item must be integer"); + return NULL; + } + return (PyObject *)_PyLong_FromNbInt(v); +} + static int II_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { unsigned long x; - if (PyLong_Check(v)) { - x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long) -1 && PyErr_Occurred()) + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { return -1; + } + do_decref = 1; } - else { - long y; - if (!PyArg_Parse(v, "l;array item must be integer", &y)) - return -1; - if (y < 0) { - PyErr_SetString(PyExc_OverflowError, - "unsigned int is less than minimum"); - return -1; + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); } - x = (unsigned long)y; - + return -1; } if (x > UINT_MAX) { PyErr_SetString(PyExc_OverflowError, - "unsigned int is greater than maximum"); + "unsigned int is greater than maximum"); + if (do_decref) { + Py_DECREF(v); + } return -1; } - if (i >= 0) ((unsigned int *)ap->ob_item)[i] = (unsigned int)x; + + if (do_decref) { + Py_DECREF(v); + } return 0; } @@ -390,31 +406,28 @@ static int LL_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { unsigned long x; - if (PyLong_Check(v)) { - x = PyLong_AsUnsignedLong(v); - if (x == (unsigned long) -1 && PyErr_Occurred()) - return -1; - } - else { - long y; - if (!PyArg_Parse(v, "l;array item must be integer", &y)) - return -1; - if (y < 0) { - PyErr_SetString(PyExc_OverflowError, - "unsigned long is less than minimum"); + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { return -1; } - x = (unsigned long)y; - + do_decref = 1; } - if (x > ULONG_MAX) { - PyErr_SetString(PyExc_OverflowError, - "unsigned long is greater than maximum"); + x = PyLong_AsUnsignedLong(v); + if (x == (unsigned long)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); + } return -1; } - if (i >= 0) ((unsigned long *)ap->ob_item)[i] = x; + + if (do_decref) { + Py_DECREF(v); + } return 0; } @@ -448,25 +461,28 @@ static int QQ_setitem(arrayobject *ap, Py_ssize_t i, PyObject *v) { unsigned PY_LONG_LONG x; - if (PyLong_Check(v)) { - x = PyLong_AsUnsignedLongLong(v); - if (x == (unsigned PY_LONG_LONG) -1 && PyErr_Occurred()) + int do_decref = 0; /* if nb_int was called */ + + if (!PyLong_Check(v)) { + v = get_int_unless_float(v); + if (NULL == v) { return -1; + } + do_decref = 1; } - else { - PY_LONG_LONG y; - if (!PyArg_Parse(v, "L;array item must be integer", &y)) - return -1; - if (y < 0) { - PyErr_SetString(PyExc_OverflowError, - "unsigned long long is less than minimum"); - return -1; + x = PyLong_AsUnsignedLongLong(v); + if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) { + if (do_decref) { + Py_DECREF(v); } - x = (unsigned PY_LONG_LONG)y; + return -1; } - if (i >= 0) ((unsigned PY_LONG_LONG *)ap->ob_item)[i] = x; + + if (do_decref) { + Py_DECREF(v); + } return 0; } #endif From e73f9256a2dfb21a60f333f815f2c1fe4cdca0d0 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 10 Mar 2017 01:07:18 -0600 Subject: [PATCH 069/340] Add Appveyor (GH-324 backport) (GH-492) --- .github/appveyor.yml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml new file mode 100644 index 00000000000000..e44b5b09e6ea17 --- /dev/null +++ b/.github/appveyor.yml @@ -0,0 +1,6 @@ +version: 3.5.3+.{build} +clone_depth: 5 +build_script: +- cmd: PCbuild\build.bat -e +test_script: +- cmd: PCbuild\rt.bat -q -uall -rwW --timeout=1200 -j0 From 518d8fcb89896dd30fbf11c667ee4e6b509e4dd9 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 10 Mar 2017 19:36:52 -0800 Subject: [PATCH 070/340] bpo-29784: Fix the reference to shutil.copy in the docs (GH-602) (GH-609) (cherry picked from commit 70ee0cd5c2a3dba82cb8e0c0742c012f9134c040) --- Doc/library/shutil.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst index b020bb31c83b7b..358081137afd9c 100644 --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -153,7 +153,7 @@ Directory and files operations is true and *src* is a symbolic link, *dst* will be a copy of the file *src* refers to. - :func:`copy` copies the file data and the file's permission + :func:`~shutil.copy` copies the file data and the file's permission mode (see :func:`os.chmod`). Other metadata, like the file's creation and modification times, is not preserved. To preserve all file metadata from the original, use @@ -302,7 +302,7 @@ Directory and files operations *src* and *dst*, and will be used to copy *src* to *dest* if :func:`os.rename` cannot be used. If the source is a directory, :func:`copytree` is called, passing it the :func:`copy_function`. The - default *copy_function* is :func:`copy2`. Using :func:`copy` as the + default *copy_function* is :func:`copy2`. Using :func:`~shutil.copy` as the *copy_function* allows the move to succeed when it is not possible to also copy the metadata, at the expense of not copying any of the metadata. From ce222c87706b1062f7fc03867d1867aa4848dd7b Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Sat, 11 Mar 2017 14:12:29 +0800 Subject: [PATCH 071/340] bpo-29770: remove outdated PYO related info (GH-590) (GH-613) --- Doc/glossary.rst | 2 +- Doc/library/zipfile.rst | 6 +++--- Doc/library/zipimport.rst | 2 +- Doc/using/cmdline.rst | 4 ++-- Modules/main.c | 2 +- Modules/zipimport.c | 8 ++++---- PC/getpathp.c | 4 ++-- PCbuild/rmpyc.py | 20 +++++++------------- PCbuild/rt.bat | 8 ++++---- Python/pylifecycle.c | 2 +- 10 files changed, 26 insertions(+), 32 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 45b794f48ef7c9..4a8bb8e633b3aa 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -127,7 +127,7 @@ Glossary bytecode Python source code is compiled into bytecode, the internal representation of a Python program in the CPython interpreter. The bytecode is also - cached in ``.pyc`` and ``.pyo`` files so that executing the same file is + cached in ``.pyc`` files so that executing the same file is faster the second time (recompilation from source to bytecode can be avoided). This "intermediate language" is said to run on a :term:`virtual machine` that executes the machine code corresponding to diff --git a/Doc/library/zipfile.rst b/Doc/library/zipfile.rst index d144ae36f1e7cb..629b7ed55a145a 100644 --- a/Doc/library/zipfile.rst +++ b/Doc/library/zipfile.rst @@ -418,12 +418,12 @@ The :class:`PyZipFile` constructor takes the same parameters as the added to the archive, compiling if necessary. If *pathname* is a file, the filename must end with :file:`.py`, and - just the (corresponding :file:`\*.py[co]`) file is added at the top level + just the (corresponding :file:`\*.pyc`) file is added at the top level (no path information). If *pathname* is a file that does not end with :file:`.py`, a :exc:`RuntimeError` will be raised. If it is a directory, and the directory is not a package directory, then all the files - :file:`\*.py[co]` are added at the top level. If the directory is a - package directory, then all :file:`\*.py[co]` are added under the package + :file:`\*.pyc` are added at the top level. If the directory is a + package directory, then all :file:`\*.pyc` are added under the package name as a file path, and if any subdirectories are package directories, all of these are added recursively. diff --git a/Doc/library/zipimport.rst b/Doc/library/zipimport.rst index 46b8c245f7b3fe..eaae2bb04b7482 100644 --- a/Doc/library/zipimport.rst +++ b/Doc/library/zipimport.rst @@ -9,7 +9,7 @@ -------------- This module adds the ability to import Python modules (:file:`\*.py`, -:file:`\*.py[co]`) and packages from ZIP-format archives. It is usually not +:file:`\*.pyc`) and packages from ZIP-format archives. It is usually not needed to use the :mod:`zipimport` module explicitly; it is automatically used by the built-in :keyword:`import` mechanism for :data:`sys.path` items that are paths to ZIP archives. diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 611779618e71d6..906d31f3859245 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -518,8 +518,8 @@ conflict. .. envvar:: PYTHONDONTWRITEBYTECODE - If this is set to a non-empty string, Python won't try to write ``.pyc`` or - ``.pyo`` files on the import of source modules. This is equivalent to + If this is set to a non-empty string, Python won't try to write ``.pyc`` + files on the import of source modules. This is equivalent to specifying the :option:`-B` option. diff --git a/Modules/main.c b/Modules/main.c index 75ee2f607ca83d..d36db6d8b511af 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -50,7 +50,7 @@ static char *usage_1 = "\ Options and arguments (and corresponding environment variables):\n\ -b : issue warnings about str(bytes_instance), str(bytearray_instance)\n\ and comparing bytes/bytearray with str. (-bb: issue errors)\n\ --B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\ +-B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser; also PYTHONDEBUG=x\n\ -E : ignore PYTHON* environment variables (such as PYTHONPATH)\n\ diff --git a/Modules/zipimport.c b/Modules/zipimport.c index a693fbbf6e280e..feef98f582b580 100644 --- a/Modules/zipimport.c +++ b/Modules/zipimport.c @@ -1104,7 +1104,7 @@ get_decompress_func(void) _Py_IDENTIFIER(decompress); if (importing_zlib != 0) - /* Someone has a zlib.py[co] in their Zip file; + /* Someone has a zlib.pyc in their Zip file; let's avoid a stack overflow. */ return NULL; importing_zlib = 1; @@ -1264,11 +1264,11 @@ eq_mtime(time_t t1, time_t t2) } /* Issue #29537: handle issue27286 bytecode incompatibility - * See Lib/importlib/_bootstrap_external.py for general discussion + * See Lib/importlib/_bootstrap_external.py for general discussion */ extern PY_UINT32_T _Py_BACKCOMPAT_MAGIC_NUMBER; -/* Given the contents of a .py[co] file in a buffer, unmarshal the data +/* Given the contents of a .pyc file in a buffer, unmarshal the data and return the code object. Return None if it the magic word doesn't match (we do this instead of raising an exception as we fall back to .py if available and we don't want to mask other errors). @@ -1414,7 +1414,7 @@ get_mtime_of_source(ZipImporter *self, PyObject *path) PyObject *toc_entry, *stripped; time_t mtime; - /* strip 'c' or 'o' from *.py[co] */ + /* strip 'c' from *.pyc */ if (PyUnicode_READY(path) == -1) return (time_t)-1; stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path), diff --git a/PC/getpathp.c b/PC/getpathp.c index c7ddf1ea6b33eb..47a571e272b00d 100644 --- a/PC/getpathp.c +++ b/PC/getpathp.c @@ -133,7 +133,7 @@ exists(wchar_t *filename) may extend 'filename' by one character. */ static int -ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc/.pyo too */ +ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc too */ { int n; @@ -144,7 +144,7 @@ ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc/ n = wcsnlen_s(filename, MAXPATHLEN+1); if (n < MAXPATHLEN) { int exist = 0; - filename[n] = Py_OptimizeFlag ? L'o' : L'c'; + filename[n] = L'c'; filename[n + 1] = L'\0'; exist = exists(filename); if (!update_filename) diff --git a/PCbuild/rmpyc.py b/PCbuild/rmpyc.py index a1e75bb7ae5b4b..0b58f687729f7e 100644 --- a/PCbuild/rmpyc.py +++ b/PCbuild/rmpyc.py @@ -1,25 +1,19 @@ -# Remove all the .pyc and .pyo files under ../Lib. +# Remove all the .pyc files under ../Lib. def deltree(root): import os from os.path import join - npyc = npyo = 0 + npyc = 0 for root, dirs, files in os.walk(root): for name in files: - delete = False - if name.endswith('.pyc'): - delete = True + # to be thorough + if name.endswith(('.pyc', '.pyo')): npyc += 1 - elif name.endswith('.pyo'): - delete = True - npyo += 1 - - if delete: os.remove(join(root, name)) - return npyc, npyo + return npyc -npyc, npyo = deltree("../Lib") -print(npyc, ".pyc deleted,", npyo, ".pyo deleted") +npyc = deltree("../Lib") +print(npyc, ".pyc deleted") diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index 2d93b80a499fa5..20568549b1599d 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -4,8 +4,8 @@ rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args rem -d Run Debug build (python_d.exe). Else release build. rem -O Run python.exe or python_d.exe (see -d) with -O. rem -q "quick" -- normally the tests are run twice, the first time -rem after deleting all the .py[co] files reachable from Lib/. -rem -q runs the tests just once, and without deleting .py[co] files. +rem after deleting all the .pyc files reachable from Lib/. +rem -q runs the tests just once, and without deleting .pyc files. rem -x64 Run the 64-bit build of python (or python_d if -d was specified) rem from the 'amd64' dir instead of the 32-bit build in this dir. rem All leading instances of these switches are shifted off, and @@ -45,14 +45,14 @@ set exe=%prefix%python%suffix%.exe set cmd="%exe%" %dashO% -Wd -E -bb "%pcbuild%..\lib\test\regrtest.py" %regrtestargs% if defined qmode goto Qmode -echo Deleting .pyc/.pyo files ... +echo Deleting .pyc files ... "%exe%" "%pcbuild%rmpyc.py" echo on %cmd% @echo off -echo About to run again without deleting .pyc/.pyo first: +echo About to run again without deleting .pyc first: pause :Qmode diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ce52990496931c..87dadc164c2645 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -85,7 +85,7 @@ int Py_BytesWarningFlag; /* Warn on str(bytes) and str(buffer) */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ int Py_FrozenFlag; /* Needed by getpath.c */ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */ -int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ +int Py_DontWriteBytecodeFlag; /* Suppress writing bytecode files (*.pyc) */ int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ From 5f63884b724f416c62a81cf5b2ab6d761f50d365 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 11 Mar 2017 10:19:37 -0800 Subject: [PATCH 072/340] tempfile.rst: Fix some typos (GH-610) (GH-619) (cherry picked from commit d3b8f98696b905367da3975f73b482bac380b51c) --- Doc/library/tempfile.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst index 665261ffb21f94..c59aca1e189086 100644 --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -245,12 +245,12 @@ 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. +to specify the directory and this is the recommended 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 + default value for the *dir* argument to the functions defined in this module. If ``tempdir`` is unset or ``None`` at any call to any of the above From a951c554ce4adcaa3af85b8e5fb56df9c46e9287 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 11 Mar 2017 15:47:13 -0600 Subject: [PATCH 073/340] Only trigger AppVeyor on code or config changes (GH-611 backport) (GH-621) --- .github/appveyor.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/appveyor.yml b/.github/appveyor.yml index e44b5b09e6ea17..60c2dae444761e 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -4,3 +4,20 @@ build_script: - cmd: PCbuild\build.bat -e test_script: - cmd: PCbuild\rt.bat -q -uall -rwW --timeout=1200 -j0 + +# Only trigger AppVeyor if actual code or its configuration changes +only_commits: + files: + - .github/appveyor.yml + - .gitattributes + - Grammar/ + - Include/ + - Lib/ + - Modules/ + - Objects/ + - PC/ + - PCBuild/ + - Parser/ + - Programs/ + - Python/ + - Tools/ From be31a837304f81842b13dbabdaaa14bb9bbe64af Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Mar 2017 16:18:14 +1000 Subject: [PATCH 074/340] bpo-29656: Handle PR branches in 'make patchcheck' (#302) (#627) (cherry picked from commit 482f7a274fa52b7ba34ff308cd9acdcac9f41ba5) --- Tools/scripts/patchcheck.py | 58 +++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py index 58b081a9c53ff5..7a04aafa82a8a1 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -12,7 +12,6 @@ SRCDIR = sysconfig.get_config_var('srcdir') - def n_files_str(count): """Return 'N file(s)' with the proper plurality on 'file'.""" return "{} file{}".format(count, "s" if count != 1 else "") @@ -46,27 +45,73 @@ def mq_patches_applied(): return st.returncode == 0 and bstdout +def get_git_branch(): + """Get the symbolic name for the current git branch""" + cmd = "git rev-parse --abbrev-ref HEAD".split() + try: + return subprocess.check_output(cmd, stderr=subprocess.DEVNULL) + except subprocess.CalledProcessError: + return None + + +def get_git_upstream_remote(): + """Get the remote name to use for upstream branches + + Uses "upstream" if it exists, "origin" otherwise + """ + cmd = "git remote get-url upstream".split() + try: + subprocess.check_output(cmd, stderr=subprocess.DEVNULL) + except subprocess.CalledProcessError: + return "origin" + return "upstream" + + +@status("Getting base branch for PR", + info=lambda x: x if x is not None else "not a PR branch") +def get_base_branch(): + if not os.path.isdir(os.path.join(SRCDIR, '.git')): + # Not a git checkout, so there's no base branch + return None + version = sys.version_info + if version.releaselevel == 'alpha': + base_branch = "master" + else: + base_branch = "{0.major}.{0.minor}".format(version) + this_branch = get_git_branch() + if this_branch is None or this_branch == base_branch: + # Not on a git PR branch, so there's no base branch + return None + upstream_remote = get_git_upstream_remote() + return upstream_remote + "/" + base_branch + + @status("Getting the list of files that have been added/changed", info=lambda x: n_files_str(len(x))) -def changed_files(): +def changed_files(base_branch=None): """Get the list of changed or added files from Mercurial or git.""" if os.path.isdir(os.path.join(SRCDIR, '.hg')): + if base_branch is not None: + sys.exit('need a git checkout to check PR status') cmd = 'hg status --added --modified --no-status' if mq_patches_applied(): cmd += ' --rev qparent' with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st: return [x.decode().rstrip() for x in st.stdout] elif os.path.isdir(os.path.join(SRCDIR, '.git')): - cmd = 'git status --porcelain' + if base_branch: + cmd = 'git diff --name-status ' + base_branch + else: + cmd = 'git status --porcelain' filenames = [] with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st: for line in st.stdout: line = line.decode().rstrip() - status = set(line[:2]) + status_text, filename = line.split(maxsplit=1) + status = set(status_text) # modified, added or unmerged files if not status.intersection('MAU'): continue - filename = line[3:] if ' -> ' in filename: # file is renamed filename = filename.split(' -> ', 2)[1].strip() @@ -165,7 +210,8 @@ def regenerated_pyconfig_h_in(file_paths): return "not needed" def main(): - file_paths = changed_files() + base_branch = get_base_branch() + file_paths = changed_files(base_branch) python_files = [fn for fn in file_paths if fn.endswith('.py')] c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))] doc_files = [fn for fn in file_paths if fn.startswith('Doc') and From f12f820ef887b009ce70e67e71b8690f30c605ee Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 12 Mar 2017 10:05:27 +0200 Subject: [PATCH 075/340] bpo-29746: Update marshal docs to Python 3. (#547) (#630) (cherry picked from commit c611a5b1d4fab0123bf622f06c3bfa510221dc32) --- Doc/c-api/marshal.rst | 8 ++++---- Doc/glossary.rst | 7 +++++++ Doc/library/marshal.rst | 19 ++++++++----------- Python/marshal.c | 26 ++++++++++++-------------- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/Doc/c-api/marshal.rst b/Doc/c-api/marshal.rst index a6d0f4688d1b78..c6d1d02a2fa510 100644 --- a/Doc/c-api/marshal.rst +++ b/Doc/c-api/marshal.rst @@ -34,7 +34,7 @@ unmarshalling. Version 2 uses a binary format for floating point numbers. .. c:function:: PyObject* PyMarshal_WriteObjectToString(PyObject *value, int version) - Return a string object containing the marshalled representation of *value*. + Return a bytes object containing the marshalled representation of *value*. *version* indicates the file format. @@ -88,10 +88,10 @@ written using these routines? :exc:`TypeError`) and returns *NULL*. -.. c:function:: PyObject* PyMarshal_ReadObjectFromString(const char *string, Py_ssize_t len) +.. c:function:: PyObject* PyMarshal_ReadObjectFromString(const char *data, Py_ssize_t len) - Return a Python object from the data stream in a character buffer - containing *len* bytes pointed to by *string*. + Return a Python object from the data stream in a byte buffer + containing *len* bytes pointed to by *data*. On error, sets the appropriate exception (:exc:`EOFError` or :exc:`TypeError`) and returns *NULL*. diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 4a8bb8e633b3aa..07b26a64b89c13 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -103,6 +103,10 @@ Glossary binary file A :term:`file object` able to read and write :term:`bytes-like objects `. + Examples of binary files are files opened in binary mode (``'rb'``, + ``'wb'`` or ``'rb+'``), :data:`sys.stdin.buffer`, + :data:`sys.stdout.buffer`, and instances of :class:`io.BytesIO` and + :class:`gzip.GzipFile`. .. seealso:: A :term:`text file` reads and writes :class:`str` objects. @@ -926,6 +930,9 @@ Glossary A :term:`file object` able to read and write :class:`str` objects. Often, a text file actually accesses a byte-oriented datastream and handles the :term:`text encoding` automatically. + Examples of text files are files opened in text mode (``'r'`` or ``'w'``), + :data:`sys.stdin`, :data:`sys.stdout`, and instances of + :class:`io.StringIO`. .. seealso:: A :term:`binary file` reads and write :class:`bytes` objects. diff --git a/Doc/library/marshal.rst b/Doc/library/marshal.rst index 1ffc6effc7142d..d65afc20041133 100644 --- a/Doc/library/marshal.rst +++ b/Doc/library/marshal.rst @@ -49,7 +49,7 @@ For format *version* lower than 3, recursive lists, sets and dictionaries cannot be written (see below). There are functions that read/write files as well as functions operating on -strings. +bytes-like objects. The module defines these functions: @@ -57,9 +57,7 @@ The module defines these functions: .. function:: dump(value, file[, version]) Write the value on the open file. The value must be a supported type. The - file must be an open file object such as ``sys.stdout`` or returned by - :func:`open` or :func:`os.popen`. It must be opened in binary mode (``'wb'`` - or ``'w+b'``). + file must be a writeable :term:`binary file`. If the value has (or contains an object that has) an unsupported type, a :exc:`ValueError` exception is raised --- but garbage data will also be written @@ -74,8 +72,7 @@ The module defines these functions: Read one value from the open file and return it. If no valid value is read (e.g. because the data has a different Python version's incompatible marshal format), raise :exc:`EOFError`, :exc:`ValueError` or :exc:`TypeError`. The - file must be an open file object opened in binary mode (``'rb'`` or - ``'r+b'``). + file must be a readable :term:`binary file`. .. note:: @@ -85,7 +82,7 @@ The module defines these functions: .. function:: dumps(value[, version]) - Return the string that would be written to a file by ``dump(value, file)``. The + Return the bytes object that would be written to a file by ``dump(value, file)``. The value must be a supported type. Raise a :exc:`ValueError` exception if value has (or contains an object that has) an unsupported type. @@ -93,11 +90,11 @@ The module defines these functions: (see below). -.. function:: loads(string) +.. function:: loads(bytes) - Convert the string to a value. If no valid value is found, raise - :exc:`EOFError`, :exc:`ValueError` or :exc:`TypeError`. Extra characters in the - string are ignored. + Convert the :term:`bytes-like object` to a value. If no valid value is found, raise + :exc:`EOFError`, :exc:`ValueError` or :exc:`TypeError`. Extra bytes in the + input are ignored. In addition, the following constants are defined: diff --git a/Python/marshal.c b/Python/marshal.c index 5b8de991921784..67e32c89734c48 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -549,7 +549,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p) w_object(co->co_lnotab, p); } else if (PyObject_CheckBuffer(v)) { - /* Write unknown bytes-like objects as a byte string */ + /* Write unknown bytes-like objects as a bytes object */ Py_buffer view; if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) != 0) { w_byte(TYPE_UNKNOWN, p); @@ -1079,7 +1079,7 @@ r_object(RFILE *p) if (PyErr_Occurred()) break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); + PyErr_SetString(PyExc_ValueError, "bad marshal data (bytes object size out of range)"); break; } v = PyBytes_FromStringAndSize((char *)NULL, n); @@ -1103,7 +1103,7 @@ r_object(RFILE *p) if (PyErr_Occurred()) break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)"); + PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); break; } goto _read_ascii; @@ -1143,7 +1143,7 @@ r_object(RFILE *p) if (PyErr_Occurred()) break; if (n < 0 || n > SIZE32_MAX) { - PyErr_SetString(PyExc_ValueError, "bad marshal data (unicode size out of range)"); + PyErr_SetString(PyExc_ValueError, "bad marshal data (string size out of range)"); break; } if (n != 0) { @@ -1594,7 +1594,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version) if (wf.ptr - base > PY_SSIZE_T_MAX) { Py_DECREF(wf.str); PyErr_SetString(PyExc_OverflowError, - "too much marshal data for a string"); + "too much marshal data for a bytes object"); return NULL; } if (_PyBytes_Resize(&wf.str, (Py_ssize_t)(wf.ptr - base)) < 0) @@ -1640,8 +1640,7 @@ PyDoc_STRVAR(dump_doc, "dump(value, file[, version])\n\ \n\ Write the value on the open file. The value must be a supported type.\n\ -The file must be an open file object such as sys.stdout or returned by\n\ -open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\ +The file must be a writeable binary file.\n\ \n\ If the value has (or contains an object that has) an unsupported type, a\n\ ValueError exception is raised - but garbage data will also be written\n\ @@ -1697,8 +1696,7 @@ PyDoc_STRVAR(load_doc, Read one value from the open file and return it. If no valid value is\n\ read (e.g. because the data has a different Python version's\n\ incompatible marshal format), raise EOFError, ValueError or TypeError.\n\ -The file must be an open file object opened in binary mode ('rb' or\n\ -'r+b').\n\ +The file must be a readable binary file.\n\ \n\ Note: If an object containing an unsupported type was marshalled with\n\ dump(), load() will substitute None for the unmarshallable type."); @@ -1717,7 +1715,7 @@ marshal_dumps(PyObject *self, PyObject *args) PyDoc_STRVAR(dumps_doc, "dumps(value[, version])\n\ \n\ -Return the string that would be written to a file by dump(value, file).\n\ +Return the bytes object that would be written to a file by dump(value, file).\n\ The value must be a supported type. Raise a ValueError exception if\n\ value has (or contains an object that has) an unsupported type.\n\ \n\ @@ -1753,8 +1751,8 @@ marshal_loads(PyObject *self, PyObject *args) PyDoc_STRVAR(loads_doc, "loads(bytes)\n\ \n\ -Convert the bytes object to a value. If no valid value is found, raise\n\ -EOFError, ValueError or TypeError. Extra characters in the input are\n\ +Convert the bytes-like object to a value. If no valid value is found,\n\ +raise EOFError, ValueError or TypeError. Extra bytes in the input are\n\ ignored."); static PyMethodDef marshal_methods[] = { @@ -1792,8 +1790,8 @@ Functions:\n\ \n\ dump() -- write value to a file\n\ load() -- read value from a file\n\ -dumps() -- write value to a string\n\ -loads() -- read value from a string"); +dumps() -- marshal value as a bytes object\n\ +loads() -- read value from a bytes-like object"); From a6aac8c87036c3180916b893d66b1e257b5e2ec2 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 12 Mar 2017 20:03:35 +1000 Subject: [PATCH 076/340] bpo-29798: Handle git worktree in `make patchcheck` (#629) (#634) In git worktree directories, `.git` is a configuration file rather than a subdirectory (cherry picked from commit 6a6d090612dd7deaac2bc0399fad743e5e2db606) --- Tools/scripts/patchcheck.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py index 7a04aafa82a8a1..f4ec7d8a30ea23 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -98,7 +98,10 @@ def changed_files(base_branch=None): cmd += ' --rev qparent' with subprocess.Popen(cmd.split(), stdout=subprocess.PIPE) as st: return [x.decode().rstrip() for x in st.stdout] - elif os.path.isdir(os.path.join(SRCDIR, '.git')): + elif os.path.exists(os.path.join(SRCDIR, '.git')): + # We just use an existence check here as: + # directory = normal git checkout/clone + # file = git worktree directory if base_branch: cmd = 'git diff --name-status ' + base_branch else: From a16894ebf8823f0e09036aacde9288c00e8d9058 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 12 Mar 2017 21:52:57 +0200 Subject: [PATCH 077/340] [3.5] bpo-8256: Fixed possible failing or crashing input() (#642) if attributes "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not strings. (cherry picked from commit c2cf12857187aa147c268651f10acd6da2c9cb74) --- Misc/NEWS | 3 +++ Python/bltinmodule.c | 21 ++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index df0975a4d5ea22..98b47bdab4a8f1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -41,6 +41,9 @@ Extension Modules Library ------- +- bpo-8256: Fixed possible failing or crashing input() if attributes "encoding" + or "errors" of sys.stdin or sys.stdout are not set or are not strings. + - bpo-28298: Fix a bug that prevented array 'Q', 'L' and 'I' from accepting big intables (objects that have __int__) as elements. Patch by Oren Milman. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 33d2cc2dc8e2cf..17c074a1b3b26b 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1892,12 +1892,15 @@ builtin_input_impl(PyObject *module, PyObject *prompt) PyObject *result; size_t len; + /* stdin is a text stream, so it must have an encoding. */ stdin_encoding = _PyObject_GetAttrId(fin, &PyId_encoding); stdin_errors = _PyObject_GetAttrId(fin, &PyId_errors); - if (!stdin_encoding || !stdin_errors) - /* stdin is a text stream, so it must have an - encoding. */ + if (!stdin_encoding || !stdin_errors || + !PyUnicode_Check(stdin_encoding) || + !PyUnicode_Check(stdin_errors)) { + tty = 0; goto _readline_errors; + } stdin_encoding_str = _PyUnicode_AsString(stdin_encoding); stdin_errors_str = _PyUnicode_AsString(stdin_errors); if (!stdin_encoding_str || !stdin_errors_str) @@ -1913,8 +1916,12 @@ builtin_input_impl(PyObject *module, PyObject *prompt) PyObject *stringpo; stdout_encoding = _PyObject_GetAttrId(fout, &PyId_encoding); stdout_errors = _PyObject_GetAttrId(fout, &PyId_errors); - if (!stdout_encoding || !stdout_errors) + if (!stdout_encoding || !stdout_errors || + !PyUnicode_Check(stdout_encoding) || + !PyUnicode_Check(stdout_errors)) { + tty = 0; goto _readline_errors; + } stdout_encoding_str = _PyUnicode_AsString(stdout_encoding); stdout_errors_str = _PyUnicode_AsString(stdout_errors); if (!stdout_encoding_str || !stdout_errors_str) @@ -1969,13 +1976,17 @@ builtin_input_impl(PyObject *module, PyObject *prompt) Py_XDECREF(po); PyMem_FREE(s); return result; + _readline_errors: Py_XDECREF(stdin_encoding); Py_XDECREF(stdout_encoding); Py_XDECREF(stdin_errors); Py_XDECREF(stdout_errors); Py_XDECREF(po); - return NULL; + if (tty) + return NULL; + + PyErr_Clear(); } /* Fallback if we're not interactive */ From 216803d8e10615c769571fbfbd1f341557f25a14 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sun, 12 Mar 2017 17:03:46 -0400 Subject: [PATCH 078/340] Fix wrapping into StopIteration of return values in generators and coroutines (#644) (#648) --- Lib/test/test_coroutines.py | 15 +++++++++++++++ Misc/NEWS | 2 ++ Objects/genobject.c | 3 +-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 4a327b5ba9f168..6d63cdb5f0fcc9 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -975,6 +975,21 @@ async def waiter(coro): "coroutine is being awaited already"): waiter(coro).send(None) + def test_await_16(self): + # See https://bugs.python.org/issue29600 for details. + + async def f(): + return ValueError() + + async def g(): + try: + raise KeyError + except: + return await f() + + _, result = run_async(g()) + self.assertIsNone(result.__context__) + def test_with_1(self): class Manager: def __init__(self, name): diff --git a/Misc/NEWS b/Misc/NEWS index 98b47bdab4a8f1..e56c0914b1b8d2 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-29600: Fix wrapping coroutine return values in StopIteration. + - Issue #29537: Restore runtime compatibility with bytecode files generated by CPython 3.5.0 to 3.5.2, and adjust the eval loop to avoid the problems that could be caused by the malformed variant of the BUILD_MAP_UNPACK_WITH_CALL diff --git a/Objects/genobject.c b/Objects/genobject.c index d403598181abd4..0de540898d5e15 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -466,8 +466,7 @@ _PyGen_SetStopIterationValue(PyObject *value) PyObject *e; if (value == NULL || - (!PyTuple_Check(value) && - !PyObject_TypeCheck(value, (PyTypeObject *) PyExc_StopIteration))) + (!PyTuple_Check(value) && !PyExceptionInstance_Check(value))) { /* Delay exception instantiation if we can */ PyErr_SetObject(PyExc_StopIteration, value); From db522dc86294a99f46a63cd5b54c7c4ab8017c96 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sun, 12 Mar 2017 17:06:04 -0400 Subject: [PATCH 079/340] bpo-29742: asyncio get_extra_info() throws exception (#525) (#646) --- Lib/asyncio/sslproto.py | 4 +++- Lib/test/test_asyncio/test_sslproto.py | 12 ++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index c2c4b95fcbc803..aa5e03423766c4 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -542,8 +542,10 @@ def eof_received(self): def _get_extra_info(self, name, default=None): if name in self._extra: return self._extra[name] - else: + elif self._transport is not None: return self._transport.get_extra_info(name, default) + else: + return default def _start_shutdown(self): if self._in_shutdown: diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 59ff0f6967e5b5..f1771c5561afea 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -95,5 +95,17 @@ def test_connection_lost(self): test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionAbortedError) + def test_get_extra_info_on_closed_connection(self): + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + self.assertIsNone(ssl_proto._get_extra_info('socket')) + default = object() + self.assertIs(ssl_proto._get_extra_info('socket', default), default) + self.connection_made(ssl_proto) + self.assertIsNotNone(ssl_proto._get_extra_info('socket')) + ssl_proto.connection_lost(None) + self.assertIsNone(ssl_proto._get_extra_info('socket')) + + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index e56c0914b1b8d2..f12b5e665512ff 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,9 @@ Extension Modules Library ------- +- bpo-29742: get_extra_info() raises exception if get called on closed ssl transport. + Patch by Nikolay Kim. + - bpo-8256: Fixed possible failing or crashing input() if attributes "encoding" or "errors" of sys.stdin or sys.stdout are not set or are not strings. From 3a8098f679a7ad6fd890aaabf145b2ffdb376a2a Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 13 Mar 2017 10:36:54 +0800 Subject: [PATCH 080/340] fix the name of argument to ftplib.FTP.set_pasv and fix wording (GH-653) (GH-655) --- Doc/library/ftplib.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index 1e35f37f448bcd..a0cbe93e3a75c4 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -248,9 +248,9 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. prints the line to ``sys.stdout``. -.. method:: FTP.set_pasv(boolean) +.. method:: FTP.set_pasv(val) - Enable "passive" mode if *boolean* is true, other disable passive mode. + Enable "passive" mode if *val* is true, otherwise disable passive mode. Passive mode is on by default. From 59883bb25263318b25a817cc6e5af2b1a1246443 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 13 Mar 2017 11:06:58 +0800 Subject: [PATCH 081/340] ftplib.FTP.retrbinary callback gets a bytes, not a str (GH-652) (GH-658) --- Doc/library/ftplib.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst index a0cbe93e3a75c4..f0e19bde452861 100644 --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -228,7 +228,7 @@ followed by ``lines`` for the text version or ``binary`` for the binary version. Retrieve a file in binary transfer mode. *cmd* should be an appropriate ``RETR`` command: ``'RETR filename'``. The *callback* function is called for - each block of data received, with a single string argument giving the data + each block of data received, with a single bytes argument giving the data block. The optional *blocksize* argument specifies the maximum chunk size to read on the low-level socket object created to do the actual transfer (which will also be the largest size of the data blocks passed to *callback*). A From 0641ada9b78b6a06f539d4bde42c1ad1b90579a7 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Wed, 15 Mar 2017 08:42:30 +0100 Subject: [PATCH 082/340] bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords are not strings (#649) (#672) --- Lib/test/test_functools.py | 26 ++++++++++++++++++++++++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/_functoolsmodule.c | 5 ++++- 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index a82ca7ab88c38f..04ffab9a82dfc2 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -387,6 +387,32 @@ def __getitem__(self, key): self.assertRaises(TypeError, f.__setstate__, BadSequence()) + def test_manually_adding_non_string_keyword(self): + p = self.partial(capture) + # Adding a non-string/unicode keyword to partial kwargs + p.keywords[1234] = 'value' + r = repr(p) + self.assertIn('1234', r) + self.assertIn("'value'", r) + with self.assertRaises(TypeError): + p() + + def test_keystr_replaces_value(self): + p = self.partial(capture) + + class MutatesYourDict(object): + def __str__(self): + p.keywords[self] = ['sth2'] + return 'astr' + + # Raplacing the value during key formatting should keep the original + # value alive (at least long enough). + p.keywords[MutatesYourDict()] = ['sth'] + r = repr(p) + self.assertIn('astr', r) + self.assertIn("['sth']", r) + + class TestPartialPy(TestPartial, unittest.TestCase): partial = staticmethod(py_functools.partial) diff --git a/Misc/ACKS b/Misc/ACKS index d33ee913f49c41..8a952a45f5dcd4 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1348,6 +1348,7 @@ Federico Schwindt Barry Scott Steven Scott Nick Seidenman +Michael Seifert Žiga Seilnacht Yury Selivanov Fred Sells diff --git a/Misc/NEWS b/Misc/NEWS index f12b5e665512ff..40d87e291d0f6e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,9 @@ Extension Modules Library ------- +- bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords + are not strings. Patch by Michael Seifert. + - bpo-29742: get_extra_info() raises exception if get called on closed ssl transport. Patch by Nikolay Kim. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 0471d665e65a58..985bcb6985e835 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -234,8 +234,11 @@ partial_repr(partialobject *pto) /* Pack keyword arguments */ assert (PyDict_Check(pto->kw)); for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { - Py_SETREF(arglist, PyUnicode_FromFormat("%U, %U=%R", arglist, + /* Prevent key.__str__ from deleting the value. */ + Py_INCREF(value); + Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist, key, value)); + Py_DECREF(value); if (arglist == NULL) goto done; } From 9a29d7577a6da0ab0f4411567204f1a93a2452b6 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Wed, 15 Mar 2017 14:13:09 +0300 Subject: [PATCH 083/340] Change assertRaises to assertRaisesRegex in test_xmlrpc (#481) (#675) (cherry picked from commit c6b448b36d22769c684bb3276f85c1b47d15ab63) --- Lib/test/test_xmlrpc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 7e023c16733196..c2de057ecbfaa4 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -364,7 +364,7 @@ def test_registered_func_is_none(self): dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() dispatcher.register_function(None, name='method') - with self.assertRaises(Exception, expected_regex='method'): + with self.assertRaisesRegex(Exception, 'method'): dispatcher._dispatch('method', ('param',)) def test_instance_has_no_func(self): @@ -372,14 +372,14 @@ def test_instance_has_no_func(self): dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() dispatcher.register_instance(object()) - with self.assertRaises(Exception, expected_regex='method'): + with self.assertRaisesRegex(Exception, 'method'): dispatcher._dispatch('method', ('param',)) def test_cannot_locate_func(self): """Calls a function that the dispatcher cannot locate""" dispatcher = xmlrpc.server.SimpleXMLRPCDispatcher() - with self.assertRaises(Exception, expected_regex='method'): + with self.assertRaisesRegex(Exception, 'method'): dispatcher._dispatch('method', ('param',)) From 00cbb8a0fa49b23ba15001d5a754717d07f824f9 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Thu, 16 Mar 2017 10:45:41 -0700 Subject: [PATCH 084/340] Takes vcruntime140.dll from the correct source. (#683) --- Tools/msi/make_zip.proj | 9 +++------ Tools/nuget/make_pkg.proj | 8 +++----- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Tools/msi/make_zip.proj b/Tools/msi/make_zip.proj index 1af6dd2868a1b9..1ff5fc549abb2e 100644 --- a/Tools/msi/make_zip.proj +++ b/Tools/msi/make_zip.proj @@ -17,15 +17,12 @@ rmdir /q/s "$(IntermediateOutputPath)\zip_$(ArchName)" "$(PythonExe)" "$(MSBuildThisFileDirectory)\make_zip.py" $(Arguments) -e -o "$(TargetPath)" -t "$(IntermediateOutputPath)\zip_$(ArchName)" -b "$(BuildPath.TrimEnd('\'))" - set DOC_FILENAME=python$(PythonVersion).chm -set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT + set DOC_FILENAME=python$(PythonVersion).chm + $(Environment)%0D%0Aset VCREDIST_PATH=$(CRTRedist)\$(Platform) - + diff --git a/Tools/nuget/make_pkg.proj b/Tools/nuget/make_pkg.proj index 81b84f98846b78..21acc2aa2e3c6e 100644 --- a/Tools/nuget/make_pkg.proj +++ b/Tools/nuget/make_pkg.proj @@ -34,9 +34,8 @@ $(NugetArguments) -Version "$(NuspecVersion)" $(NugetArguments) -NoPackageAnalysis -NonInteractive - setlocal -set DOC_FILENAME=python$(PythonVersion).chm -set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140.CRT + set DOC_FILENAME=python$(PythonVersion).chm + $(Environment)%0D%0Aset VCREDIST_PATH=$(CRTRedist)\$(Platform) @@ -45,8 +44,7 @@ set VCREDIST_PATH=$(VS140COMNTOOLS)\..\..\VC\redist\$(Platform)\Microsoft.VC140. - + From 091d90f9a429b81b046cb83582062941f8ded9da Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 16 Mar 2017 19:57:12 -0700 Subject: [PATCH 085/340] bpo-29820: othergui.rst: Remove outdated information (GH-685) (GH-689) (cherry picked from commit 1bb0f3762ec5104014aeed0ae6e9d64598d8fcac) --- Doc/library/othergui.rst | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Doc/library/othergui.rst b/Doc/library/othergui.rst index ee1ce50b6bd5e1..d40abe167653b7 100644 --- a/Doc/library/othergui.rst +++ b/Doc/library/othergui.rst @@ -9,14 +9,15 @@ available for Python: .. seealso:: `PyGObject `_ - provides introspection bindings for C libraries using + PyGObject provides introspection bindings for C libraries using `GObject `_. One of these libraries is the `GTK+ 3 `_ widget set. GTK+ comes with many more widgets than Tkinter provides. An online `Python GTK+ 3 Tutorial `_ is available. - `PyGTK `_ provides bindings for an older version + `PyGTK `_ + PyGTK provides bindings for an older version of the library, GTK+ 2. It provides an object oriented interface that is slightly higher level than the C one. There are also bindings to `GNOME `_. An online `tutorial @@ -27,15 +28,10 @@ available for Python: extensive C++ GUI application development framework that is available for Unix, Windows and Mac OS X. :program:`sip` is a tool for generating bindings for C++ libraries as Python classes, and - is specifically designed for Python. The *PyQt3* bindings have a - book, `GUI Programming with Python: QT Edition - `_ by Boudewijn - Rempt. The *PyQt4* bindings also have a book, `Rapid GUI Programming - with Python and Qt `_, by Mark - Summerfield. + is specifically designed for Python. `PySide `_ - is a newer binding to the Qt toolkit, provided by Nokia. + PySide is a newer binding to the Qt toolkit, provided by Nokia. Compared to PyQt, its licensing scheme is friendlier to non-open source applications. @@ -49,9 +45,7 @@ available for Python: documentation and context sensitive help, printing, HTML viewing, low-level device context drawing, drag and drop, system clipboard access, an XML-based resource format and more, including an ever growing library - of user-contributed modules. wxPython has a book, `wxPython in Action - `_, by Noel Rappin and - Robin Dunn. + of user-contributed modules. PyGTK, PyQt, and wxPython, all have a modern look and feel and more widgets than Tkinter. In addition, there are many other GUI toolkits for From 41b4a2189f29daae008e57f799a30890643d191f Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Fri, 17 Mar 2017 14:37:51 +0300 Subject: [PATCH 086/340] bpo-16355: Clarify when inspect.getcomments() returns None (#428) (#691) Initial patch by Vajrasky Kok. (cherry picked from commit 3f2155ffe683080f2a1b28408fa48d43ba92f943) --- Doc/library/inspect.rst | 4 +++- Lib/test/test_inspect.py | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 89263e7bec1795..9526a0d59dabb5 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -440,7 +440,9 @@ Retrieving source code Return in a single string any lines of comments immediately preceding the object's source code (for a class, function, or method), or at the top of the - Python source file (if the object is a module). + Python source file (if the object is a module). If the object's source code + is unavailable, return ``None``. This could happen if the object has been + defined in C or the interactive shell. .. function:: getfile(object) diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index d33de9e5bc3f78..2283000c860246 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -376,6 +376,11 @@ def test_cleandoc(self): def test_getcomments(self): self.assertEqual(inspect.getcomments(mod), '# line 1\n') self.assertEqual(inspect.getcomments(mod.StupidGit), '# line 20\n') + # If the object source file is not available, return None. + co = compile('x=1', '_non_existing_filename.py', 'exec') + self.assertIsNone(inspect.getcomments(co)) + # If the object has been defined in C, return None. + self.assertIsNone(inspect.getcomments(list)) def test_getmodule(self): # Check actual module From e59af55c28b657cdf57c71a7b0837c9e9f4b2a31 Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Fri, 17 Mar 2017 19:54:50 +0000 Subject: [PATCH 087/340] bpo-29808: Do not fail in SysLogHandler constructor if syslog isn't available. (#695) bpo-29808: SysLogHandler: Do not fail if initial connect to syslog failed. (cherry picked from commit 1b038e073807ecb6fd176edaf3386a8e3205416e) --- Lib/logging/handlers.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index c39a56ff066d22..e3463312f94065 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -803,7 +803,14 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT), if isinstance(address, str): self.unixsocket = True - self._connect_unixsocket(address) + # Syslog server may be unavailable during handler initialisation. + # C's openlog() function also ignores connection errors. + # Moreover, we ignore these errors while logging, so it not worse + # to ignore it also here. + try: + self._connect_unixsocket(address) + except OSError: + pass else: self.unixsocket = False if socktype is None: From 825153bf8fd3b8ee80cf580d24b1a1b64bd8f4d1 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 17 Mar 2017 15:41:48 -0700 Subject: [PATCH 088/340] Combine the C++ header CI build into the main C build (GH-697) (GH-705) This will eliminate one of the builds in Travis, allowing for CI overall to complete faster. (cherry picked from commit 993d4b3440f2282976901ce66879037c4443868a) --- .travis.yml | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 27b63c6c08b376..36961e38790a4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -64,15 +64,6 @@ matrix: # Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files. - source ./venv/bin/activate - bash <(curl -s https://codecov.io/bash) - - os: linux - language: cpp - compiler: clang - env: - - TESTING="C++ header compatibility" - before_script: - - ./configure - script: - - echo '#include "Python.h"' > test.cc && $CXX -c test.cc -o /dev/null -I ./Include -I . # Travis provides only 2 cores, so don't overdue the parallelism and waste memory. before_script: @@ -88,6 +79,8 @@ before_script: script: # `-r -w` implicitly provided through `make buildbottest`. - make buildbottest TESTOPTS="-j4" + # Test for C++ header compatibility. + - echo '#include "Python.h"' > test.cc && $CXX -c test.cc -o /dev/null -I ./Include -I . notifications: email: false From 3091636f16cdf9ed46bffa770fb3ec7c332799cf Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sun, 19 Mar 2017 10:03:48 -0700 Subject: [PATCH 089/340] Drop C++ header compatibility test (#718) (#720) The $CXX environment variable is not exported under the 'c' language on Travis. (cherry picked from commit 77ed11552da3e01dd235b7d68988076866b1f604) --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 36961e38790a4d..66f03dc7161a7f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -79,8 +79,6 @@ before_script: script: # `-r -w` implicitly provided through `make buildbottest`. - make buildbottest TESTOPTS="-j4" - # Test for C++ header compatibility. - - echo '#include "Python.h"' > test.cc && $CXX -c test.cc -o /dev/null -I ./Include -I . notifications: email: false From 88b32eb7b317dd7c7943433f980e17e34e50f8f8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 19 Mar 2017 20:26:42 +0200 Subject: [PATCH 090/340] bpo-28749: Fixed the documentation of the mapping codec APIs. (#487) (#715) Added the documentation for PyUnicode_Translate(). (cherry picked from commit c85a26628ceb9624c96c3064e8b99033c026d8a3) --- Doc/c-api/unicode.rst | 95 +++++++++++++++++++++-------------------- Include/unicodeobject.h | 45 ++++++++----------- 2 files changed, 66 insertions(+), 74 deletions(-) diff --git a/Doc/c-api/unicode.rst b/Doc/c-api/unicode.rst index 256fef3b2774a9..54d0373881d60b 100644 --- a/Doc/c-api/unicode.rst +++ b/Doc/c-api/unicode.rst @@ -1388,77 +1388,78 @@ Character Map Codecs This codec is special in that it can be used to implement many different codecs (and this is in fact what was done to obtain most of the standard codecs included in the :mod:`encodings` package). The codec uses mapping to encode and -decode characters. - -Decoding mappings must map single string characters to single Unicode -characters, integers (which are then interpreted as Unicode ordinals) or ``None`` -(meaning "undefined mapping" and causing an error). - -Encoding mappings must map single Unicode characters to single string -characters, integers (which are then interpreted as Latin-1 ordinals) or ``None`` -(meaning "undefined mapping" and causing an error). - -The mapping objects provided must only support the __getitem__ mapping -interface. - -If a character lookup fails with a LookupError, the character is copied as-is -meaning that its ordinal value will be interpreted as Unicode or Latin-1 ordinal -resp. Because of this, mappings only need to contain those mappings which map -characters to different code points. +decode characters. The mapping objects provided must support the +:meth:`__getitem__` mapping interface; dictionaries and sequences work well. These are the mapping codec APIs: -.. c:function:: PyObject* PyUnicode_DecodeCharmap(const char *s, Py_ssize_t size, \ +.. c:function:: PyObject* PyUnicode_DecodeCharmap(const char *data, Py_ssize_t size, \ PyObject *mapping, const char *errors) - Create a Unicode object by decoding *size* bytes of the encoded string *s* using - the given *mapping* object. Return *NULL* if an exception was raised by the - codec. If *mapping* is *NULL* latin-1 decoding will be done. Else it can be a - dictionary mapping byte or a unicode string, which is treated as a lookup table. - Byte values greater that the length of the string and U+FFFE "characters" are - treated as "undefined mapping". + Create a Unicode object by decoding *size* bytes of the encoded string *s* + using the given *mapping* object. Return *NULL* if an exception was raised + by the codec. + + If *mapping* is *NULL*, Latin-1 decoding will be applied. Else + *mapping* must map bytes ordinals (integers in the range from 0 to 255) + to Unicode strings, integers (which are then interpreted as Unicode + ordinals) or ``None``. Unmapped data bytes -- ones which cause a + :exc:`LookupError`, as well as ones which get mapped to ``None``, + ``0xFFFE`` or ``'\ufffe'``, are treated as undefined mappings and cause + an error. .. c:function:: PyObject* PyUnicode_AsCharmapString(PyObject *unicode, PyObject *mapping) - Encode a Unicode object using the given *mapping* object and return the result - as Python string object. Error handling is "strict". Return *NULL* if an + Encode a Unicode object using the given *mapping* object and return the + result as a bytes object. Error handling is "strict". Return *NULL* if an exception was raised by the codec. -The following codec API is special in that maps Unicode to Unicode. - + The *mapping* object must map Unicode ordinal integers to bytes objects, + integers in the range from 0 to 255 or ``None``. Unmapped character + ordinals (ones which cause a :exc:`LookupError`) as well as mapped to + ``None`` are treated as "undefined mapping" and cause an error. -.. c:function:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, \ - PyObject *table, const char *errors) - - Translate a :c:type:`Py_UNICODE` buffer of the given *size* by applying a - character mapping *table* to it and return the resulting Unicode object. Return - *NULL* when an exception was raised by the codec. - The *mapping* table must map Unicode ordinal integers to Unicode ordinal - integers or ``None`` (causing deletion of the character). +.. c:function:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, \ + PyObject *mapping, const char *errors) - Mapping tables need only provide the :meth:`__getitem__` interface; dictionaries - and sequences work well. Unmapped character ordinals (ones which cause a - :exc:`LookupError`) are left untouched and are copied as-is. + Encode the :c:type:`Py_UNICODE` buffer of the given *size* using the given + *mapping* object and return the result as a bytes object. Return *NULL* if + an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_Translate`. or :ref:`generic codec based API - ` + :c:func:`PyUnicode_AsCharmapString` or + :c:func:`PyUnicode_AsEncodedString`. -.. c:function:: PyObject* PyUnicode_EncodeCharmap(const Py_UNICODE *s, Py_ssize_t size, \ +The following codec API is special in that maps Unicode to Unicode. + +.. c:function:: PyObject* PyUnicode_Translate(PyObject *unicode, \ PyObject *mapping, const char *errors) - Encode the :c:type:`Py_UNICODE` buffer of the given *size* using the given - *mapping* object and return a Python string object. Return *NULL* if an - exception was raised by the codec. + Translate a Unicode object using the given *mapping* object and return the + resulting Unicode object. Return *NULL* if an exception was raised by the + codec. + + The *mapping* object must map Unicode ordinal integers to Unicode strings, + integers (which are then interpreted as Unicode ordinals) or ``None`` + (causing deletion of the character). Unmapped character ordinals (ones + which cause a :exc:`LookupError`) are left untouched and are copied as-is. + + +.. c:function:: PyObject* PyUnicode_TranslateCharmap(const Py_UNICODE *s, Py_ssize_t size, \ + PyObject *mapping, const char *errors) + + Translate a :c:type:`Py_UNICODE` buffer of the given *size* by applying a + character *mapping* table to it and return the resulting Unicode object. + Return *NULL* when an exception was raised by the codec. .. deprecated-removed:: 3.3 4.0 Part of the old-style :c:type:`Py_UNICODE` API; please migrate to using - :c:func:`PyUnicode_AsCharmapString` or - :c:func:`PyUnicode_AsEncodedString`. + :c:func:`PyUnicode_Translate`. or :ref:`generic codec based API + ` MBCS codecs for Windows diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 9308a6aa96af90..0accc1d5c2ddad 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1570,50 +1570,41 @@ PyAPI_FUNC(PyObject*) PyUnicode_EncodeASCII( This codec uses mappings to encode and decode characters. - Decoding mappings must map single string characters to single - Unicode characters, integers (which are then interpreted as Unicode - ordinals) or None (meaning "undefined mapping" and causing an - error). - - Encoding mappings must map single Unicode characters to single - string characters, integers (which are then interpreted as Latin-1 - ordinals) or None (meaning "undefined mapping" and causing an - error). - - If a character lookup fails with a LookupError, the character is - copied as-is meaning that its ordinal value will be interpreted as - Unicode or Latin-1 ordinal resp. Because of this mappings only need - to contain those mappings which map characters to different code - points. + Decoding mappings must map byte ordinals (integers in the range from 0 to + 255) to Unicode strings, integers (which are then interpreted as Unicode + ordinals) or None. Unmapped data bytes (ones which cause a LookupError) + as well as mapped to None, 0xFFFE or '\ufffe' are treated as "undefined + mapping" and cause an error. + + Encoding mappings must map Unicode ordinal integers to bytes objects, + integers in the range from 0 to 255 or None. Unmapped character + ordinals (ones which cause a LookupError) as well as mapped to + None are treated as "undefined mapping" and cause an error. */ PyAPI_FUNC(PyObject*) PyUnicode_DecodeCharmap( const char *string, /* Encoded string */ Py_ssize_t length, /* size of string */ - PyObject *mapping, /* character mapping - (char ordinal -> unicode ordinal) */ + PyObject *mapping, /* decoding mapping */ const char *errors /* error handling */ ); PyAPI_FUNC(PyObject*) PyUnicode_AsCharmapString( PyObject *unicode, /* Unicode object */ - PyObject *mapping /* character mapping - (unicode ordinal -> char ordinal) */ + PyObject *mapping /* encoding mapping */ ); #ifndef Py_LIMITED_API PyAPI_FUNC(PyObject*) PyUnicode_EncodeCharmap( const Py_UNICODE *data, /* Unicode char buffer */ Py_ssize_t length, /* Number of Py_UNICODE chars to encode */ - PyObject *mapping, /* character mapping - (unicode ordinal -> char ordinal) */ + PyObject *mapping, /* encoding mapping */ const char *errors /* error handling */ ); PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( PyObject *unicode, /* Unicode object */ - PyObject *mapping, /* character mapping - (unicode ordinal -> char ordinal) */ + PyObject *mapping, /* encoding mapping */ const char *errors /* error handling */ ); #endif @@ -1622,8 +1613,8 @@ PyAPI_FUNC(PyObject*) _PyUnicode_EncodeCharmap( character mapping table to it and return the resulting Unicode object. - The mapping table must map Unicode ordinal integers to Unicode - ordinal integers or None (causing deletion of the character). + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). Mapping tables may be dictionaries or sequences. Unmapped character ordinals (ones which cause a LookupError) are left untouched and @@ -1915,8 +1906,8 @@ PyAPI_FUNC(PyObject*) PyUnicode_RSplit( /* Translate a string by applying a character mapping table to it and return the resulting Unicode object. - The mapping table must map Unicode ordinal integers to Unicode - ordinal integers or None (causing deletion of the character). + The mapping table must map Unicode ordinal integers to Unicode strings, + Unicode ordinal integers or None (causing deletion of the character). Mapping tables may be dictionaries or sequences. Unmapped character ordinals (ones which cause a LookupError) are left untouched and From 2c5b2c3832d4d2af7b60333a5a8f73dd51ef6245 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 19 Mar 2017 21:06:44 +0200 Subject: [PATCH 091/340] bpo-29116: Fix error messages for concatenating bytes and bytearray with unsupported type. (#709) (#724) (cherry picked from commit 6b5a9ec4788770c652bac3bf5d5a0a3b710b82ae) --- Objects/bytearrayobject.c | 2 +- Objects/bytesobject.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 3fad6d80b59e5a..5132eba52bf5ac 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -254,7 +254,7 @@ PyByteArray_Concat(PyObject *a, PyObject *b) if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name); goto done; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 673bb00b984370..8ede5f0c599671 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1272,7 +1272,7 @@ bytes_concat(PyObject *a, PyObject *b) if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", - Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name); + Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name); goto done; } From bb67f10179011c50805a942cb6f2701c84854888 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 19 Mar 2017 21:38:53 +0200 Subject: [PATCH 092/340] bpo-29845: Mark tests that use _testcapi as CPython-only (#711) (#726) (cherry picked from commit 24c738a9e91b8f46da6166663d8ce7ec18cec784) --- Lib/ctypes/test/test_structures.py | 5 ++++- Lib/test/test_atexit.py | 1 + Lib/test/test_coroutines.py | 1 + Lib/test/test_socket.py | 1 + Lib/test/test_tracemalloc.py | 1 + 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index 0b9391a4dbb5a7..2e9fc7c49cc499 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -2,8 +2,8 @@ from ctypes import * from ctypes.test import need_symbol from struct import calcsize -import _testcapi import _ctypes_test +import test.support class SubclassesTest(unittest.TestCase): def test_subclass(self): @@ -202,7 +202,10 @@ class X(Structure): "_pack_": -1} self.assertRaises(ValueError, type(Structure), "X", (Structure,), d) + @test.support.cpython_only + def test_packed_c_limits(self): # Issue 15989 + import _testcapi d = {"_fields_": [("a", c_byte)], "_pack_": _testcapi.INT_MAX + 1} self.assertRaises(ValueError, type(Structure), "X", (Structure,), d) diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index 172bd25419cea7..c761076c4a0225 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -143,6 +143,7 @@ def test_bound_methods(self): self.assertEqual(l, [5]) +@support.cpython_only class SubinterpreterTest(unittest.TestCase): def test_callbacks_leak(self): diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 6d63cdb5f0fcc9..402fbe845765e5 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1772,6 +1772,7 @@ def wrap(gen): sys.set_coroutine_wrapper(None) +@support.cpython_only class CAPITest(unittest.TestCase): def test_tp_await_1(self): diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 70c03f9c468a21..b72fc8fbf0cadd 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -876,6 +876,7 @@ def testNtoH(self): self.assertEqual(swapped & mask, mask) self.assertRaises(OverflowError, func, 1<<34) + @support.cpython_only def testNtoHErrors(self): good_values = [ 1, 2, 3, 1, 2, 3 ] bad_values = [ -1, -2, -3, -1, -2, -3 ] diff --git a/Lib/test/test_tracemalloc.py b/Lib/test/test_tracemalloc.py index da89a9a8715935..2d1a9b3cfb20af 100644 --- a/Lib/test/test_tracemalloc.py +++ b/Lib/test/test_tracemalloc.py @@ -809,6 +809,7 @@ def test_sys_xoptions_invalid(self): b'number of frames', stderr) + @support.cpython_only def test_pymem_alloc0(self): # Issue #21639: Check that PyMem_Malloc(0) with tracemalloc enabled # does not crash. From 08612ed6a91003cdba7617dee7787c26495c50d9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 20 Mar 2017 00:51:16 +0200 Subject: [PATCH 093/340] bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. (#514) (#727) (cherry picked from commit a5af6e1af77ee0f9294c5776478a9c24d9fbab94) --- Lib/test/test_fileio.py | 9 ++++++++- Lib/test/test_io.py | 20 ++++++++++++++++++++ Misc/NEWS | 2 ++ Modules/_io/bufferedio.c | 14 ++++++++++++-- Modules/_io/fileio.c | 16 +++++++++++++--- Modules/_io/textio.c | 23 ++++++++++++++++++++--- 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py index 12f2f119b5e903..1bc1847a360cc7 100644 --- a/Lib/test/test_fileio.py +++ b/Lib/test/test_fileio.py @@ -9,7 +9,8 @@ from weakref import proxy from functools import wraps -from test.support import TESTFN, check_warnings, run_unittest, make_bad_fd, cpython_only +from test.support import (TESTFN, check_warnings, run_unittest, + make_bad_fd, cpython_only, swap_attr) from collections import UserList import _io # C implementation of io @@ -175,6 +176,12 @@ def testReprNoCloseFD(self): finally: os.close(fd) + def testRecursiveRepr(self): + # Issue #25455 + with swap_attr(self.f, 'name', self.f): + with self.assertRaises(RuntimeError): + repr(self.f) # Should not crash + def testErrors(self): f = self.f self.assertFalse(f.isatty()) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index 5111882a0258e9..ab24ca110dd929 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -981,6 +981,16 @@ def test_repr(self): raw.name = b"dummy" self.assertEqual(repr(b), "<%s name=b'dummy'>" % clsname) + def test_recursive_repr(self): + # Issue #25455 + raw = self.MockRawIO() + b = self.tp(raw) + with support.swap_attr(raw, 'name', b): + try: + repr(b) # Should not crash + except RuntimeError: + pass + def test_flush_error_on_close(self): # Test that buffered file is closed despite failed flush # and that flush() is called before file closed. @@ -2391,6 +2401,16 @@ def test_repr(self): t.buffer.detach() repr(t) # Should not raise an exception + def test_recursive_repr(self): + # Issue #25455 + raw = self.BytesIO() + t = self.TextIOWrapper(raw) + with support.swap_attr(raw, 'name', t): + try: + repr(t) # Should not crash + except RuntimeError: + pass + def test_line_buffering(self): r = self.BytesIO() b = self.BufferedWriter(r, 1000) diff --git a/Misc/NEWS b/Misc/NEWS index 40d87e291d0f6e..1005bc54358819 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -43,6 +43,8 @@ Extension Modules Library ------- +- bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. + - bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords are not strings. Patch by Michael Seifert. diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 6d67751c7d6b08..909c4fa84659e5 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -1416,8 +1416,18 @@ buffered_repr(buffered *self) res = PyUnicode_FromFormat("<%s>", Py_TYPE(self)->tp_name); } else { - res = PyUnicode_FromFormat("<%s name=%R>", - Py_TYPE(self)->tp_name, nameobj); + int status = Py_ReprEnter((PyObject *)self); + res = NULL; + if (status == 0) { + res = PyUnicode_FromFormat("<%s name=%R>", + Py_TYPE(self)->tp_name, nameobj); + Py_ReprLeave((PyObject *)self); + } + else if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } Py_DECREF(nameobj); } return res; diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index 919cf502dca4ac..c77f05521d080c 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1093,9 +1093,19 @@ fileio_repr(fileio *self) self->fd, mode_string(self), self->closefd ? "True" : "False"); } else { - res = PyUnicode_FromFormat( - "<_io.FileIO name=%R mode='%s' closefd=%s>", - nameobj, mode_string(self), self->closefd ? "True" : "False"); + int status = Py_ReprEnter((PyObject *)self); + res = NULL; + if (status == 0) { + res = PyUnicode_FromFormat( + "<_io.FileIO name=%R mode='%s' closefd=%s>", + nameobj, mode_string(self), self->closefd ? "True" : "False"); + Py_ReprLeave((PyObject *)self); + } + else if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } Py_DECREF(nameobj); } return res; diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 89b0798cd0b687..3ab11387bf722a 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -2483,6 +2483,7 @@ static PyObject * textiowrapper_repr(textio *self) { PyObject *nameobj, *modeobj, *res, *s; + int status; CHECK_INITIALIZED(self); @@ -2490,6 +2491,15 @@ textiowrapper_repr(textio *self) if (res == NULL) return NULL; + status = Py_ReprEnter((PyObject *)self); + if (status != 0) { + if (status > 0) { + PyErr_Format(PyExc_RuntimeError, + "reentrant call inside %s.__repr__", + Py_TYPE(self)->tp_name); + } + goto error; + } nameobj = _PyObject_GetAttrId((PyObject *) self, &PyId_name); if (nameobj == NULL) { if (PyErr_ExceptionMatches(PyExc_Exception)) @@ -2504,7 +2514,7 @@ textiowrapper_repr(textio *self) goto error; PyUnicode_AppendAndDel(&res, s); if (res == NULL) - return NULL; + goto error; } modeobj = _PyObject_GetAttrId((PyObject *) self, &PyId_mode); if (modeobj == NULL) { @@ -2520,14 +2530,21 @@ textiowrapper_repr(textio *self) goto error; PyUnicode_AppendAndDel(&res, s); if (res == NULL) - return NULL; + goto error; } s = PyUnicode_FromFormat("%U encoding=%R>", res, self->encoding); Py_DECREF(res); + if (status == 0) { + Py_ReprLeave((PyObject *)self); + } return s; -error: + + error: Py_XDECREF(res); + if (status == 0) { + Py_ReprLeave((PyObject *)self); + } return NULL; } From 7cc071c96b95e7422f64cb436d547c952e0ca52f Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 19 Mar 2017 20:58:34 -0700 Subject: [PATCH 094/340] bpo-29856: Fix typo in curses documentation (GH-730) (GH-732) From Shifted Dxit -> Shifted Exit in Doc/library/curses.rst (cherry picked from commit 64508780d72769e4c7afc67a511c057261c578f6) --- Doc/library/curses.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index d746eafaea9b5c..d51085506c2a96 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1443,7 +1443,7 @@ The exact keycaps available are system dependent. +-------------------+--------------------------------------------+ | ``KEY_SEOL`` | Shifted Clear line | +-------------------+--------------------------------------------+ -| ``KEY_SEXIT`` | Shifted Dxit | +| ``KEY_SEXIT`` | Shifted Exit | +-------------------+--------------------------------------------+ | ``KEY_SFIND`` | Shifted Find | +-------------------+--------------------------------------------+ From 4276068fe57e93b4c8d428f0b1cde8ca04b8fb99 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 20 Mar 2017 09:37:31 +0200 Subject: [PATCH 095/340] bpo-28876: bool of large range raises OverflowError (#699) (#735) (cherry picked from commit e46fb8611867fa3b407a813f53137929b7cb4a10) --- Lib/test/test_range.py | 17 +++++++++++++---- Misc/NEWS | 3 +++ Objects/rangeobject.c | 21 ++++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index c022f070bf52c7..90efa1a01e6ab1 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -98,20 +98,24 @@ def test_large_operands(self): x = range(10**20+10, 10**20, 3) self.assertEqual(len(x), 0) self.assertEqual(len(list(x)), 0) + self.assertFalse(x) x = range(10**20, 10**20+10, -3) self.assertEqual(len(x), 0) self.assertEqual(len(list(x)), 0) + self.assertFalse(x) x = range(10**20+10, 10**20, -3) self.assertEqual(len(x), 4) self.assertEqual(len(list(x)), 4) + self.assertTrue(x) # Now test range() with longs - self.assertEqual(list(range(-2**100)), []) - self.assertEqual(list(range(0, -2**100)), []) - self.assertEqual(list(range(0, 2**100, -1)), []) - self.assertEqual(list(range(0, 2**100, -1)), []) + for x in [range(-2**100), + range(0, -2**100), + range(0, 2**100, -1)]: + self.assertEqual(list(x), []) + self.assertFalse(x) a = int(10 * sys.maxsize) b = int(100 * sys.maxsize) @@ -152,6 +156,7 @@ def _range_len(x): step = x[1] - x[0] length = 1 + ((x[-1] - x[0]) // step) return length + a = -sys.maxsize b = sys.maxsize expected_len = b - a @@ -159,6 +164,7 @@ def _range_len(x): self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) + self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 @@ -176,6 +182,7 @@ def _range_len(x): self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) + self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 @@ -194,6 +201,7 @@ def _range_len(x): self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) + self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 @@ -212,6 +220,7 @@ def _range_len(x): self.assertIn(a, x) self.assertNotIn(b, x) self.assertRaises(OverflowError, len, x) + self.assertTrue(x) self.assertEqual(_range_len(x), expected_len) self.assertEqual(x[0], a) idx = sys.maxsize+1 diff --git a/Misc/NEWS b/Misc/NEWS index 1005bc54358819..e45cf3edfdaf8a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-28876: ``bool(range)`` works even if ``len(range)`` + raises :exc:`OverflowError`. + - bpo-29600: Fix wrapping coroutine return values in StopIteration. - Issue #29537: Restore runtime compatibility with bytecode files generated by diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 899697aa3a1639..f221fde83f33c8 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -675,6 +675,25 @@ static PyMappingMethods range_as_mapping = { (objobjargproc)0, /* mp_ass_subscript */ }; +static int +range_bool(rangeobject* self) +{ + return PyObject_IsTrue(self->length); +} + +static PyNumberMethods range_as_number = { + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + (inquiry)range_bool, /* nb_bool */ +}; + static PyObject * range_iter(PyObject *seq); static PyObject * range_reverse(PyObject *seq); @@ -714,7 +733,7 @@ PyTypeObject PyRange_Type = { 0, /* tp_setattr */ 0, /* tp_reserved */ (reprfunc)range_repr, /* tp_repr */ - 0, /* tp_as_number */ + &range_as_number, /* tp_as_number */ &range_as_sequence, /* tp_as_sequence */ &range_as_mapping, /* tp_as_mapping */ (hashfunc)range_hash, /* tp_hash */ From ed512cba78af211da4d83cbb7cc533c39176f374 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Tue, 21 Mar 2017 00:35:51 -0400 Subject: [PATCH 096/340] bpo-27593: Revise git SCM build info. (#744) (#746) Use --short form of git hash. Use output from "git describe" for tag. Expected outputs: 1. previous hg 2. previous git 3. updated git Release (tagged) build: 1. Python 3.7.0a0 (v3.7.0a0:4def2a2901a5, ... 2. Python 3.7.0a0 (v3.7.0a0^0:05f53735c8912f8df1077e897f052571e13c3496, ... 3. Python 3.7.0a0 (v3.7.0a0:05f53735c8, ... Development build: 1. Python 3.7.0a0 (default:41df79263a11, ... 2. Python 3.7.0a0 (master:05f53735c8912f8df1077e897f052571e13c3496, ... 3. Python 3.7.0a0 (heads/master-dirty:05f53735c8, ... "dirty" means the working tree has uncommitted changes. See "git help describe" for more info. (cherry picked from commit 554626ada769abf82a5dabe6966afa4265acb6a6) --- PCbuild/pythoncore.vcxproj | 4 ++-- configure | 4 ++-- configure.ac | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index b7e0f3cec534d4..6466a6b48b9b08 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -407,8 +407,8 @@ - - + + $([System.IO.File]::ReadAllText('$(IntDir)gitbranch.txt').Trim()) $([System.IO.File]::ReadAllText('$(IntDir)gitversion.txt').Trim()) diff --git a/configure b/configure index 640cad7c4aa45a..0f7484231a38ce 100755 --- a/configure +++ b/configure @@ -2884,8 +2884,8 @@ HAS_GIT=no-repository fi if test $HAS_GIT = found then - GITVERSION="git -C \$(srcdir) rev-parse HEAD" - GITTAG="git -C \$(srcdir) name-rev --tags --name-only HEAD" + GITVERSION="git -C \$(srcdir) rev-parse --short HEAD" + GITTAG="git -C \$(srcdir) describe --all --always --dirty" GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else GITVERSION="" diff --git a/configure.ac b/configure.ac index 4682341723f038..0eca886aebdc69 100644 --- a/configure.ac +++ b/configure.ac @@ -37,8 +37,8 @@ HAS_GIT=no-repository fi if test $HAS_GIT = found then - GITVERSION="git -C \$(srcdir) rev-parse HEAD" - GITTAG="git -C \$(srcdir) name-rev --tags --name-only HEAD" + GITVERSION="git -C \$(srcdir) rev-parse --short HEAD" + GITTAG="git -C \$(srcdir) describe --all --always --dirty" GITBRANCH="git -C \$(srcdir) name-rev --name-only HEAD" else GITVERSION="" From cb4beb6b89f992b7967ca3e7471d292789385b48 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Wed, 22 Mar 2017 16:03:27 +0800 Subject: [PATCH 097/340] fix function name in tabnanny documentation (GH-763) --- Doc/library/tabnanny.rst | 8 ++++---- Lib/tabnanny.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/tabnanny.rst b/Doc/library/tabnanny.rst index 1edb0fbabb2023..dfe688a2f93e0c 100644 --- a/Doc/library/tabnanny.rst +++ b/Doc/library/tabnanny.rst @@ -48,14 +48,14 @@ described below. .. exception:: NannyNag - Raised by :func:`tokeneater` if detecting an ambiguous indent. Captured and + Raised by :func:`process_tokens` if detecting an ambiguous indent. Captured and handled in :func:`check`. -.. function:: tokeneater(type, token, start, end, line) +.. function:: process_tokens(tokens) - This function is used by :func:`check` as a callback parameter to the function - :func:`tokenize.tokenize`. + This function is used by :func:`check` to process tokens generated by the + :mod:`tokenize` module. .. XXX document errprint, format_witnesses, Whitespace, check_equal, indents, reset_globals diff --git a/Lib/tabnanny.py b/Lib/tabnanny.py index 46e0f56a392ae6..bfb670c9027d76 100755 --- a/Lib/tabnanny.py +++ b/Lib/tabnanny.py @@ -59,7 +59,7 @@ def main(): class NannyNag(Exception): """ - Raised by tokeneater() if detecting an ambiguous indent. + Raised by process_tokens() if detecting an ambiguous indent. Captured and handled in check(). """ def __init__(self, lineno, msg, line): From d7df9e61c8ea1a7919466f82423bdbb0bfe1df61 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 22 Mar 2017 17:14:17 +0900 Subject: [PATCH 098/340] doc: minor fix for library/profile (GH-767) (cherry picked from commit bd3d8ba3b22da0bad018b53a3e6610ae03c5aa49) --- Doc/library/profile.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index bd67fe486abf77..b4b1479e2ceba4 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -85,11 +85,11 @@ next line: ``Ordered by: standard name``, indicates that the text string in the far right column was used to sort the output. The column headings include: ncalls - for the number of calls, + for the number of calls. tottime - for the total time spent in the given function (and excluding time made in - calls to sub-functions) + for the total time spent in the given function (and excluding time made in + calls to sub-functions) percall is the quotient of ``tottime`` divided by ``ncalls`` From a6a856f4d85d6dab5ea924546777292988cbc706 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 22 Mar 2017 18:55:33 -0700 Subject: [PATCH 099/340] Remove an outdated statement in execution model docs (GH-754) (GH-774) (cherry picked from commit fad7f1560669af1766c583c7ef242c55d8c8de41) --- Doc/reference/executionmodel.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst index 5f1ea92ed460f3..f0dbbd1edf6321 100644 --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -194,12 +194,6 @@ This means that the following code will print 42:: i = 42 f() -There are several cases where Python statements are illegal when used in -conjunction with nested scopes that contain free variables. - -If a variable is referenced in an enclosing scope, it is illegal to delete the -name. An error will be reported at compile time. - .. XXX from * also invalid with relative imports (at least currently) The :func:`eval` and :func:`exec` functions do not have access to the full From 6a45811d06e25447c83f78d67fd78298f83868ee Mon Sep 17 00:00:00 2001 From: Christophe Zeitouny Date: Fri, 24 Mar 2017 04:21:37 -0700 Subject: [PATCH 100/340] faulthandler: Restore the old sigaltstack during teardown (GH-777) (GH-796) (cherry picked from commit 20fbf8accd494fd15b0fc4c84928178c71ead4d1) --- Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/faulthandler.c | 17 ++++++++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Misc/ACKS b/Misc/ACKS index 8a952a45f5dcd4..edfbb448bd9155 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1679,6 +1679,7 @@ Artur Zaprzala Mike Zarnstorff Yury V. Zaytsev Siebren van der Zee +Christophe Zeitouny Nickolai Zeldovich Yuxiao Zeng Uwe Zessin diff --git a/Misc/NEWS b/Misc/NEWS index e45cf3edfdaf8a..e063455b986413 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,9 @@ Extension Modules Library ------- +- bpo-29884: faulthandler: Restore the old sigaltstack during teardown. + Patch by Christophe Zeitouny. + - bpo-25455: Fixed crashes in repr of recursive buffered file-like objects. - bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c index f1fda481fc61bf..56285b6358e056 100644 --- a/Modules/faulthandler.c +++ b/Modules/faulthandler.c @@ -124,6 +124,7 @@ static const unsigned char faulthandler_nsignals = \ #ifdef HAVE_SIGALTSTACK static stack_t stack; +static stack_t old_stack; #endif @@ -1148,7 +1149,7 @@ int _PyFaulthandler_Init(void) stack.ss_size = SIGSTKSZ; stack.ss_sp = PyMem_Malloc(stack.ss_size); if (stack.ss_sp != NULL) { - err = sigaltstack(&stack, NULL); + err = sigaltstack(&stack, &old_stack); if (err) { PyMem_Free(stack.ss_sp); stack.ss_sp = NULL; @@ -1204,6 +1205,20 @@ void _PyFaulthandler_Fini(void) faulthandler_disable(); #ifdef HAVE_SIGALTSTACK if (stack.ss_sp != NULL) { + /* Fetch the current alt stack */ + stack_t current_stack; + if (sigaltstack(NULL, ¤t_stack) == 0) { + if (current_stack.ss_sp == stack.ss_sp) { + /* The current alt stack is the one that we installed. + It is safe to restore the old stack that we found when + we installed ours */ + sigaltstack(&old_stack, NULL); + } else { + /* Someone switched to a different alt stack and didn't + restore ours when they were done (if they're done). + There's not much we can do in this unlikely case */ + } + } PyMem_Free(stack.ss_sp); stack.ss_sp = NULL; } From 80cb6ed4db9bae09de1e9ad6001d11cb45a4c1cc Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 24 Mar 2017 15:19:18 +0100 Subject: [PATCH 101/340] bpo-29861: release references to multiprocessing Pool tasks (#743) (#801) * bpo-29861: release references to multiprocessing Pool tasks (#743) * bpo-29861: release references to multiprocessing Pool tasks Release references to tasks, their arguments and their results as soon as they are finished, instead of keeping them alive until another task arrives. * Comments in test (cherry picked from commit 8988945cdc27ffa86ba8c624e095b51c459f5154) * Fix Misc/NEWS?? --- Lib/multiprocessing/pool.py | 7 ++++++- Lib/test/_test_multiprocessing.py | 28 ++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 6d25469e1620c0..7d5ab67b4704cd 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -128,6 +128,8 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, util.debug("Possible encoding error while sending result: %s" % ( wrapped)) put((job, i, (False, wrapped))) + + task = job = result = func = args = kwds = None completed += 1 util.debug('worker exiting after %d tasks' % completed) @@ -402,10 +404,11 @@ def _handle_tasks(taskqueue, put, outqueue, pool, cache): if set_length: util.debug('doing set_length()') set_length(i+1) + finally: + task = taskseq = job = None else: util.debug('task handler got sentinel') - try: # tell result handler to finish when cache is empty util.debug('task handler sending sentinel to result handler') @@ -445,6 +448,7 @@ def _handle_results(outqueue, get, cache): cache[job]._set(i, obj) except KeyError: pass + task = job = obj = None while cache and thread._state != TERMINATE: try: @@ -461,6 +465,7 @@ def _handle_results(outqueue, get, cache): cache[job]._set(i, obj) except KeyError: pass + task = job = obj = None if hasattr(outqueue, '_reader'): util.debug('ensuring that outqueue is not full') diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 9b789c2a3385b2..b053342f1c26c1 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -18,6 +18,7 @@ import logging import struct import operator +import weakref import test.support import test.support.script_helper @@ -1668,6 +1669,19 @@ def sqr(x, wait=0.0): def mul(x, y): return x*y +def identity(x): + return x + +class CountedObject(object): + n_instances = 0 + + def __new__(cls): + cls.n_instances += 1 + return object.__new__(cls) + + def __del__(self): + type(self).n_instances -= 1 + class SayWhenError(ValueError): pass def exception_throwing_generator(total, when): @@ -1676,6 +1690,7 @@ def exception_throwing_generator(total, when): raise SayWhenError("Somebody said when") yield i + class _TestPool(BaseTestCase): @classmethod @@ -1910,6 +1925,19 @@ def test_wrapped_exception(self): with self.assertRaises(RuntimeError): p.apply(self._test_wrapped_exception) + def test_release_task_refs(self): + # Issue #29861: task arguments and results should not be kept + # alive after we are done with them. + objs = [CountedObject() for i in range(10)] + refs = [weakref.ref(o) for o in objs] + self.pool.map(identity, objs) + + del objs + self.assertEqual(set(wr() for wr in refs), {None}) + # With a process pool, copies of the objects are returned, check + # they were released too. + self.assertEqual(CountedObject.n_instances, 0) + def raising(): raise KeyError("key") diff --git a/Misc/NEWS b/Misc/NEWS index e063455b986413..cc219d4bed0d49 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,9 @@ Extension Modules Library ------- +- bpo-29861: Release references to tasks, their arguments and their results + as soon as they are finished in multiprocessing.Pool. + - bpo-29884: faulthandler: Restore the old sigaltstack during teardown. Patch by Christophe Zeitouny. From 1fc1f8d7f737f80a1ee5ea37b9781c0a790102b2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 24 Mar 2017 21:46:46 +0200 Subject: [PATCH 102/340] bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) (#805) (#807) when the OS gives priority to errors such as EACCES over EEXIST. (cherry picked from commit af7b9ec5c855366feef4c67dc492d64b3baf84ca) --- Lib/pathlib.py | 32 +++++++++++++++----------------- Lib/test/test_pathlib.py | 5 +++++ Misc/NEWS | 3 +++ 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index c0d858ef56120a..16b99cddbc7183 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1207,25 +1207,23 @@ def touch(self, mode=0o666, exist_ok=True): os.close(fd) def mkdir(self, mode=0o777, parents=False, exist_ok=False): + """ + Create a new directory at this given path. + """ if self._closed: self._raise_closed() - if not parents: - try: - self._accessor.mkdir(self, mode) - except FileExistsError: - if not exist_ok or not self.is_dir(): - raise - else: - try: - self._accessor.mkdir(self, mode) - except FileExistsError: - if not exist_ok or not self.is_dir(): - raise - except OSError as e: - if e.errno != ENOENT or self.parent == self: - raise - self.parent.mkdir(parents=True) - self._accessor.mkdir(self, mode) + try: + self._accessor.mkdir(self, mode) + except FileNotFoundError: + if not parents or self.parent == self: + raise + self.parent.mkdir(parents=True) + self._accessor.mkdir(self, mode) + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not self.is_dir(): + raise def chmod(self, mode): """ diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 28e3ea4da6e28c..86d3077d5c4458 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -1727,6 +1727,11 @@ def test_mkdir_exist_ok_with_parent(self): self.assertTrue(p.exists()) self.assertEqual(p.stat().st_ctime, st_ctime_first) + def test_mkdir_exist_ok_root(self): + # Issue #25803: A drive root could raise PermissionError on Windows + self.cls('/').resolve().mkdir(exist_ok=True) + self.cls('/').resolve().mkdir(parents=True, exist_ok=True) + @only_nt # XXX: not sure how to test this on POSIX def test_mkdir_with_unknown_drive(self): for d in 'ZYXWVUTSRQPONMLKJIHGFEDCBA': diff --git a/Misc/NEWS b/Misc/NEWS index cc219d4bed0d49..f541504e0cdc5f 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,9 @@ Extension Modules Library ------- +- bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + - bpo-29861: Release references to tasks, their arguments and their results as soon as they are finished in multiprocessing.Pool. From 55717b4b487a9ccc119ca501fad71937fa01d1f6 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 25 Mar 2017 03:42:38 -0700 Subject: [PATCH 103/340] bpo-29862: Fix grammar in importlib.reload() exception (GH-809) (GH-812) (cherry picked from commit 9f0aa4843f8c26937d5817f27cac4aae9c0a034f) --- Lib/importlib/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/importlib/__init__.py b/Lib/importlib/__init__.py index b6a9f82e05f268..8b11d22b024ffa 100644 --- a/Lib/importlib/__init__.py +++ b/Lib/importlib/__init__.py @@ -136,7 +136,7 @@ def reload(module): """ if not module or not isinstance(module, types.ModuleType): - raise TypeError("reload() argument must be module") + raise TypeError("reload() argument must be a module") try: name = module.__spec__.name except AttributeError: From 8ce3085bf167b702989a9db466078b5676e825e3 Mon Sep 17 00:00:00 2001 From: Ned Deily Date: Sun, 26 Mar 2017 13:59:01 -0400 Subject: [PATCH 104/340] bpo-29888: Fix the link referring to the "Python download page" (GH-824) (GH-827) (cherry picked from commit f8beb9831acd5cf80b9c56aea5864e16118c5400) --- Doc/tools/templates/download.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tools/templates/download.html b/Doc/tools/templates/download.html index de84ae3abc81c7..3a05cb697938fd 100644 --- a/Doc/tools/templates/download.html +++ b/Doc/tools/templates/download.html @@ -42,7 +42,7 @@

Download Python {{ release }} Documentation

These archives contain all the content in the documentation.

HTML Help (.chm) files are made available in the "Windows" section -on the Python +on the Python download page.

From c2492ddd7c9797f94c85988ce7a86320d4ebfb59 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 26 Mar 2017 22:54:45 -0500 Subject: [PATCH 105/340] Treat Sphinx warnings as errors (GH-832) (GH-835) (cherry picked from commit 334e9ec938ea9876baadef15edb135d6d2aff30c) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 66f03dc7161a7f..3496a1abba2c97 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,7 +39,7 @@ matrix: - cd Doc - make venv script: - - make check suspicious html PYTHON="./venv/bin/python" SPHINXBUILD="./venv/bin/python -m sphinx" SPHINXOPTS="-q" + - make check suspicious html PYTHON="./venv/bin/python" SPHINXBUILD="./venv/bin/python -m sphinx" SPHINXOPTS="-q -W" - os: linux language: c compiler: clang From ec3a32699e03cc12892a1b2fd37eed5a721ab5a0 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Mon, 27 Mar 2017 00:38:20 -0500 Subject: [PATCH 106/340] Minor test cleanup (GH-837) (GH-839) * Remove unused test file * Remove duplicated text in sndhdrdata README (cherry picked from commit b8a7daf077dab18e9e3701c5380b542ae0aa9a94) --- Lib/test/185test.db | Bin 16384 -> 0 bytes Lib/test/sndhdrdata/README | 7 ------- 2 files changed, 7 deletions(-) delete mode 100644 Lib/test/185test.db diff --git a/Lib/test/185test.db b/Lib/test/185test.db deleted file mode 100644 index 14cb5e258bc0961fa22527dcb5d947a6a0fd5480..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmeI!F$%&k6vpwdEl39?E*_+VxVZETo - -Sound file samples used by Lib/test/test_sndhdr.py and generated using the -following commands: - - dd if=/dev/zero of=sndhdr.raw bs=20 count=1 - sox -s -2 -c 2 -r 44100 sndhdr.raw sndhdr. - From cf57fe13b44e3994096ae79f32c11475f333a94f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 27 Mar 2017 16:11:34 +0200 Subject: [PATCH 107/340] bpo-27425: Add .gitattributes, fix Windows tests (#844) Mark binary files as binay in .gitattributes to not translate newline characters in Git repositories on Windows. --- .gitattributes | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000000..82694d81f276b2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,8 @@ +*.pck binary +Lib/test/cjkencodings/* binary +Lib/test/decimaltestdata/*.decTest binary +Lib/test/sndhdrdata/sndhdr.* binary +Lib/test/test_email/data/msg_26.txt binary +Lib/test/xmltestdata/* binary +Lib/venv/scripts/nt/* binary +Lib/test/coding20731.py binary From cb09f421c88ff4c0bb8282ef6ca49d5ce2ccfc2c Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Mon, 27 Mar 2017 16:46:46 -0700 Subject: [PATCH 108/340] Drop the standard gcc test build on Travis (GH-853) (GH-860) Instead have gcc be used for the coverage build so gcc is exercised in at least one place. (cherry picked from commit ad2f9e2c8a0b44b3e6aec9d28ba59e13239236f7) --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3496a1abba2c97..5fee6cd7673324 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,11 @@ os: - linux # macOS builds are disabled as the machines are under-provisioned on Travis, # adding up to an extra hour completing a full CI run. - #- osx compiler: - clang - - gcc + # gcc also works, but to keep the # of concurrent builds down, we use one C + # compiler here and the other to run the coverage build. env: - TESTING=cpython @@ -32,7 +32,7 @@ matrix: include: - os: linux language: python - python: 3.5 + python: 3.6 env: - TESTING=docs before_script: @@ -42,7 +42,7 @@ matrix: - make check suspicious html PYTHON="./venv/bin/python" SPHINXBUILD="./venv/bin/python -m sphinx" SPHINXOPTS="-q -W" - os: linux language: c - compiler: clang + compiler: gcc env: - TESTING=coverage before_script: From 8994f36287b068e8ea9a9230fc90eda72bf5fff0 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 27 Mar 2017 17:09:21 -0700 Subject: [PATCH 109/340] bpo-29677: DOC: clarify documentation for `round` (GH-357) (GH-863) (cherry picked from commit 6003db7db5fec545c01923c198a5fdfca5a91538) --- Doc/library/functions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 2f14949e1f646b..15413cba941932 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1241,7 +1241,8 @@ are always available. They are listed here in alphabetical order. closest multiple of 10 to the power minus *ndigits*; if two multiples are equally close, rounding is done toward the even choice (so, for example, both ``round(0.5)`` and ``round(-0.5)`` are ``0``, and ``round(1.5)`` is - ``2``). The return value is an integer if called with one argument, + ``2``). Any integer value is valid for *ndigits* (positive, zero, or + negative). The return value is an integer if called with one argument, otherwise of the same type as *number*. .. note:: From e6a49531568561fe5aaf662259ecb7b4bc2426be Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Wed, 29 Mar 2017 00:26:29 +0900 Subject: [PATCH 110/340] bpo-29643: Fix check for --enable-optimizations (GH-871) The presence of the ``--enable-optimizations`` flag is indicated by the value of ``$enableval``, but the configure script was checking ``$withval``, resulting in the ``--enable-optimizations`` flag being effectively ignored. (cherry picked from commit 8cea5929f52801b0ce5928b46ef836e99a24321a) --- Misc/NEWS | 5 +++++ configure | 2 +- configure.ac | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index f541504e0cdc5f..1b0c1c092c8dfa 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -157,6 +157,11 @@ Documentation - Issue #29349: Fix Python 2 syntax in code for building the documentation. +Build +----- + +- bpo-29643: Fix ``--enable-optimization`` didn't work. + Tests ----- diff --git a/configure b/configure index 0f7484231a38ce..c84a8ec9e04a1a 100755 --- a/configure +++ b/configure @@ -6548,7 +6548,7 @@ $as_echo_n "checking for --enable-optimizations... " >&6; } # Check whether --enable-optimizations was given. if test "${enable_optimizations+set}" = set; then : enableval=$enable_optimizations; -if test "$withval" != no +if test "$enableval" != no then Py_OPT='true' { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 diff --git a/configure.ac b/configure.ac index 0eca886aebdc69..779fe3764c7f5a 100644 --- a/configure.ac +++ b/configure.ac @@ -1237,7 +1237,7 @@ Py_OPT='false' AC_MSG_CHECKING(for --enable-optimizations) AC_ARG_ENABLE(optimizations, AS_HELP_STRING([--enable-optimizations], [Enable expensive optimizations (PGO, maybe LTO, etc). Disabled by default.]), [ -if test "$withval" != no +if test "$enableval" != no then Py_OPT='true' AC_MSG_RESULT(yes); From 0957f262c5e47167efd520624557aebdc61bfda8 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 28 Mar 2017 09:32:50 -0700 Subject: [PATCH 111/340] bpo-16011: clarify that 'in' always returns a boolean value (GH-152) (GH-875) (cherry picked from commit 0ae7c8bd614d3aa1fcaf2d71a10ff1148c80d9b5) --- Doc/reference/expressions.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index ea89486128c68f..7c1f2a6dc2d39c 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1271,28 +1271,29 @@ Membership test operations -------------------------- The operators :keyword:`in` and :keyword:`not in` test for membership. ``x in -s`` evaluates to true if *x* is a member of *s*, and false otherwise. ``x not -in s`` returns the negation of ``x in s``. All built-in sequences and set types -support this as well as dictionary, for which :keyword:`in` tests whether the -dictionary has a given key. For container types such as list, tuple, set, -frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent +s`` evaluates to ``True`` if *x* is a member of *s*, and ``False`` otherwise. +``x not in s`` returns the negation of ``x in s``. All built-in sequences and +set types support this as well as dictionary, for which :keyword:`in` tests +whether the dictionary has a given key. For container types such as list, tuple, +set, frozenset, dict, or collections.deque, the expression ``x in y`` is equivalent to ``any(x is e or x == e for e in y)``. -For the string and bytes types, ``x in y`` is true if and only if *x* is a +For the string and bytes types, ``x in y`` is ``True`` if and only if *x* is a substring of *y*. An equivalent test is ``y.find(x) != -1``. Empty strings are always considered to be a substring of any other string, so ``"" in "abc"`` will return ``True``. For user-defined classes which define the :meth:`__contains__` method, ``x in -y`` is true if and only if ``y.__contains__(x)`` is true. +y`` returns ``True`` if ``y.__contains__(x)`` returns a true value, and +``False`` otherwise. For user-defined classes which do not define :meth:`__contains__` but do define -:meth:`__iter__`, ``x in y`` is true if some value ``z`` with ``x == z`` is +:meth:`__iter__`, ``x in y`` is ``True`` if some value ``z`` with ``x == z`` is produced while iterating over ``y``. If an exception is raised during the iteration, it is as if :keyword:`in` raised that exception. Lastly, the old-style iteration protocol is tried: if a class defines -:meth:`__getitem__`, ``x in y`` is true if and only if there is a non-negative +:meth:`__getitem__`, ``x in y`` is ``True`` if and only if there is a non-negative integer index *i* such that ``x == y[i]``, and all lower integer indices do not raise :exc:`IndexError` exception. (If any other exception is raised, it is as if :keyword:`in` raised that exception). From 9f8e0904580cae3b99f8d343569b76e1be7e6092 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Wed, 29 Mar 2017 12:51:29 +0800 Subject: [PATCH 112/340] bpo-28699: fix abnormal behaviour of pools in multiprocessing.pool (GH-884) an exception raised at the very first of an iterable would cause pools behave abnormally (swallow the exception or hang) --- Lib/multiprocessing/pool.py | 79 +++++++++++++++++++++---------- Lib/test/_test_multiprocessing.py | 59 ++++++++++++++++++++++- Misc/NEWS | 4 ++ 3 files changed, 117 insertions(+), 25 deletions(-) diff --git a/Lib/multiprocessing/pool.py b/Lib/multiprocessing/pool.py index 7d5ab67b4704cd..789488f0493ce7 100644 --- a/Lib/multiprocessing/pool.py +++ b/Lib/multiprocessing/pool.py @@ -118,7 +118,7 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, try: result = (True, func(*args, **kwds)) except Exception as e: - if wrap_exception: + if wrap_exception and func is not _helper_reraises_exception: e = ExceptionWithTraceback(e, e.__traceback__) result = (False, e) try: @@ -133,6 +133,10 @@ def worker(inqueue, outqueue, initializer=None, initargs=(), maxtasks=None, completed += 1 util.debug('worker exiting after %d tasks' % completed) +def _helper_reraises_exception(ex): + 'Pickle-able helper function for use by _guarded_task_generation.' + raise ex + # # Class representing a process pool # @@ -277,6 +281,17 @@ def starmap_async(self, func, iterable, chunksize=None, callback=None, return self._map_async(func, iterable, starmapstar, chunksize, callback, error_callback) + def _guarded_task_generation(self, result_job, func, iterable): + '''Provides a generator of tasks for imap and imap_unordered with + appropriate handling for iterables which throw exceptions during + iteration.''' + try: + i = -1 + for i, x in enumerate(iterable): + yield (result_job, i, func, (x,), {}) + except Exception as e: + yield (result_job, i+1, _helper_reraises_exception, (e,), {}) + def imap(self, func, iterable, chunksize=1): ''' Equivalent of `map()` -- can be MUCH slower than `Pool.map()`. @@ -285,15 +300,23 @@ def imap(self, func, iterable, chunksize=1): raise ValueError("Pool not running") if chunksize == 1: result = IMapIterator(self._cache) - self._taskqueue.put((((result._job, i, func, (x,), {}) - for i, x in enumerate(iterable)), result._set_length)) + self._taskqueue.put( + ( + self._guarded_task_generation(result._job, func, iterable), + result._set_length + )) return result else: assert chunksize > 1 task_batches = Pool._get_tasks(func, iterable, chunksize) result = IMapIterator(self._cache) - self._taskqueue.put((((result._job, i, mapstar, (x,), {}) - for i, x in enumerate(task_batches)), result._set_length)) + self._taskqueue.put( + ( + self._guarded_task_generation(result._job, + mapstar, + task_batches), + result._set_length + )) return (item for chunk in result for item in chunk) def imap_unordered(self, func, iterable, chunksize=1): @@ -304,15 +327,23 @@ def imap_unordered(self, func, iterable, chunksize=1): raise ValueError("Pool not running") if chunksize == 1: result = IMapUnorderedIterator(self._cache) - self._taskqueue.put((((result._job, i, func, (x,), {}) - for i, x in enumerate(iterable)), result._set_length)) + self._taskqueue.put( + ( + self._guarded_task_generation(result._job, func, iterable), + result._set_length + )) return result else: assert chunksize > 1 task_batches = Pool._get_tasks(func, iterable, chunksize) result = IMapUnorderedIterator(self._cache) - self._taskqueue.put((((result._job, i, mapstar, (x,), {}) - for i, x in enumerate(task_batches)), result._set_length)) + self._taskqueue.put( + ( + self._guarded_task_generation(result._job, + mapstar, + task_batches), + result._set_length + )) return (item for chunk in result for item in chunk) def apply_async(self, func, args=(), kwds={}, callback=None, @@ -323,7 +354,7 @@ def apply_async(self, func, args=(), kwds={}, callback=None, if self._state != RUN: raise ValueError("Pool not running") result = ApplyResult(self._cache, callback, error_callback) - self._taskqueue.put(([(result._job, None, func, args, kwds)], None)) + self._taskqueue.put(([(result._job, 0, func, args, kwds)], None)) return result def map_async(self, func, iterable, chunksize=None, callback=None, @@ -354,8 +385,14 @@ def _map_async(self, func, iterable, mapper, chunksize=None, callback=None, task_batches = Pool._get_tasks(func, iterable, chunksize) result = MapResult(self._cache, chunksize, len(iterable), callback, error_callback=error_callback) - self._taskqueue.put((((result._job, i, mapper, (x,), {}) - for i, x in enumerate(task_batches)), None)) + self._taskqueue.put( + ( + self._guarded_task_generation(result._job, + mapper, + task_batches), + None + ) + ) return result @staticmethod @@ -377,33 +414,27 @@ def _handle_tasks(taskqueue, put, outqueue, pool, cache): for taskseq, set_length in iter(taskqueue.get, None): task = None - i = -1 try: - for i, task in enumerate(taskseq): + # iterating taskseq cannot fail + for task in taskseq: if thread._state: util.debug('task handler found thread._state != RUN') break try: put(task) except Exception as e: - job, ind = task[:2] + job, idx = task[:2] try: - cache[job]._set(ind, (False, e)) + cache[job]._set(idx, (False, e)) except KeyError: pass else: if set_length: util.debug('doing set_length()') - set_length(i+1) + idx = task[1] if task else -1 + set_length(idx + 1) continue break - except Exception as ex: - job, ind = task[:2] if task else (0, 0) - if job in cache: - cache[job]._set(ind + 1, (False, ex)) - if set_length: - util.debug('doing set_length()') - set_length(i+1) finally: task = taskseq = job = None else: diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b053342f1c26c1..d1ef98dab47332 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1685,6 +1685,8 @@ def __del__(self): class SayWhenError(ValueError): pass def exception_throwing_generator(total, when): + if when == -1: + raise SayWhenError("Somebody said when") for i in range(total): if i == when: raise SayWhenError("Somebody said when") @@ -1763,6 +1765,32 @@ def test_map_chunksize(self): except multiprocessing.TimeoutError: self.fail("pool.map_async with chunksize stalled on null list") + def test_map_handle_iterable_exception(self): + if self.TYPE == 'manager': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + # SayWhenError seen at the very first of the iterable + with self.assertRaises(SayWhenError): + self.pool.map(sqr, exception_throwing_generator(1, -1), 1) + # again, make sure it's reentrant + with self.assertRaises(SayWhenError): + self.pool.map(sqr, exception_throwing_generator(1, -1), 1) + + with self.assertRaises(SayWhenError): + self.pool.map(sqr, exception_throwing_generator(10, 3), 1) + + class SpecialIterable: + def __iter__(self): + return self + def __next__(self): + raise SayWhenError + def __len__(self): + return 1 + with self.assertRaises(SayWhenError): + self.pool.map(sqr, SpecialIterable(), 1) + with self.assertRaises(SayWhenError): + self.pool.map(sqr, SpecialIterable(), 1) + def test_async(self): res = self.pool.apply_async(sqr, (7, TIMEOUT1,)) get = TimingWrapper(res.get) @@ -1793,6 +1821,13 @@ def test_imap_handle_iterable_exception(self): if self.TYPE == 'manager': self.skipTest('test not appropriate for {}'.format(self.TYPE)) + # SayWhenError seen at the very first of the iterable + it = self.pool.imap(sqr, exception_throwing_generator(1, -1), 1) + self.assertRaises(SayWhenError, it.__next__) + # again, make sure it's reentrant + it = self.pool.imap(sqr, exception_throwing_generator(1, -1), 1) + self.assertRaises(SayWhenError, it.__next__) + it = self.pool.imap(sqr, exception_throwing_generator(10, 3), 1) for i in range(3): self.assertEqual(next(it), i*i) @@ -1819,6 +1854,17 @@ def test_imap_unordered_handle_iterable_exception(self): if self.TYPE == 'manager': self.skipTest('test not appropriate for {}'.format(self.TYPE)) + # SayWhenError seen at the very first of the iterable + it = self.pool.imap_unordered(sqr, + exception_throwing_generator(1, -1), + 1) + self.assertRaises(SayWhenError, it.__next__) + # again, make sure it's reentrant + it = self.pool.imap_unordered(sqr, + exception_throwing_generator(1, -1), + 1) + self.assertRaises(SayWhenError, it.__next__) + it = self.pool.imap_unordered(sqr, exception_throwing_generator(10, 3), 1) @@ -1900,7 +1946,7 @@ def test_traceback(self): except Exception as e: exc = e else: - raise AssertionError('expected RuntimeError') + self.fail('expected RuntimeError') self.assertIs(type(exc), RuntimeError) self.assertEqual(exc.args, (123,)) cause = exc.__cause__ @@ -1914,6 +1960,17 @@ def test_traceback(self): sys.excepthook(*sys.exc_info()) self.assertIn('raise RuntimeError(123) # some comment', f1.getvalue()) + # _helper_reraises_exception should not make the error + # a remote exception + with self.Pool(1) as p: + try: + p.map(sqr, exception_throwing_generator(1, -1), 1) + except Exception as e: + exc = e + else: + self.fail('expected SayWhenError') + self.assertIs(type(exc), SayWhenError) + self.assertIs(exc.__cause__, None) @classmethod def _test_wrapped_exception(cls): diff --git a/Misc/NEWS b/Misc/NEWS index 1b0c1c092c8dfa..9a22010218f38b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,10 @@ Extension Modules Library ------- +- bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an + exception at the very first of an iterable may swallow the exception or + make the program hang. Patch by Davin Potts and Xiang Zhang. + - bpo-25803: Avoid incorrect errors raised by Path.mkdir(exist_ok=True) when the OS gives priority to errors such as EACCES over EEXIST. From eef6e11f9883f54de491121b8c49fdadd3e3506d Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 29 Mar 2017 19:10:22 -0700 Subject: [PATCH 113/340] bpo-29677: DOC: clarify documentation for `round` (GH-877) (GH-893) (cherry picked from commit 85deefcf61d3cc192846f41a4ccc6df17da60c98) --- Doc/library/functions.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 15413cba941932..ff8c7b83bbddc8 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1233,9 +1233,9 @@ are always available. They are listed here in alphabetical order. .. function:: round(number[, ndigits]) - Return the floating point value *number* rounded to *ndigits* digits after - the decimal point. If *ndigits* is omitted or is ``None``, it returns the - nearest integer to its input. Delegates to ``number.__round__(ndigits)``. + Return *number* rounded to *ndigits* precision after the decimal + point. If *ndigits* is omitted or is ``None``, it returns the + nearest integer to its input. For the built-in types supporting :func:`round`, values are rounded to the closest multiple of 10 to the power minus *ndigits*; if two multiples are @@ -1245,6 +1245,9 @@ are always available. They are listed here in alphabetical order. negative). The return value is an integer if called with one argument, otherwise of the same type as *number*. + For a general Python object ``number``, ``round(number, ndigits)`` delegates to + ``number.__round__(ndigits)``. + .. note:: The behavior of :func:`round` for floats can be surprising: for example, From d1dbbaab01354f01faa696aff1280db3b349e354 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Wed, 29 Mar 2017 22:29:06 -0700 Subject: [PATCH 114/340] bpo-29917: DOC: Remove link from PyMethodDef (#890) (#895) (cherry picked from commit c3c7ef088583cc12bd218138036d1edb6de9c63f) --- Doc/c-api/structures.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/c-api/structures.rst b/Doc/c-api/structures.rst index f48119391f2bbd..c080f317bee9d9 100644 --- a/Doc/c-api/structures.rst +++ b/Doc/c-api/structures.rst @@ -241,7 +241,7 @@ definition with the same method name. +==================+=============+===============================+ | :attr:`name` | char \* | name of the member | +------------------+-------------+-------------------------------+ - | :attr:`type` | int | the type of the member in the | + | :attr:`!type` | int | the type of the member in the | | | | C struct | +------------------+-------------+-------------------------------+ | :attr:`offset` | Py_ssize_t | the offset in bytes that the | @@ -256,7 +256,7 @@ definition with the same method name. | | | docstring | +------------------+-------------+-------------------------------+ - :attr:`type` can be one of many ``T_`` macros corresponding to various C + :attr:`!type` can be one of many ``T_`` macros corresponding to various C types. When the member is accessed in Python, it will be converted to the equivalent Python type. From 0fadf25e69f3de36b5deddecd9557addc8142fdf Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Wed, 29 Mar 2017 23:56:57 -0700 Subject: [PATCH 115/340] Remove an unrequired TODO in test_urllib2. (#897) (#901) (cherry picked from commit e6911a44f69c0d302db60f49952a9cf69da69a2b) --- Lib/test/test_urllib2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index eda7cccc6035a6..8c11b40daa099a 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -1341,7 +1341,6 @@ def test_proxy_https_proxy_authorization(self): self.assertEqual(req.host, "proxy.example.com:3128") self.assertEqual(req.get_header("Proxy-authorization"), "FooBar") - # TODO: This should be only for OSX @unittest.skipUnless(sys.platform == 'darwin', "only relevant for OSX") def test_osx_proxy_bypass(self): bypass = { From c90ff1b78cb79bc3762184e03fa81f11984aaa45 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 30 Mar 2017 10:32:19 +0300 Subject: [PATCH 116/340] bpo-27863: Fixed multiple crashes in ElementTree. (#765) (#904) (cherry picked from commit 576def096ec7b64814e038f03290031f172886c3) --- Lib/test/test_xml_etree.py | 112 +++++++++++++++++++++++++++++++++++++ Misc/NEWS | 3 + Modules/_elementtree.c | 100 +++++++++++++++++---------------- 3 files changed, 167 insertions(+), 48 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py index 6c7616beae3ff9..5d0166a6a74af0 100644 --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -1875,6 +1875,118 @@ def test_recursive_repr(self): with self.assertRaises(RuntimeError): repr(e) # Should not crash + def test_element_get_text(self): + # Issue #27863 + class X(str): + def __del__(self): + try: + elem.text + except NameError: + pass + + b = ET.TreeBuilder() + b.start('tag', {}) + b.data('ABCD') + b.data(X('EFGH')) + b.data('IJKL') + b.end('tag') + + elem = b.close() + self.assertEqual(elem.text, 'ABCDEFGHIJKL') + + def test_element_get_tail(self): + # Issue #27863 + class X(str): + def __del__(self): + try: + elem[0].tail + except NameError: + pass + + b = ET.TreeBuilder() + b.start('root', {}) + b.start('tag', {}) + b.end('tag') + b.data('ABCD') + b.data(X('EFGH')) + b.data('IJKL') + b.end('root') + + elem = b.close() + self.assertEqual(elem[0].tail, 'ABCDEFGHIJKL') + + def test_element_iter(self): + # Issue #27863 + state = { + 'tag': 'tag', + '_children': [None], # non-Element + 'attrib': 'attr', + 'tail': 'tail', + 'text': 'text', + } + + e = ET.Element('tag') + try: + e.__setstate__(state) + except AttributeError: + e.__dict__ = state + + it = e.iter() + self.assertIs(next(it), e) + self.assertRaises(AttributeError, next, it) + + def test_subscr(self): + # Issue #27863 + class X: + def __index__(self): + del e[:] + return 1 + + e = ET.Element('elem') + e.append(ET.Element('child')) + e[:X()] # shouldn't crash + + e.append(ET.Element('child')) + e[0:10:X()] # shouldn't crash + + def test_ass_subscr(self): + # Issue #27863 + class X: + def __index__(self): + e[:] = [] + return 1 + + e = ET.Element('elem') + for _ in range(10): + e.insert(0, ET.Element('child')) + + e[0:10:X()] = [] # shouldn't crash + + def test_treebuilder_start(self): + # Issue #27863 + def element_factory(x, y): + return [] + b = ET.TreeBuilder(element_factory=element_factory) + + b.start('tag', {}) + b.data('ABCD') + self.assertRaises(AttributeError, b.start, 'tag2', {}) + del b + gc_collect() + + def test_treebuilder_end(self): + # Issue #27863 + def element_factory(x, y): + return [] + b = ET.TreeBuilder(element_factory=element_factory) + + b.start('tag', {}) + b.data('ABCD') + self.assertRaises(AttributeError, b.end, 'tag') + del b + gc_collect() + + class MutatingElementPath(str): def __new__(cls, elem, *args): self = str.__new__(cls, *args) diff --git a/Misc/NEWS b/Misc/NEWS index 9a22010218f38b..749f3e34997a2c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,9 @@ Extension Modules Library ------- +- bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions + and wrong types. + - bpo-28699: Fixed a bug in pools in multiprocessing.pool that raising an exception at the very first of an iterable may swallow the exception or make the program hang. Patch by Davin Potts and Xiang Zhang. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 7d50dd07a961f2..c800f92f70d766 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -155,7 +155,7 @@ deepcopy(PyObject* object, PyObject* memo) LOCAL(PyObject*) list_join(PyObject* list) { - /* join list elements (destroying the list in the process) */ + /* join list elements */ PyObject* joiner; PyObject* result; @@ -164,8 +164,6 @@ list_join(PyObject* list) return NULL; result = PyUnicode_Join(joiner, list); Py_DECREF(joiner); - if (result) - Py_DECREF(list); return result; } @@ -534,15 +532,17 @@ element_get_text(ElementObject* self) { /* return borrowed reference to text attribute */ - PyObject* res = self->text; + PyObject *res = self->text; if (JOIN_GET(res)) { res = JOIN_OBJ(res); if (PyList_CheckExact(res)) { - res = list_join(res); - if (!res) + PyObject *tmp = list_join(res); + if (!tmp) return NULL; - self->text = res; + self->text = tmp; + Py_DECREF(res); + res = tmp; } } @@ -554,15 +554,17 @@ element_get_tail(ElementObject* self) { /* return borrowed reference to text attribute */ - PyObject* res = self->tail; + PyObject *res = self->tail; if (JOIN_GET(res)) { res = JOIN_OBJ(res); if (PyList_CheckExact(res)) { - res = list_join(res); - if (!res) + PyObject *tmp = list_join(res); + if (!tmp) return NULL; - self->tail = res; + self->tail = tmp; + Py_DECREF(res); + res = tmp; } } @@ -2147,6 +2149,12 @@ elementiter_next(ElementIterObject *it) cur_parent = it->parent_stack->parent; child_index = it->parent_stack->child_index; if (cur_parent->extra && child_index < cur_parent->extra->length) { + if (!PyObject_TypeCheck(cur_parent->extra->children[child_index], &Element_Type)) { + PyErr_Format(PyExc_AttributeError, + "'%.100s' object has no attribute 'iter'", + Py_TYPE(cur_parent->extra->children[child_index])->tp_name); + return NULL; + } elem = (ElementObject *)cur_parent->extra->children[child_index]; it->parent_stack->child_index++; it->parent_stack = parent_stack_push_new(it->parent_stack, @@ -2435,40 +2443,51 @@ treebuilder_dealloc(TreeBuilderObject *self) /* helpers for handling of arbitrary element-like objects */ static int -treebuilder_set_element_text_or_tail(PyObject *element, PyObject *data, +treebuilder_set_element_text_or_tail(PyObject *element, PyObject **data, PyObject **dest, _Py_Identifier *name) { if (Element_CheckExact(element)) { - Py_DECREF(JOIN_OBJ(*dest)); - *dest = JOIN_SET(data, PyList_CheckExact(data)); + PyObject *tmp = JOIN_OBJ(*dest); + *dest = JOIN_SET(*data, PyList_CheckExact(*data)); + *data = NULL; + Py_DECREF(tmp); return 0; } else { - PyObject *joined = list_join(data); + PyObject *joined = list_join(*data); int r; if (joined == NULL) return -1; r = _PyObject_SetAttrId(element, name, joined); Py_DECREF(joined); - return r; + if (r < 0) + return -1; + Py_CLEAR(*data); + return 0; } } -/* These two functions steal a reference to data */ -static int -treebuilder_set_element_text(PyObject *element, PyObject *data) +LOCAL(int) +treebuilder_flush_data(TreeBuilderObject* self) { - _Py_IDENTIFIER(text); - return treebuilder_set_element_text_or_tail( - element, data, &((ElementObject *) element)->text, &PyId_text); -} + PyObject *element = self->last; -static int -treebuilder_set_element_tail(PyObject *element, PyObject *data) -{ - _Py_IDENTIFIER(tail); - return treebuilder_set_element_text_or_tail( - element, data, &((ElementObject *) element)->tail, &PyId_tail); + if (!self->data) { + return 0; + } + + if (self->this == element) { + _Py_IDENTIFIER(text); + return treebuilder_set_element_text_or_tail( + element, &self->data, + &((ElementObject *) element)->text, &PyId_text); + } + else { + _Py_IDENTIFIER(tail); + return treebuilder_set_element_text_or_tail( + element, &self->data, + &((ElementObject *) element)->tail, &PyId_tail); + } } static int @@ -2517,16 +2536,8 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag, PyObject* this; elementtreestate *st = ET_STATE_GLOBAL; - if (self->data) { - if (self->this == self->last) { - if (treebuilder_set_element_text(self->last, self->data)) - return NULL; - } - else { - if (treebuilder_set_element_tail(self->last, self->data)) - return NULL; - } - self->data = NULL; + if (treebuilder_flush_data(self) < 0) { + return NULL; } if (self->element_factory && self->element_factory != Py_None) { @@ -2622,15 +2633,8 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag) { PyObject* item; - if (self->data) { - if (self->this == self->last) { - if (treebuilder_set_element_text(self->last, self->data)) - return NULL; - } else { - if (treebuilder_set_element_tail(self->last, self->data)) - return NULL; - } - self->data = NULL; + if (treebuilder_flush_data(self) < 0) { + return NULL; } if (self->index == 0) { From 8b8bde44f3912d8b2df5591ffc31d2d8c6dcca6c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 30 Mar 2017 20:31:46 +0300 Subject: [PATCH 117/340] bpo-29935: Fixed error messages in the index() method of tuple, list and deque (#887) (#907) (#909) when pass indices of wrong type. (cherry picked from commit d4edfc9abffca965e76ebc5957a92031a4d6c4d4) (cherry picked from commit bf4bb2e43030661e568d5d4b046e8b9351cc164c) --- Include/ceval.h | 1 + Misc/NEWS | 3 +++ Modules/_collectionsmodule.c | 4 ++-- Objects/listobject.c | 4 ++-- Objects/tupleobject.c | 4 ++-- Python/ceval.c | 26 +++++++++++++++++++++----- 6 files changed, 31 insertions(+), 11 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h index b5373a9cc474f8..3f84b0658159ad 100644 --- a/Include/ceval.h +++ b/Include/ceval.h @@ -203,6 +203,7 @@ PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); #ifndef Py_LIMITED_API PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); +PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *); PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); #endif diff --git a/Misc/NEWS b/Misc/NEWS index 749f3e34997a2c..e640622f0d86a1 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-29935: Fixed error messages in the index() method of tuple, list and deque + when pass indices of wrong type. + - bpo-28876: ``bool(range)`` works even if ``len(range)`` raises :exc:`OverflowError`. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c index ac81680e1bd710..08fcecad9adc00 100644 --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -913,8 +913,8 @@ deque_index(dequeobject *deque, PyObject *args) size_t start_state = deque->state; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) + _PyEval_SliceIndexNotNone, &start, + _PyEval_SliceIndexNotNone, &stop)) return NULL; if (start < 0) { start += Py_SIZE(deque); diff --git a/Objects/listobject.c b/Objects/listobject.c index 815a1b9ea2d80b..e1e3cf018aaa7b 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2154,8 +2154,8 @@ listindex(PyListObject *self, PyObject *args) PyObject *v; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) + _PyEval_SliceIndexNotNone, &start, + _PyEval_SliceIndexNotNone, &stop)) return NULL; if (start < 0) { start += Py_SIZE(self); diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 7920fec2bd86e8..48719454fe6537 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -515,8 +515,8 @@ tupleindex(PyTupleObject *self, PyObject *args) PyObject *v; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, - _PyEval_SliceIndex, &start, - _PyEval_SliceIndex, &stop)) + _PyEval_SliceIndexNotNone, &start, + _PyEval_SliceIndexNotNone, &stop)) return NULL; if (start < 0) { start += Py_SIZE(self); diff --git a/Python/ceval.c b/Python/ceval.c index 9ae8653f7e4e84..3070a90b43dbfb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5098,14 +5098,10 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. Return 0 on error, 1 on success. */ -/* Note: If v is NULL, return success without storing into *pi. This - is because_PyEval_SliceIndex() is called by apply_slice(), which can be - called by the SLICE opcode with v and/or w equal to NULL. -*/ int _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) { - if (v != NULL) { + if (v != Py_None) { Py_ssize_t x; if (PyIndex_Check(v)) { x = PyNumber_AsSsize_t(v, NULL); @@ -5123,6 +5119,26 @@ _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi) return 1; } +int +_PyEval_SliceIndexNotNone(PyObject *v, Py_ssize_t *pi) +{ + Py_ssize_t x; + if (PyIndex_Check(v)) { + x = PyNumber_AsSsize_t(v, NULL); + if (x == -1 && PyErr_Occurred()) + return 0; + } + else { + PyErr_SetString(PyExc_TypeError, + "slice indices must be integers or " + "have an __index__ method"); + return 0; + } + *pi = x; + return 1; +} + + #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\ "BaseException is not allowed" From 9273dfe1800fc7241d69f4d523d748ebd35b3801 Mon Sep 17 00:00:00 2001 From: "T. Wouters" Date: Thu, 30 Mar 2017 12:48:55 -0700 Subject: [PATCH 118/340] bpo-29942: Fix the use of recursion in itertools.chain.from_iterable. (#912) Fix the use of recursion in itertools.chain.from_iterable. Using recursion is unnecessary, and can easily cause stack overflows, especially when building in low optimization modes or with Py_DEBUG enabled. (cherry picked from commit 5466d4af5fe76ec0a5fbc8a05675287d9e8e9d14) --- Lib/test/test_itertools.py | 8 ++++++ Misc/NEWS | 3 +++ Modules/itertoolsmodule.c | 52 ++++++++++++++++++++------------------ 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py index e054303dedbe38..b8399fc1220cb6 100644 --- a/Lib/test/test_itertools.py +++ b/Lib/test/test_itertools.py @@ -1943,6 +1943,14 @@ def gen2(x): self.assertRaises(AssertionError, list, cycle(gen1())) self.assertEqual(hist, [0,1]) + def test_long_chain_of_empty_iterables(self): + # Make sure itertools.chain doesn't run into recursion limits when + # dealing with long chains of empty iterables. Even with a high + # number this would probably only fail in Py_DEBUG mode. + it = chain.from_iterable(() for unused in range(10000000)) + with self.assertRaises(StopIteration): + next(it) + class SubclassWithKwargsTest(unittest.TestCase): def test_keywords_in_subclass(self): # count is not subclassable... diff --git a/Misc/NEWS b/Misc/NEWS index e640622f0d86a1..0aefc7583bcb22 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Extension Modules Library ------- +- bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering + long runs of empty iterables. + - bpo-27863: Fixed multiple crashes in ElementTree caused by race conditions and wrong types. diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index be0f4982526f62..584dc6e7924341 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1854,33 +1854,37 @@ chain_next(chainobject *lz) { PyObject *item; - if (lz->source == NULL) - return NULL; /* already stopped */ - - if (lz->active == NULL) { - PyObject *iterable = PyIter_Next(lz->source); - if (iterable == NULL) { - Py_CLEAR(lz->source); - return NULL; /* no more input sources */ - } - lz->active = PyObject_GetIter(iterable); - Py_DECREF(iterable); + /* lz->source is the iterator of iterables. If it's NULL, we've already + * consumed them all. lz->active is the current iterator. If it's NULL, + * we should grab a new one from lz->source. */ + while (lz->source != NULL) { if (lz->active == NULL) { - Py_CLEAR(lz->source); - return NULL; /* input not iterable */ + PyObject *iterable = PyIter_Next(lz->source); + if (iterable == NULL) { + Py_CLEAR(lz->source); + return NULL; /* no more input sources */ + } + lz->active = PyObject_GetIter(iterable); + Py_DECREF(iterable); + if (lz->active == NULL) { + Py_CLEAR(lz->source); + return NULL; /* input not iterable */ + } } + item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active); + if (item != NULL) + return item; + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_StopIteration)) + PyErr_Clear(); + else + return NULL; /* input raised an exception */ + } + /* lz->active is consumed, try with the next iterable. */ + Py_CLEAR(lz->active); } - item = PyIter_Next(lz->active); - if (item != NULL) - return item; - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_StopIteration)) - PyErr_Clear(); - else - return NULL; /* input raised an exception */ - } - Py_CLEAR(lz->active); - return chain_next(lz); /* recurse and use next active */ + /* Everything had been consumed already. */ + return NULL; } static PyObject * From 6356a3b7109c5c546c1e7be098170be194142f39 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Thu, 30 Mar 2017 23:15:56 -0700 Subject: [PATCH 119/340] Remove catching OSError in ftphandler test. Only URLError is raised in urllib.request module. (#918) (#921) (cherry picked from commit ed3dd1c02af6872bd0748f7b9a5dadb89f7b830f) --- Lib/test/test_urllib2.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 8c11b40daa099a..49e6c82d4339a8 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -826,7 +826,6 @@ def test_file(self): for url, ftp in [ ("file://ftp.example.com//foo.txt", False), ("file://ftp.example.com///foo.txt", False), -# XXXX bug: fails with OSError, should be URLError ("file://ftp.example.com/foo.txt", False), ("file://somehost//foo/something.txt", False), ("file://localhost//foo/something.txt", False), @@ -835,7 +834,7 @@ def test_file(self): try: h.file_open(req) # XXXX remove OSError when bug fixed - except (urllib.error.URLError, OSError): + except urllib.error.URLError: self.assertFalse(ftp) else: self.assertIs(o.req, req) @@ -1616,7 +1615,6 @@ def test_invalid_closed(self): self.assertTrue(conn.fakesock.closed, "Connection not closed") - class MiscTests(unittest.TestCase): def opener_has_handler(self, opener, handler_class): From f3158121132a1519439bf4c7dba3333b07802d6d Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Fri, 31 Mar 2017 15:43:35 +0900 Subject: [PATCH 120/340] bpo-29952: Use usual terminology of dict (GH-923) s/keys and elements/keys and values/ (cherry picked from commit cdcac039fb447f2ab04efcacbe663751bb2cb4ec) --- Doc/reference/expressions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index 7c1f2a6dc2d39c..d4d007330c7972 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -1195,7 +1195,7 @@ built-in types. true). * Mappings (instances of :class:`dict`) compare equal if and only if they have - equal `(key, value)` pairs. Equality comparison of the keys and elements + equal `(key, value)` pairs. Equality comparison of the keys and values enforces reflexivity. Order comparisons (``<``, ``>``, ``<=``, and ``>=``) raise :exc:`TypeError`. From 51fc7e3d6a29de7b3142e51f8caf4d31f7ac72a0 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sat, 1 Apr 2017 20:00:41 -0700 Subject: [PATCH 121/340] bpo-26947: DOC: clarify wording on hashable in glossary (#948) (#958) (cherry picked from commit 64c887ab3a400cf91bde4f0c5ef69eacc88bc5e1) --- Doc/glossary.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/glossary.rst b/Doc/glossary.rst index 07b26a64b89c13..f474a6d8a71e95 100644 --- a/Doc/glossary.rst +++ b/Doc/glossary.rst @@ -434,9 +434,9 @@ Glossary Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally. - All of Python's immutable built-in objects are hashable, while no mutable - containers (such as lists or dictionaries) are. Objects which are - instances of user-defined classes are hashable by default; they all + All of Python's immutable built-in objects are hashable; mutable + containers (such as lists or dictionaries) are not. Objects which are + instances of user-defined classes are hashable by default. They all compare unequal (except with themselves), and their hash value is derived from their :func:`id`. From 553275d125478a6563dde7523f4f28c92f1861b4 Mon Sep 17 00:00:00 2001 From: "T. Wouters" Date: Sat, 1 Apr 2017 20:20:24 -0700 Subject: [PATCH 122/340] bpo-29941: Assert fixes (#886) (#956) Make a non-Py_DEBUG, asserts-enabled build of CPython possible. This means making sure helper functions are defined when NDEBUG is not defined, not just when Py_DEBUG is defined. Also fix a division-by-zero in obmalloc.c that went unnoticed because in Py_DEBUG mode, elsize is never zero. (cherry picked from commit a00c3fd12d421e41b769debd7df717d17b0deed5 and 06bb4873d6a9ac303701d08a851d6cd9a51e02a3) --- Include/unicodeobject.h | 4 ++++ Objects/obmalloc.c | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 0accc1d5c2ddad..59dcf736b1b2b3 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -2263,6 +2263,10 @@ PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy( PyAPI_FUNC(int) _PyUnicode_CheckConsistency( PyObject *op, int check_content); +#elif !defined(NDEBUG) +/* For asserts that call _PyUnicode_CheckConsistency(), which would + * otherwise be a problem when building with asserts but without Py_DEBUG. */ +#define _PyUnicode_CheckConsistency(op, check_content) PyUnicode_Check(op) #endif /* Return an interned Unicode object for an Identifier; may fail if there is no memory.*/ diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 7cc889f817b628..9dd8421a339482 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -1176,7 +1176,7 @@ _PyObject_Alloc(int use_calloc, void *ctx, size_t nelem, size_t elsize) _Py_AllocatedBlocks++; - assert(nelem <= PY_SSIZE_T_MAX / elsize); + assert(elsize == 0 || nelem <= PY_SSIZE_T_MAX / elsize); nbytes = nelem * elsize; #ifdef WITH_VALGRIND @@ -2233,7 +2233,9 @@ _PyObject_DebugMallocStats(FILE *out) if (p->ref.count == 0) { /* currently unused */ +#ifdef Py_DEBUG assert(pool_is_in_list(p, arenas[i].freepools)); +#endif continue; } ++numpools[sz]; From 9881e02d690fd9638b7dff959640db51d297d151 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 2 Apr 2017 01:37:04 -0700 Subject: [PATCH 123/340] Minor spell fix and formatting fixes in urllib tests. (#959) (#960) (cherry picked from commit efbd4ea65dbb9f87b1afeec6a760802756badee5) --- Lib/test/test_urllib.py | 6 +++++- Lib/test/test_urllibnet.py | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py index 1772399803499a..1a28c9a21d14ab 100644 --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -206,6 +206,7 @@ def test_iter(self): def test_relativelocalfile(self): self.assertRaises(ValueError,urllib.request.urlopen,'./' + self.pathname) + class ProxyTests(unittest.TestCase): def setUp(self): @@ -259,6 +260,7 @@ def test_proxy_bypass_environment_host_match(self): self.assertFalse(bypass('newdomain.com')) # no port self.assertFalse(bypass('newdomain.com:1235')) # wrong port + class ProxyTests_withOrderedEnv(unittest.TestCase): def setUp(self): @@ -294,6 +296,7 @@ def test_getproxies_environment_prefer_lowercase(self): proxies = urllib.request.getproxies_environment() self.assertEqual('http://somewhere:3128', proxies['http']) + class urlopen_HttpTests(unittest.TestCase, FakeHTTPMixin, FakeFTPMixin): """Test urlopen() opening a fake http connection.""" @@ -432,7 +435,6 @@ def test_ftp_cache_pruning(self): finally: self.unfakeftp() - def test_userpass_inurl(self): self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!") try: @@ -475,6 +477,7 @@ def test_cafile_and_context(self): "https://localhost", cafile="/nonexistent/path", context=context ) + class urlopen_DataTests(unittest.TestCase): """Test urlopen() opening a data URL.""" @@ -548,6 +551,7 @@ def test_invalid_base64_data(self): # missing padding character self.assertRaises(ValueError,urllib.request.urlopen,'data:;base64,Cg=') + class urlretrieve_FileTests(unittest.TestCase): """Test urllib.urlretrieve() on local files""" diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index b811930bbc7554..8379f1a512e94f 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -30,7 +30,7 @@ def testURLread(self): class urlopenNetworkTests(unittest.TestCase): - """Tests urllib.reqest.urlopen using the network. + """Tests urllib.request.urlopen using the network. These tests are not exhaustive. Assuming that testing using files does a good job overall of some of the basic interface features. There are no From 0f9ceaf322cc9358373167115fd4c21ab2d9ad50 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 3 Apr 2017 22:28:23 -0700 Subject: [PATCH 124/340] bpo-29725: DOC: add text for arraysize in sqlite3.Cursor (#947) (#986) (cherry picked from commit 02e12138000da834f23719521a011fa93763384d) --- Doc/library/sqlite3.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst index 84a478352feb6d..1419ce0947ac29 100644 --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -633,6 +633,11 @@ Cursor Objects method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. + .. attribute:: arraysize + + Read/write attribute that controls the number of rows returned by :meth:`fetchmany`. + The default value is 1 which means a single row would be fetched per call. + .. attribute:: description This read-only attribute provides the column names of the last query. To From 846bd39a9ca4fd95f0d3c12e2466f8c89c619944 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 5 Apr 2017 13:42:37 +0300 Subject: [PATCH 125/340] Miscellaneous minor fixes of Misc/NEWS formatting. (#1002) (#1006) (cherry picked from commit a0157b5f11e621f2196af4e918b9f07688a6cd1c) --- Misc/NEWS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 0aefc7583bcb22..2e5904bdd96775 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -349,7 +349,7 @@ Library - Issue #28427: old keys should not remove new values from WeakValueDictionary when collecting from another thread. -- Issue 28923: Remove editor artifacts from Tix.py. +- Issue #28923: Remove editor artifacts from Tix.py. - Issue #28871: Fixed a crash when deallocate deep ElementTree. @@ -472,7 +472,7 @@ Library - Issue #27599: Fixed buffer overrun in binascii.b2a_qp() and binascii.a2b_qp(). -- Issue #19003:m email.generator now replaces only \r and/or \n line +- Issue #19003:m email.generator now replaces only ``\r`` and/or ``\n`` line endings, per the RFC, instead of all unicode line endings. - Issue #28019: itertools.count() no longer rounds non-integer step in range @@ -495,7 +495,7 @@ Library - Issue #27445: Don't pass str(_charset) to MIMEText.set_payload(). Patch by Claude Paroz. -- Issue #22450: urllib now includes an "Accept: */*" header among the +- Issue #22450: urllib now includes an ``Accept: */*`` header among the default headers. This makes the results of REST API requests more consistent and predictable especially when proxy servers are involved. @@ -510,7 +510,7 @@ Library characters, not on arbitrary unicode line breaks. This also fixes a bug in HTTP header parsing. -- Issue 27988: Fix email iter_attachments incorrect mutation of payload list. +- Issue #27988: Fix email iter_attachments incorrect mutation of payload list. - Issue #27691: Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 certs. @@ -961,7 +961,7 @@ Core and Builtins cookie names. - Issue #4806: Avoid masking the original TypeError exception when using star - (*) unpacking in function calls. Based on patch by Hagen Fürstenau and + (``*``) unpacking in function calls. Based on patch by Hagen Fürstenau and Daniel Urban. - Issue #27138: Fix the doc comment for FileFinder.find_spec(). @@ -1341,7 +1341,7 @@ Library - Issue #25672: In the ssl module, enable the SSL_MODE_RELEASE_BUFFERS mode option if it is safe to do so. -- Issue #26012: Don't traverse into symlinks for ** pattern in +- Issue #26012: Don't traverse into symlinks for ``**`` pattern in pathlib.Path.[r]glob(). - Issue #24120: Ignore PermissionError when traversing a tree with @@ -1751,7 +1751,7 @@ Library - Issue #25584: Added "escape" to the __all__ list in the glob module. -- Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. +- Issue #25584: Fixed recursive glob() with patterns starting with ``**``. - Issue #25446: Fix regression in smtplib's AUTH LOGIN support. @@ -3294,7 +3294,7 @@ Library - Issue #23521: Corrected pure python implementation of timedelta division. - * Eliminated OverflowError from timedelta * float for some floats; + * Eliminated OverflowError from ``timedelta * float`` for some floats; * Corrected rounding in timedlta true division. - Issue #21619: Popen objects no longer leave a zombie after exit in the with @@ -4093,7 +4093,7 @@ Library character instead of truncating it. Based on patch by Victor Stinner. - Issue #13968: The glob module now supports recursive search in - subdirectories using the "**" pattern. + subdirectories using the ``**`` pattern. - Issue #21951: Fixed a crash in Tkinter on AIX when called Tcl command with empty string or tuple argument. From 2d8bda5c1618e2917226635502fd5f15cdef123f Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Wed, 5 Apr 2017 06:52:53 -0700 Subject: [PATCH 126/340] correct parse_qs and parse_qsl test case descriptions. (#968) (#998) (cherry picked from commit 257b980b316a5206ecf6c23b958e2b7c4df4f3de) --- Lib/test/test_urlparse.py | 12 ++++++------ Lib/urllib/parse.py | 30 +++++++++++++++++------------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 71abc147a6f9a2..8dac4b14102635 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -6,8 +6,8 @@ RFC3986_BASE = 'http://a/b/c/d;p?q' SIMPLE_BASE = 'http://a/b/c/d' -# A list of test cases. Each test case is a two-tuple that contains -# a string with the query and a dictionary with the expected result. +# Each parse_qsl testcase is a two-tuple that contains +# a string with the query and a list with the expected result. parse_qsl_test_cases = [ ("", []), @@ -42,6 +42,9 @@ (b"a=1;a=2", [(b'a', b'1'), (b'a', b'2')]), ] +# Each parse_qs testcase is a two-tuple that contains +# a string with the query and a dictionary with the expected result. + parse_qs_test_cases = [ ("", {}), ("&", {}), @@ -290,7 +293,6 @@ def test_RFC2368(self): def test_RFC2396(self): # cases from RFC 2396 - self.checkJoin(RFC2396_BASE, 'g:h', 'g:h') self.checkJoin(RFC2396_BASE, 'g', 'http://a/b/c/g') self.checkJoin(RFC2396_BASE, './g', 'http://a/b/c/g') @@ -333,9 +335,7 @@ def test_RFC2396(self): # self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g') # self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g') - def test_RFC3986(self): - # Test cases from RFC3986 self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y') self.checkJoin(RFC3986_BASE, ';x', 'http://a/b/c/;x') self.checkJoin(RFC3986_BASE, 'g:h','g:h') @@ -363,7 +363,7 @@ def test_RFC3986(self): self.checkJoin(RFC3986_BASE, '../../g','http://a/g') self.checkJoin(RFC3986_BASE, '../../../g', 'http://a/g') - #Abnormal Examples + # Abnormal Examples # The 'abnormal scenarios' are incompatible with RFC2986 parsing # Tests are here for reference. diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 566fbf71888186..50641ba69bc83b 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -550,6 +550,7 @@ def unquote(string, encoding='utf-8', errors='replace'): append(bits[i + 1]) return ''.join(res) + def parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace'): """Parse a query given as a string argument. @@ -571,6 +572,8 @@ def parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding and errors: specify how to decode percent-encoded sequences into Unicode characters, as accepted by the bytes.decode() method. + + Returns a dictionary. """ parsed_result = {} pairs = parse_qsl(qs, keep_blank_values, strict_parsing, @@ -582,28 +585,29 @@ def parse_qs(qs, keep_blank_values=False, strict_parsing=False, parsed_result[name] = [value] return parsed_result + def parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace'): """Parse a query given as a string argument. - Arguments: + Arguments: - qs: percent-encoded query string to be parsed + qs: percent-encoded query string to be parsed - keep_blank_values: flag indicating whether blank values in - percent-encoded queries should be treated as blank strings. A - true value indicates that blanks should be retained as blank - strings. The default false value indicates that blank values - are to be ignored and treated as if they were not included. + keep_blank_values: flag indicating whether blank values in + percent-encoded queries should be treated as blank strings. + A true value indicates that blanks should be retained as blank + strings. The default false value indicates that blank values + are to be ignored and treated as if they were not included. - strict_parsing: flag indicating what to do with parsing errors. If - false (the default), errors are silently ignored. If true, - errors raise a ValueError exception. + strict_parsing: flag indicating what to do with parsing errors. If + false (the default), errors are silently ignored. If true, + errors raise a ValueError exception. - encoding and errors: specify how to decode percent-encoded sequences - into Unicode characters, as accepted by the bytes.decode() method. + encoding and errors: specify how to decode percent-encoded sequences + into Unicode characters, as accepted by the bytes.decode() method. - Returns a list, as G-d intended. + Returns a list, as G-d intended. """ qs, _coerce_result = _coerce_args(qs) pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')] From 2cfe583ac8d3eaa98e3d2aca597577ce4787ca20 Mon Sep 17 00:00:00 2001 From: cocoatomo Date: Thu, 6 Apr 2017 23:00:15 +0900 Subject: [PATCH 127/340] [3.5] bpo-19225: Lack of c api exceptions doc (#965) * Keep the c-api exception doc up-to-date cherry-pick'ed from ec1f5df..e3d6db3 and fix conflict --- Doc/c-api/exceptions.rst | 201 ++++++++++++++++++++++++++++----------- Misc/ACKS | 1 + 2 files changed, 146 insertions(+), 56 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index c389888b2bb01c..cf2385f3deb3c7 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -735,6 +735,60 @@ All standard Python exceptions are available as global variables whose names are :c:type:`PyObject\*`; they are all class objects. For completeness, here are all the variables: +.. index:: + single: PyExc_BaseException + single: PyExc_Exception + single: PyExc_ArithmeticError + single: PyExc_AssertionError + single: PyExc_AttributeError + single: PyExc_BlockingIOError + single: PyExc_BrokenPipeError + single: PyExc_BufferError + single: PyExc_ChildProcessError + single: PyExc_ConnectionAbortedError + single: PyExc_ConnectionError + single: PyExc_ConnectionRefusedError + single: PyExc_ConnectionResetError + single: PyExc_EOFError + single: PyExc_FileExistsError + single: PyExc_FileNotFoundError + single: PyExc_FloatingPointError + single: PyExc_GeneratorExit + single: PyExc_ImportError + single: PyExc_IndentationError + single: PyExc_IndexError + single: PyExc_InterruptedError + single: PyExc_IsADirectoryError + single: PyExc_KeyError + single: PyExc_KeyboardInterrupt + single: PyExc_LookupError + single: PyExc_MemoryError + single: PyExc_NameError + single: PyExc_NotADirectoryError + single: PyExc_NotImplementedError + single: PyExc_OSError + single: PyExc_OverflowError + single: PyExc_PermissionError + single: PyExc_ProcessLookupError + single: PyExc_RecursionError + single: PyExc_ReferenceError + single: PyExc_RuntimeError + single: PyExc_StopAsyncIteration + single: PyExc_StopIteration + single: PyExc_SyntaxError + single: PyExc_SystemError + single: PyExc_SystemExit + single: PyExc_TabError + single: PyExc_TimeoutError + single: PyExc_TypeError + single: PyExc_UnboundLocalError + single: PyExc_UnicodeDecodeError + single: PyExc_UnicodeEncodeError + single: PyExc_UnicodeError + single: PyExc_UnicodeTranslateError + single: PyExc_ValueError + single: PyExc_ZeroDivisionError + +-----------------------------------------+---------------------------------+----------+ | C Name | Python Name | Notes | +=========================================+=================================+==========+ @@ -744,8 +798,6 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ArithmeticError` | :exc:`ArithmeticError` | \(1) | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) | -+-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_AssertionError` | :exc:`AssertionError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_AttributeError` | :exc:`AttributeError` | | @@ -754,26 +806,32 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_BrokenPipeError` | :exc:`BrokenPipeError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_ChildProcessError` | :exc:`ChildProcessError` | | +| :c:data:`PyExc_BufferError` | :exc:`BufferError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_ConnectionError` | :exc:`ConnectionError` | | +| :c:data:`PyExc_ChildProcessError` | :exc:`ChildProcessError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ConnectionAbortedError` | :exc:`ConnectionAbortedError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_ConnectionError` | :exc:`ConnectionError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ConnectionRefusedError` | :exc:`ConnectionRefusedError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ConnectionResetError` | :exc:`ConnectionResetError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_EOFError` | :exc:`EOFError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_FileExistsError` | :exc:`FileExistsError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_FileNotFoundError` | :exc:`FileNotFoundError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_EOFError` | :exc:`EOFError` | | -+-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_FloatingPointError` | :exc:`FloatingPointError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_GeneratorExit` | :exc:`GeneratorExit` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ImportError` | :exc:`ImportError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_IndentationError` | :exc:`IndentationError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_IndexError` | :exc:`IndexError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_InterruptedError` | :exc:`InterruptedError` | | @@ -784,6 +842,8 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_KeyboardInterrupt` | :exc:`KeyboardInterrupt` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_LookupError` | :exc:`LookupError` | \(1) | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_MemoryError` | :exc:`MemoryError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_NameError` | :exc:`NameError` | | @@ -806,16 +866,32 @@ the variables: +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_RuntimeError` | :exc:`RuntimeError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_StopAsyncIteration` | :exc:`StopAsyncIteration` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_StopIteration` | :exc:`StopIteration` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_SyntaxError` | :exc:`SyntaxError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_SystemError` | :exc:`SystemError` | | +-----------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_TimeoutError` | :exc:`TimeoutError` | | -+-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_SystemExit` | :exc:`SystemExit` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_TabError` | :exc:`TabError` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_TimeoutError` | :exc:`TimeoutError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_TypeError` | :exc:`TypeError` | | +-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnboundLocalError` | :exc:`UnboundLocalError` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnicodeDecodeError` | :exc:`UnicodeDecodeError` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnicodeEncodeError` | :exc:`UnicodeEncodeError` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnicodeError` | :exc:`UnicodeError` | | ++-----------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnicodeTranslateError` | :exc:`UnicodeTranslateError` | | ++-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ValueError` | :exc:`ValueError` | | +-----------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ZeroDivisionError` | :exc:`ZeroDivisionError` | | @@ -832,11 +908,15 @@ the variables: and :c:data:`PyExc_TimeoutError` were introduced following :pep:`3151`. .. versionadded:: 3.5 - :c:data:`PyExc_RecursionError`. - + :c:data:`PyExc_StopAsyncIteration` and :c:data:`PyExc_RecursionError`. These are compatibility aliases to :c:data:`PyExc_OSError`: +.. index:: + single: PyExc_EnvironmentError + single: PyExc_IOError + single: PyExc_WindowsError + +-------------------------------------+----------+ | C Name | Notes | +=====================================+==========+ @@ -850,52 +930,6 @@ These are compatibility aliases to :c:data:`PyExc_OSError`: .. versionchanged:: 3.3 These aliases used to be separate exception types. - -.. index:: - single: PyExc_BaseException - single: PyExc_Exception - single: PyExc_ArithmeticError - single: PyExc_LookupError - single: PyExc_AssertionError - single: PyExc_AttributeError - single: PyExc_BlockingIOError - single: PyExc_BrokenPipeError - single: PyExc_ConnectionError - single: PyExc_ConnectionAbortedError - single: PyExc_ConnectionRefusedError - single: PyExc_ConnectionResetError - single: PyExc_EOFError - single: PyExc_FileExistsError - single: PyExc_FileNotFoundError - single: PyExc_FloatingPointError - single: PyExc_ImportError - single: PyExc_IndexError - single: PyExc_InterruptedError - single: PyExc_IsADirectoryError - single: PyExc_KeyError - single: PyExc_KeyboardInterrupt - single: PyExc_MemoryError - single: PyExc_NameError - single: PyExc_NotADirectoryError - single: PyExc_NotImplementedError - single: PyExc_OSError - single: PyExc_OverflowError - single: PyExc_PermissionError - single: PyExc_ProcessLookupError - single: PyExc_RecursionError - single: PyExc_ReferenceError - single: PyExc_RuntimeError - single: PyExc_SyntaxError - single: PyExc_SystemError - single: PyExc_SystemExit - single: PyExc_TimeoutError - single: PyExc_TypeError - single: PyExc_ValueError - single: PyExc_ZeroDivisionError - single: PyExc_EnvironmentError - single: PyExc_IOError - single: PyExc_WindowsError - Notes: (1) @@ -907,3 +941,58 @@ Notes: (3) Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. + +Standard Warnings +================= + +All standard Python warning categories are available as global variables whose +names are ``PyExc_`` followed by the Python exception name. These have the type +:c:type:`PyObject\*`; they are all class objects. For completeness, here are all +the variables: + +.. index:: + single: PyExc_Warning + single: PyExc_BytesWarning + single: PyExc_DepricationWarning + single: PyExc_FutureWarning + single: PyExc_ImportWarning + single: PyExc_PendingDeprecationWarning + single: PyExc_ResourceWarning + single: PyExc_RuntimeWarning + single: PyExc_SyntaxWarning + single: PyExc_UnicodeWarning + single: PyExc_UserWarning + ++------------------------------------------+---------------------------------+----------+ +| C Name | Python Name | Notes | ++==========================================+=================================+==========+ +| :c:data:`PyExc_Warning` | :exc:`Warning` | \(1) | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_BytesWarning` | :exc:`BytesWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_DeprecationWarning` | :exc:`DeprecationWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_FutureWarning` | :exc:`FutureWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_ImportWarning` | :exc:`ImportWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_PendingDepricationWarning`| :exc:`PendingDeprecationWarning`| | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_ResourceWarning` | :exc:`ResourceWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_RuntimeWarning` | :exc:`RuntimeWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_SyntaxWarning` | :exc:`SyntaxWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UnicodeWarning` | :exc:`UnicodeWarning` | | ++------------------------------------------+---------------------------------+----------+ +| :c:data:`PyExc_UserWarning` | :exc:`UserWarning` | | ++------------------------------------------+---------------------------------+----------+ + +.. versionadded:: 3.2 + :c:data:`PyExc_ResourceWarning`. + +Notes: + +(1) + This is a base class for other standard warning categories. diff --git a/Misc/ACKS b/Misc/ACKS index edfbb448bd9155..42790834da765f 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -764,6 +764,7 @@ Jason Killen Jan Kim Taek Joo Kim Sam Kimbrel +Tomohiko Kinebuchi James King W. Trevor King Paul Kippes From 041e6006db57820dcd05f06bd15d26512c575841 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Fri, 7 Apr 2017 00:56:41 -0700 Subject: [PATCH 128/340] Remove Invalid comment in test_urllib2.py (#1021) (cherry picked from commit fd0cd07a5a3c964c084f4efc5bbcb89dd2193ee6) --- Lib/test/test_urllib2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/test/test_urllib2.py b/Lib/test/test_urllib2.py index 49e6c82d4339a8..3ed81ce5105119 100644 --- a/Lib/test/test_urllib2.py +++ b/Lib/test/test_urllib2.py @@ -833,7 +833,6 @@ def test_file(self): req = Request(url) try: h.file_open(req) - # XXXX remove OSError when bug fixed except urllib.error.URLError: self.assertFalse(ftp) else: From f688f180b21679c06d5258e88c688635ed719473 Mon Sep 17 00:00:00 2001 From: Barry Warsaw Date: Fri, 7 Apr 2017 16:50:20 -0400 Subject: [PATCH 129/340] Fix a minor typo. (#1032) (#1036) (cherry picked from commit dd9a0a14c89d57e43898d4b866b8c161e4ff8506) --- Doc/library/asyncio-protocol.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index e0d2b0f0b6e781..2e1a11bed7503b 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -381,7 +381,7 @@ The following callbacks are called on :class:`Protocol` instances: .. method:: Protocol.eof_received() - Calls when the other end signals it won't send any more data + Called when the other end signals it won't send any more data (for example by calling :meth:`write_eof`, if the other end also uses asyncio). From ae0915e42d8cd96e5ced1fc442ea078b4a59e82d Mon Sep 17 00:00:00 2001 From: Vinay Sajip Date: Fri, 7 Apr 2017 23:24:51 +0100 Subject: [PATCH 130/340] Closes bpo-29939: suppress compiler warnings in _ctypes_test (#1039) Changed test code to suppress a compiler warning, while taking care to avoid the code being optimized out by the compiler. (cherry picked from commit 164d30eb1e66575dafee6af4fca4cbf52c7fbe6a) --- Modules/_ctypes/_ctypes_test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index 20e65d2c1aef2b..e3240c526f7859 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -52,9 +52,9 @@ _testfunc_cbk_large_struct(Test in, void (*func)(Test)) EXPORT(void) _testfunc_large_struct_update_value(Test in) { - in.first = 0x0badf00d; - in.second = 0x0badf00d; - in.third = 0x0badf00d; + ((volatile Test *)&in)->first = 0x0badf00d; + ((volatile Test *)&in)->second = 0x0badf00d; + ((volatile Test *)&in)->third = 0x0badf00d; } EXPORT(void)testfunc_array(int values[4]) From fa25f16a4499178d7d79c18d2d68be7f70594106 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 8 Apr 2017 11:18:30 +0300 Subject: [PATCH 131/340] Expand the PySlice_GetIndicesEx macro. (#1023) (#1045) (cherry picked from commit b879fe82e7e5c3f7673c9a7fa4aad42bd05445d8) --- Modules/_ctypes/_ctypes.c | 10 ++++------ Modules/_elementtree.c | 12 ++++++------ Modules/_testbuffer.c | 7 ++++--- Modules/arraymodule.c | 11 ++++++----- Modules/mmapmodule.c | 9 ++++----- Objects/bytearrayobject.c | 12 ++++++------ Objects/bytesobject.c | 6 +++--- Objects/listobject.c | 10 ++++++---- Objects/memoryobject.c | 4 ++-- Objects/tupleobject.c | 6 +++--- Objects/unicodeobject.c | 5 +++-- 11 files changed, 47 insertions(+), 45 deletions(-) diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index b32a0ce9e81b4d..33fe659d45f88f 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -4279,11 +4279,10 @@ Array_subscript(PyObject *myself, PyObject *item) PyObject *np; Py_ssize_t start, stop, step, slicelen, cur, i; - if (PySlice_GetIndicesEx(item, - self->b_length, &start, &stop, - &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); stgdict = PyObject_stgdict((PyObject *)self); assert(stgdict); /* Cannot be NULL for array object instances */ @@ -4420,11 +4419,10 @@ Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value) else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen, otherlen, i, cur; - if (PySlice_GetIndicesEx(item, - self->b_length, &start, &stop, - &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } + slicelen = PySlice_AdjustIndices(self->b_length, &start, &stop, step); if ((step < 0 && start < stop) || (step > 0 && start > stop)) stop = start; diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index c800f92f70d766..0276452db4c337 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1688,11 +1688,11 @@ element_subscr(PyObject* self_, PyObject* item) if (!self->extra) return PyList_New(0); - if (PySlice_GetIndicesEx(item, - self->extra->length, - &start, &stop, &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, + step); if (slicelen <= 0) return PyList_New(0); @@ -1744,11 +1744,11 @@ element_ass_subscr(PyObject* self_, PyObject* item, PyObject* value) return -1; } - if (PySlice_GetIndicesEx(item, - self->extra->length, - &start, &stop, &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } + slicelen = PySlice_AdjustIndices(self->extra->length, &start, &stop, + step); if (value == NULL) { /* Delete slice */ diff --git a/Modules/_testbuffer.c b/Modules/_testbuffer.c index 43db8a8e53a34a..0885a0333ebdaa 100644 --- a/Modules/_testbuffer.c +++ b/Modules/_testbuffer.c @@ -1714,10 +1714,10 @@ init_slice(Py_buffer *base, PyObject *key, int dim) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(key, base->shape[dim], - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(key, &start, &stop, &step) < 0) { return -1; } + slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step); if (base->suboffsets == NULL || dim == 0) { @@ -1934,9 +1934,10 @@ slice_indices(PyObject *self, PyObject *args) "first argument must be a slice object"); return NULL; } - if (PySlice_GetIndicesEx(key, len, &s[0], &s[1], &s[2], &s[3]) < 0) { + if (PySlice_Unpack(key, &s[0], &s[1], &s[2]) < 0) { return NULL; } + s[3] = PySlice_AdjustIndices(len, &s[0], &s[1], s[2]); ret = PyTuple_New(4); if (ret == NULL) diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c index 8612847fcafe81..f615a690f31360 100644 --- a/Modules/arraymodule.c +++ b/Modules/arraymodule.c @@ -2343,10 +2343,11 @@ array_subscr(arrayobject* self, PyObject* item) arrayobject* ar; int itemsize = self->ob_descr->itemsize; - if (PySlice_GetIndicesEx(item, Py_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); if (slicelength <= 0) { return newarrayobject(&Arraytype, 0, self->ob_descr); @@ -2414,11 +2415,11 @@ array_ass_subscr(arrayobject* self, PyObject* item, PyObject* value) return (*self->ob_descr->setitem)(self, i, value); } else if (PySlice_Check(item)) { - if (PySlice_GetIndicesEx(item, - Py_SIZE(self), &start, &stop, - &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); } else { PyErr_SetString(PyExc_TypeError, diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c index 4eb9274c665e7c..d80b1f63a06437 100644 --- a/Modules/mmapmodule.c +++ b/Modules/mmapmodule.c @@ -807,10 +807,10 @@ mmap_subscript(mmap_object *self, PyObject *item) else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelen; - if (PySlice_GetIndicesEx(item, self->size, - &start, &stop, &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); if (slicelen <= 0) return PyBytes_FromStringAndSize("", 0); @@ -933,11 +933,10 @@ mmap_ass_subscript(mmap_object *self, PyObject *item, PyObject *value) Py_ssize_t start, stop, step, slicelen; Py_buffer vbuf; - if (PySlice_GetIndicesEx(item, - self->size, &start, &stop, - &step, &slicelen) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } + slicelen = PySlice_AdjustIndices(self->size, &start, &stop, step); if (value == NULL) { PyErr_SetString(PyExc_TypeError, "mmap object doesn't support slice deletion"); diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 5132eba52bf5ac..85c6d1b748eff8 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -427,11 +427,11 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index) } else if (PySlice_Check(index)) { Py_ssize_t start, stop, step, slicelength, cur, i; - if (PySlice_GetIndicesEx(index, - PyByteArray_GET_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(index, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), + &start, &stop, step); if (slicelength <= 0) return PyByteArray_FromStringAndSize("", 0); @@ -657,11 +657,11 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu } } else if (PySlice_Check(index)) { - if (PySlice_GetIndicesEx(index, - PyByteArray_GET_SIZE(self), - &start, &stop, &step, &slicelen) < 0) { + if (PySlice_Unpack(index, &start, &stop, &step) < 0) { return -1; } + slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start, + &stop, step); } else { PyErr_Format(PyExc_TypeError, diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 8ede5f0c599671..77dd45e84af8e9 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1534,11 +1534,11 @@ bytes_subscript(PyBytesObject* self, PyObject* item) char* result_buf; PyObject* result; - if (PySlice_GetIndicesEx(item, - PyBytes_GET_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(PyBytes_GET_SIZE(self), &start, + &stop, step); if (slicelength <= 0) { return PyBytes_FromStringAndSize("", 0); diff --git a/Objects/listobject.c b/Objects/listobject.c index e1e3cf018aaa7b..8100048561565a 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2421,10 +2421,11 @@ list_subscript(PyListObject* self, PyObject* item) PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx(item, Py_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); if (slicelength <= 0) { return PyList_New(0); @@ -2470,10 +2471,11 @@ list_ass_subscript(PyListObject* self, PyObject* item, PyObject* value) else if (PySlice_Check(item)) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(item, Py_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return -1; } + slicelength = PySlice_AdjustIndices(Py_SIZE(self), &start, &stop, + step); if (step == 1) return list_ass_slice(self, start, stop, value); diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index e261ee0cbfc8c3..45849be69c1fe2 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -2311,10 +2311,10 @@ init_slice(Py_buffer *base, PyObject *key, int dim) { Py_ssize_t start, stop, step, slicelength; - if (PySlice_GetIndicesEx(key, base->shape[dim], - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(key, &start, &stop, &step) < 0) { return -1; } + slicelength = PySlice_AdjustIndices(base->shape[dim], &start, &stop, step); if (base->suboffsets == NULL || dim == 0) { diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 48719454fe6537..19a6fed5cfc712 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -713,11 +713,11 @@ tuplesubscript(PyTupleObject* self, PyObject* item) PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx(item, - PyTuple_GET_SIZE(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(PyTuple_GET_SIZE(self), &start, + &stop, step); if (slicelength <= 0) { return PyTuple_New(0); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 64a3760328f9fa..d7c9a34c39451b 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -13804,10 +13804,11 @@ unicode_subscript(PyObject* self, PyObject* item) int src_kind, dest_kind; Py_UCS4 ch, max_char, kind_limit; - if (PySlice_GetIndicesEx(item, PyUnicode_GET_LENGTH(self), - &start, &stop, &step, &slicelength) < 0) { + if (PySlice_Unpack(item, &start, &stop, &step) < 0) { return NULL; } + slicelength = PySlice_AdjustIndices(PyUnicode_GET_LENGTH(self), + &start, &stop, step); if (slicelength <= 0) { _Py_RETURN_UNICODE_EMPTY(); From e63f8f293a96ceebf06de15b4e1c97dbbff0f6a8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 8 Apr 2017 11:26:03 +0300 Subject: [PATCH 132/340] bpo-29998: Pickling and copying ImportError now preserves name and path (#1010) (#1043) attributes. (cherry picked from commit b785396ab451b0c9d6ae9ee5a9e56c810209a6cb) --- Lib/test/test_exceptions.py | 20 ++++++++++++++++ Misc/NEWS | 3 +++ Objects/exceptions.c | 48 +++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 96c3a48c317eb7..12cf7b84a7c2bd 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1,5 +1,6 @@ # Python test set -- part 5, built-in exceptions +import copy import os import sys import unittest @@ -1120,6 +1121,25 @@ def test_non_str_argument(self): exc = ImportError(arg) self.assertEqual(str(arg), str(exc)) + def test_copy_pickle(self): + for kwargs in (dict(), + dict(name='somename'), + dict(path='somepath'), + dict(name='somename', path='somepath')): + orig = ImportError('test', **kwargs) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + exc = pickle.loads(pickle.dumps(orig, proto)) + self.assertEqual(exc.args, ('test',)) + self.assertEqual(exc.msg, 'test') + self.assertEqual(exc.name, orig.name) + self.assertEqual(exc.path, orig.path) + for c in copy.copy, copy.deepcopy: + exc = c(orig) + self.assertEqual(exc.args, ('test',)) + self.assertEqual(exc.msg, 'test') + self.assertEqual(exc.name, orig.name) + self.assertEqual(exc.path, orig.path) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index 2e5904bdd96775..49926830dcb3a6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Extension Modules Library ------- +- bpo-29998: Pickling and copying ImportError now preserves name and path + attributes. + - bpo-29942: Fix a crash in itertools.chain.from_iterable when encountering long runs of empty iterables. diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 981ead2172a0ff..345a0fef70981d 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -692,6 +692,53 @@ ImportError_str(PyImportErrorObject *self) } } +static PyObject * +ImportError_getstate(PyImportErrorObject *self) +{ + PyObject *dict = ((PyBaseExceptionObject *)self)->dict; + if (self->name || self->path) { + _Py_IDENTIFIER(name); + _Py_IDENTIFIER(path); + dict = dict ? PyDict_Copy(dict) : PyDict_New(); + if (dict == NULL) + return NULL; + if (self->name && _PyDict_SetItemId(dict, &PyId_name, self->name) < 0) { + Py_DECREF(dict); + return NULL; + } + if (self->path && _PyDict_SetItemId(dict, &PyId_path, self->path) < 0) { + Py_DECREF(dict); + return NULL; + } + return dict; + } + else if (dict) { + Py_INCREF(dict); + return dict; + } + else { + Py_RETURN_NONE; + } +} + +/* Pickling support */ +static PyObject * +ImportError_reduce(PyImportErrorObject *self) +{ + PyObject *res; + PyObject *args; + PyObject *state = ImportError_getstate(self); + if (state == NULL) + return NULL; + args = ((PyBaseExceptionObject *)self)->args; + if (state == Py_None) + res = PyTuple_Pack(2, Py_TYPE(self), args); + else + res = PyTuple_Pack(3, Py_TYPE(self), args, state); + Py_DECREF(state); + return res; +} + static PyMemberDef ImportError_members[] = { {"msg", T_OBJECT, offsetof(PyImportErrorObject, msg), 0, PyDoc_STR("exception message")}, @@ -703,6 +750,7 @@ static PyMemberDef ImportError_members[] = { }; static PyMethodDef ImportError_methods[] = { + {"__reduce__", (PyCFunction)ImportError_reduce, METH_NOARGS}, {NULL} }; From c82d39479a88154bd72a3a304be5f473c118da95 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 9 Apr 2017 19:22:50 +1000 Subject: [PATCH 133/340] bpo-29798: Handle git worktree in patchcheck The original attempted fix missed an `isdir()` call in `get_base_branch()`. (cherry picked from commit 2abfdf5a81383d3b1ed6b7321903a9a168c373c5) --- Tools/scripts/patchcheck.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py index f4ec7d8a30ea23..33a9fead879325 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -70,7 +70,7 @@ def get_git_upstream_remote(): @status("Getting base branch for PR", info=lambda x: x if x is not None else "not a PR branch") def get_base_branch(): - if not os.path.isdir(os.path.join(SRCDIR, '.git')): + if not os.path.exists(os.path.join(SRCDIR, '.git')): # Not a git checkout, so there's no base branch return None version = sys.version_info From bd18351c31573ab9a8580677004370a774a4eaae Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Sun, 9 Apr 2017 20:57:15 +1000 Subject: [PATCH 134/340] bpo-29506: Clarify deep copy note in copy module The reference to administrative data was confusing to readers, so this simplifies the note to explain that deep copying may copy more then you intended, such as data that you expected to be shared between copies. (cherry picked from commit 19e04942562a980ad2519f6ff79c455a7472783b) --- Doc/library/copy.rst | 4 ++-- Misc/ACKS | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst index d0b861d469bc05..2041d9175ea587 100644 --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -47,8 +47,8 @@ copy operations: * Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop. -* Because deep copy copies *everything* it may copy too much, e.g., - even administrative data structures that should be shared even between copies. +* Because deep copy copies everything it may copy too much, such as data + which is intended to be shared between copies. The :func:`deepcopy` function avoids these problems by: diff --git a/Misc/ACKS b/Misc/ACKS index 42790834da765f..babd4950da6797 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -759,6 +759,7 @@ Lawrence Kesteloot Vivek Khera Dhiru Kholia Akshit Khurana +Sanyam Khurana Mads Kiilerich Jason Killen Jan Kim From d4489da36044b554921d6c566ed3c9f1013cb97e Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 9 Apr 2017 10:14:48 -0700 Subject: [PATCH 135/340] Remove invalid comment in urllib.request.(#1056) (cherry picked from commit a2a9ddd923a849124bdd1c484f70f02df6fde0e9) --- Lib/urllib/request.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index a46c6894935757..0cd03332b0e972 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1594,14 +1594,10 @@ def pathname2url(pathname): of the 'file' scheme; not recommended for general use.""" return quote(pathname) -# This really consists of two pieces: -# (1) a class which handles opening of all sorts of URLs -# (plus assorted utilities etc.) -# (2) a set of functions for parsing URLs -# XXX Should these be separated out into different modules? - ftpcache = {} + + class URLopener: """Class to open URLs. This is a class rather than just a subroutine because we may need From aa218af34494230e8f258b3ed4f9cf5070225a92 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 9 Apr 2017 15:16:14 -0700 Subject: [PATCH 136/340] [3.5] Correct typo in configparser.rst (GH-1012) (GH-1027) (cherry picked from commit 01fa9ae5460b00bf1ced500c797176ebd3fb060d) --- Doc/library/configparser.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index e09562dc9046c7..6f1c55e2351aa1 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -34,8 +34,8 @@ can be customized by end users easily. .. seealso:: Module :mod:`shlex` - Support for a creating Unix shell-like mini-languages which can be used - as an alternate format for application configuration files. + Support for creating Unix shell-like mini-languages which can be used as + an alternate format for application configuration files. Module :mod:`json` The json module implements a subset of JavaScript syntax which can also From 1adca396766d318981c0a4b98d9cff2661a57735 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sun, 9 Apr 2017 20:38:00 -0700 Subject: [PATCH 137/340] Remove OSError related comment in urllib.request. (#1071) (cherry picked from commit 6dfcc81f6b1c82a71a1c876e14424fb8b3573447) --- Lib/urllib/request.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 0cd03332b0e972..e98be0cde1d355 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -1424,7 +1424,6 @@ def open_local_file(self, req): origurl = 'file://' + filename return addinfourl(open(localfile, 'rb'), headers, origurl) except OSError as exp: - # users shouldn't expect OSErrors coming from urlopen() raise URLError(exp) raise URLError('file not on local host') From 72b1d419ac5f7cd9ef82ffd2ffe21aa9b34e21d2 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Thu, 13 Apr 2017 11:37:38 +0800 Subject: [PATCH 138/340] bpo-26985: Add missing info of code object in inspect documentation (GH-1090) (GH-1100) --- Doc/library/inspect.rst | 379 +++++++++++++++++++++------------------- Lib/inspect.py | 30 ++-- Misc/NEWS | 2 + 3 files changed, 220 insertions(+), 191 deletions(-) diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 9526a0d59dabb5..16e33f0f724102 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -34,185 +34,198 @@ provided as convenient choices for the second argument to :func:`getmembers`. They also help you determine when you can expect to find the following special attributes: -+-----------+-----------------+---------------------------+ -| Type | Attribute | Description | -+===========+=================+===========================+ -| module | __doc__ | documentation string | -+-----------+-----------------+---------------------------+ -| | __file__ | filename (missing for | -| | | built-in modules) | -+-----------+-----------------+---------------------------+ -| class | __doc__ | documentation string | -+-----------+-----------------+---------------------------+ -| | __name__ | name with which this | -| | | class was defined | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | __module__ | name of module in which | -| | | this class was defined | -+-----------+-----------------+---------------------------+ -| method | __doc__ | documentation string | -+-----------+-----------------+---------------------------+ -| | __name__ | name with which this | -| | | method was defined | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | __func__ | function object | -| | | containing implementation | -| | | of method | -+-----------+-----------------+---------------------------+ -| | __self__ | instance to which this | -| | | method is bound, or | -| | | ``None`` | -+-----------+-----------------+---------------------------+ -| function | __doc__ | documentation string | -+-----------+-----------------+---------------------------+ -| | __name__ | name with which this | -| | | function was defined | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | __code__ | code object containing | -| | | compiled function | -| | | :term:`bytecode` | -+-----------+-----------------+---------------------------+ -| | __defaults__ | tuple of any default | -| | | values for positional or | -| | | keyword parameters | -+-----------+-----------------+---------------------------+ -| | __kwdefaults__ | mapping of any default | -| | | values for keyword-only | -| | | parameters | -+-----------+-----------------+---------------------------+ -| | __globals__ | global namespace in which | -| | | this function was defined | -+-----------+-----------------+---------------------------+ -| | __annotations__ | mapping of parameters | -| | | names to annotations; | -| | | ``"return"`` key is | -| | | reserved for return | -| | | annotations. | -+-----------+-----------------+---------------------------+ -| traceback | tb_frame | frame object at this | -| | | level | -+-----------+-----------------+---------------------------+ -| | tb_lasti | index of last attempted | -| | | instruction in bytecode | -+-----------+-----------------+---------------------------+ -| | tb_lineno | current line number in | -| | | Python source code | -+-----------+-----------------+---------------------------+ -| | tb_next | next inner traceback | -| | | object (called by this | -| | | level) | -+-----------+-----------------+---------------------------+ -| frame | f_back | next outer frame object | -| | | (this frame's caller) | -+-----------+-----------------+---------------------------+ -| | f_builtins | builtins namespace seen | -| | | by this frame | -+-----------+-----------------+---------------------------+ -| | f_code | code object being | -| | | executed in this frame | -+-----------+-----------------+---------------------------+ -| | f_globals | global namespace seen by | -| | | this frame | -+-----------+-----------------+---------------------------+ -| | f_lasti | index of last attempted | -| | | instruction in bytecode | -+-----------+-----------------+---------------------------+ -| | f_lineno | current line number in | -| | | Python source code | -+-----------+-----------------+---------------------------+ -| | f_locals | local namespace seen by | -| | | this frame | -+-----------+-----------------+---------------------------+ -| | f_restricted | 0 or 1 if frame is in | -| | | restricted execution mode | -+-----------+-----------------+---------------------------+ -| | f_trace | tracing function for this | -| | | frame, or ``None`` | -+-----------+-----------------+---------------------------+ -| code | co_argcount | number of arguments (not | -| | | including \* or \*\* | -| | | args) | -+-----------+-----------------+---------------------------+ -| | co_code | string of raw compiled | -| | | bytecode | -+-----------+-----------------+---------------------------+ -| | co_consts | tuple of constants used | -| | | in the bytecode | -+-----------+-----------------+---------------------------+ -| | co_filename | name of file in which | -| | | this code object was | -| | | created | -+-----------+-----------------+---------------------------+ -| | co_firstlineno | number of first line in | -| | | Python source code | -+-----------+-----------------+---------------------------+ -| | co_flags | bitmap of ``CO_*`` flags, | -| | | read more :ref:`here | -| | | `| -+-----------+-----------------+---------------------------+ -| | co_lnotab | encoded mapping of line | -| | | numbers to bytecode | -| | | indices | -+-----------+-----------------+---------------------------+ -| | co_name | name with which this code | -| | | object was defined | -+-----------+-----------------+---------------------------+ -| | co_names | tuple of names of local | -| | | variables | -+-----------+-----------------+---------------------------+ -| | co_nlocals | number of local variables | -+-----------+-----------------+---------------------------+ -| | co_stacksize | virtual machine stack | -| | | space required | -+-----------+-----------------+---------------------------+ -| | co_varnames | tuple of names of | -| | | arguments and local | -| | | variables | -+-----------+-----------------+---------------------------+ -| generator | __name__ | name | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | gi_frame | frame | -+-----------+-----------------+---------------------------+ -| | gi_running | is the generator running? | -+-----------+-----------------+---------------------------+ -| | gi_code | code | -+-----------+-----------------+---------------------------+ -| | gi_yieldfrom | object being iterated by | -| | | ``yield from``, or | -| | | ``None`` | -+-----------+-----------------+---------------------------+ -| coroutine | __name__ | name | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | cr_await | object being awaited on, | -| | | or ``None`` | -+-----------+-----------------+---------------------------+ -| | cr_frame | frame | -+-----------+-----------------+---------------------------+ -| | cr_running | is the coroutine running? | -+-----------+-----------------+---------------------------+ -| | cr_code | code | -+-----------+-----------------+---------------------------+ -| builtin | __doc__ | documentation string | -+-----------+-----------------+---------------------------+ -| | __name__ | original name of this | -| | | function or method | -+-----------+-----------------+---------------------------+ -| | __qualname__ | qualified name | -+-----------+-----------------+---------------------------+ -| | __self__ | instance to which a | -| | | method is bound, or | -| | | ``None`` | -+-----------+-----------------+---------------------------+ ++-----------+-------------------+---------------------------+ +| Type | Attribute | Description | ++===========+===================+===========================+ +| module | __doc__ | documentation string | ++-----------+-------------------+---------------------------+ +| | __file__ | filename (missing for | +| | | built-in modules) | ++-----------+-------------------+---------------------------+ +| class | __doc__ | documentation string | ++-----------+-------------------+---------------------------+ +| | __name__ | name with which this | +| | | class was defined | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | __module__ | name of module in which | +| | | this class was defined | ++-----------+-------------------+---------------------------+ +| method | __doc__ | documentation string | ++-----------+-------------------+---------------------------+ +| | __name__ | name with which this | +| | | method was defined | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | __func__ | function object | +| | | containing implementation | +| | | of method | ++-----------+-------------------+---------------------------+ +| | __self__ | instance to which this | +| | | method is bound, or | +| | | ``None`` | ++-----------+-------------------+---------------------------+ +| function | __doc__ | documentation string | ++-----------+-------------------+---------------------------+ +| | __name__ | name with which this | +| | | function was defined | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | __code__ | code object containing | +| | | compiled function | +| | | :term:`bytecode` | ++-----------+-------------------+---------------------------+ +| | __defaults__ | tuple of any default | +| | | values for positional or | +| | | keyword parameters | ++-----------+-------------------+---------------------------+ +| | __kwdefaults__ | mapping of any default | +| | | values for keyword-only | +| | | parameters | ++-----------+-------------------+---------------------------+ +| | __globals__ | global namespace in which | +| | | this function was defined | ++-----------+-------------------+---------------------------+ +| | __annotations__ | mapping of parameters | +| | | names to annotations; | +| | | ``"return"`` key is | +| | | reserved for return | +| | | annotations. | ++-----------+-------------------+---------------------------+ +| traceback | tb_frame | frame object at this | +| | | level | ++-----------+-------------------+---------------------------+ +| | tb_lasti | index of last attempted | +| | | instruction in bytecode | ++-----------+-------------------+---------------------------+ +| | tb_lineno | current line number in | +| | | Python source code | ++-----------+-------------------+---------------------------+ +| | tb_next | next inner traceback | +| | | object (called by this | +| | | level) | ++-----------+-------------------+---------------------------+ +| frame | f_back | next outer frame object | +| | | (this frame's caller) | ++-----------+-------------------+---------------------------+ +| | f_builtins | builtins namespace seen | +| | | by this frame | ++-----------+-------------------+---------------------------+ +| | f_code | code object being | +| | | executed in this frame | ++-----------+-------------------+---------------------------+ +| | f_globals | global namespace seen by | +| | | this frame | ++-----------+-------------------+---------------------------+ +| | f_lasti | index of last attempted | +| | | instruction in bytecode | ++-----------+-------------------+---------------------------+ +| | f_lineno | current line number in | +| | | Python source code | ++-----------+-------------------+---------------------------+ +| | f_locals | local namespace seen by | +| | | this frame | ++-----------+-------------------+---------------------------+ +| | f_restricted | 0 or 1 if frame is in | +| | | restricted execution mode | ++-----------+-------------------+---------------------------+ +| | f_trace | tracing function for this | +| | | frame, or ``None`` | ++-----------+-------------------+---------------------------+ +| code | co_argcount | number of arguments (not | +| | | including keyword only | +| | | arguments, \* or \*\* | +| | | args) | ++-----------+-------------------+---------------------------+ +| | co_code | string of raw compiled | +| | | bytecode | ++-----------+-------------------+---------------------------+ +| | co_cellvars | tuple of names of cell | +| | | variables (referenced by | +| | | containing scopes) | ++-----------+-------------------+---------------------------+ +| | co_consts | tuple of constants used | +| | | in the bytecode | ++-----------+-------------------+---------------------------+ +| | co_filename | name of file in which | +| | | this code object was | +| | | created | ++-----------+-------------------+---------------------------+ +| | co_firstlineno | number of first line in | +| | | Python source code | ++-----------+-------------------+---------------------------+ +| | co_flags | bitmap of ``CO_*`` flags, | +| | | read more :ref:`here | +| | | `| ++-----------+-------------------+---------------------------+ +| | co_lnotab | encoded mapping of line | +| | | numbers to bytecode | +| | | indices | ++-----------+-------------------+---------------------------+ +| | co_freevars | tuple of names of free | +| | | variables (referenced via | +| | | a function's closure) | ++-----------+-------------------+---------------------------+ +| | co_kwonlyargcount | number of keyword only | +| | | arguments (not including | +| | | \*\* arg) | ++-----------+-------------------+---------------------------+ +| | co_name | name with which this code | +| | | object was defined | ++-----------+-------------------+---------------------------+ +| | co_names | tuple of names of local | +| | | variables | ++-----------+-------------------+---------------------------+ +| | co_nlocals | number of local variables | ++-----------+-------------------+---------------------------+ +| | co_stacksize | virtual machine stack | +| | | space required | ++-----------+-------------------+---------------------------+ +| | co_varnames | tuple of names of | +| | | arguments and local | +| | | variables | ++-----------+-------------------+---------------------------+ +| generator | __name__ | name | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | gi_frame | frame | ++-----------+-------------------+---------------------------+ +| | gi_running | is the generator running? | ++-----------+-------------------+---------------------------+ +| | gi_code | code | ++-----------+-------------------+---------------------------+ +| | gi_yieldfrom | object being iterated by | +| | | ``yield from``, or | +| | | ``None`` | ++-----------+-------------------+---------------------------+ +| coroutine | __name__ | name | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | cr_await | object being awaited on, | +| | | or ``None`` | ++-----------+-------------------+---------------------------+ +| | cr_frame | frame | ++-----------+-------------------+---------------------------+ +| | cr_running | is the coroutine running? | ++-----------+-------------------+---------------------------+ +| | cr_code | code | ++-----------+-------------------+---------------------------+ +| builtin | __doc__ | documentation string | ++-----------+-------------------+---------------------------+ +| | __name__ | original name of this | +| | | function or method | ++-----------+-------------------+---------------------------+ +| | __qualname__ | qualified name | ++-----------+-------------------+---------------------------+ +| | __self__ | instance to which a | +| | | method is bound, or | +| | | ``None`` | ++-----------+-------------------+---------------------------+ .. versionchanged:: 3.5 @@ -1238,6 +1251,10 @@ Code Objects Bit Flags Python code objects have a ``co_flags`` attribute, which is a bitmap of the following flags: +.. data:: CO_OPTIMIZED + + The code object is optimized, using fast locals. + .. data:: CO_NEWLOCALS If set, a new dict will be created for the frame's ``f_locals`` when @@ -1251,6 +1268,10 @@ the following flags: The code object has a variable keyword parameter (``**kwargs``-like). +.. data:: CO_NESTED + + The flag is set when the code object is a nested function. + .. data:: CO_GENERATOR The flag is set when the code object is a generator function, i.e. diff --git a/Lib/inspect.py b/Lib/inspect.py index 9f9fcfef47c160..4a11006746acb4 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -241,18 +241,24 @@ def iscode(object): """Return true if the object is a code object. Code objects provide these attributes: - co_argcount number of arguments (not including * or ** args) - co_code string of raw compiled bytecode - co_consts tuple of constants used in the bytecode - co_filename name of file in which this code object was created - co_firstlineno number of first line in Python source code - co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg - co_lnotab encoded mapping of line numbers to bytecode indices - co_name name with which this code object was defined - co_names tuple of names of local variables - co_nlocals number of local variables - co_stacksize virtual machine stack space required - co_varnames tuple of names of arguments and local variables""" + co_argcount number of arguments (not including *, ** args + or keyword only arguments) + co_code string of raw compiled bytecode + co_cellvars tuple of names of cell variables + co_consts tuple of constants used in the bytecode + co_filename name of file in which this code object was created + co_firstlineno number of first line in Python source code + co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg + | 16=nested | 32=generator | 64=nofree | 128=coroutine + | 256=iterable_coroutine + co_freevars tuple of names of free variables + co_kwonlyargcount number of keyword only arguments (not including ** arg) + co_lnotab encoded mapping of line numbers to bytecode indices + co_name name with which this code object was defined + co_names tuple of names of local variables + co_nlocals number of local variables + co_stacksize virtual machine stack space required + co_varnames tuple of names of arguments and local variables""" return isinstance(object, types.CodeType) def isbuiltin(object): diff --git a/Misc/NEWS b/Misc/NEWS index 49926830dcb3a6..fd3814ca1fa543 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -163,6 +163,8 @@ C API Documentation ------------- +- bpo-26985: Add missing info of code object in inspect documentation. + - bpo-28929: Link the documentation to its source file on GitHub. - bpo-25008: Document smtpd.py as effectively deprecated and add a pointer to From f3972dd1c1c514ed26bb8139b59b649fa7983743 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 12 Apr 2017 20:46:07 -0700 Subject: [PATCH 139/340] [3.5] Remove superfluous comment in urllib.error. (GH-1076) (GH-1102) (cherry picked from commit 6fab78e9027f9ebd6414995580781b480433e595) --- Lib/urllib/error.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Lib/urllib/error.py b/Lib/urllib/error.py index c5b675d16188b8..851515bc307d62 100644 --- a/Lib/urllib/error.py +++ b/Lib/urllib/error.py @@ -16,10 +16,6 @@ __all__ = ['URLError', 'HTTPError', 'ContentTooShortError'] -# do these error classes make sense? -# make sure all of the OSError stuff is overridden. we just want to be -# subtypes. - class URLError(OSError): # URLError is a sub-type of OSError, but it doesn't share any of # the implementation. need to override __init__ and __str__. From c0f4240fac397e1cdd1ee202fc1ce6eb23037d06 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 12 Apr 2017 21:05:25 -0700 Subject: [PATCH 140/340] [3.5] Clarify exception handler scope in contextlib (GH-1104) Moved explicit raise from inside try to try...else. (cherry picked from commit 680e20beee8bbce9f857b8e7795009191f98b0ba) --- Lib/contextlib.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index 4a7bd079a7dbb8..c0188952ad701e 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -75,7 +75,6 @@ def __exit__(self, type, value, traceback): value = type() try: self.gen.throw(type, value, traceback) - raise RuntimeError("generator didn't stop after throw()") except StopIteration as exc: # Suppress StopIteration *unless* it's the same exception that # was passed to throw(). This prevents a StopIteration @@ -101,6 +100,8 @@ def __exit__(self, type, value, traceback): # if sys.exc_info()[1] is not value: raise + else: + raise RuntimeError("generator didn't stop after throw()") def contextmanager(func): From 4d015a40a7b9c3c1b8cfbe81453187d700a43163 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 13 Apr 2017 03:14:53 -0700 Subject: [PATCH 141/340] [3.5] bpo-29692: contextlib.contextmanager may incorrectly unchain RuntimeError (GH-949) (#1107) contextlib._GeneratorContextManager.__exit__ includes a special case to deal with PEP 479 RuntimeErrors created when `StopIteration` is thrown into the context manager body. Previously this check was too permissive, and undid one level of chaining on *all* RuntimeError instances, not just those that wrapped a StopIteration instance. (cherry picked from commit 00c75e9a45ff0366c185e9e8a2e23af5a35481b0) --- Lib/contextlib.py | 12 ++++++------ Lib/test/test_contextlib.py | 23 +++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Lib/contextlib.py b/Lib/contextlib.py index c0188952ad701e..5371a9f3319221 100644 --- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -65,7 +65,7 @@ def __exit__(self, type, value, traceback): try: next(self.gen) except StopIteration: - return + return False else: raise RuntimeError("generator didn't stop") else: @@ -87,7 +87,7 @@ def __exit__(self, type, value, traceback): # Likewise, avoid suppressing if a StopIteration exception # was passed to throw() and later wrapped into a RuntimeError # (see PEP 479). - if exc.__cause__ is value: + if type is StopIteration and exc.__cause__ is value: return False raise except: @@ -98,10 +98,10 @@ def __exit__(self, type, value, traceback): # fixes the impedance mismatch between the throw() protocol # and the __exit__() protocol. # - if sys.exc_info()[1] is not value: - raise - else: - raise RuntimeError("generator didn't stop after throw()") + if sys.exc_info()[1] is value: + return False + raise + raise RuntimeError("generator didn't stop after throw()") def contextmanager(func): diff --git a/Lib/test/test_contextlib.py b/Lib/test/test_contextlib.py index 516403ef655b9e..ad1b6cd787f88a 100644 --- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -119,6 +119,29 @@ def woohoo(): else: self.fail('StopIteration was suppressed') + def test_contextmanager_do_not_unchain_non_stopiteration_exceptions(self): + @contextmanager + def test_issue29692(): + try: + yield + except Exception as exc: + raise RuntimeError('issue29692:Chained') from exc + try: + with test_issue29692(): + raise ZeroDivisionError + except Exception as ex: + self.assertIs(type(ex), RuntimeError) + self.assertEqual(ex.args[0], 'issue29692:Chained') + self.assertIsInstance(ex.__cause__, ZeroDivisionError) + + try: + with test_issue29692(): + raise StopIteration('issue29692:Unchained') + except Exception as ex: + self.assertIs(type(ex), StopIteration) + self.assertEqual(ex.args[0], 'issue29692:Unchained') + self.assertIsNone(ex.__cause__) + def _create_contextmanager_attribs(self): def attribs(**kw): def decorate(func): diff --git a/Misc/NEWS b/Misc/NEWS index fd3814ca1fa543..0caeefdfff45a8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,9 @@ Extension Modules Library ------- +- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in + contextlib.contextmanager. + Patch by Siddharth Velankar. - bpo-29998: Pickling and copying ImportError now preserves name and path attributes. From df9783720e40773e7854d2f4e4cfc93f0a2c08b8 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 13 Apr 2017 16:16:30 +0300 Subject: [PATCH 142/340] bpo-29791: Clarify that flush is keyword-only argument (GH-1093) Reported by Lucio Ricardo Montero Valenzuela. (cherry picked from commit 61b9ac93712df8092a25223cd56fa6528359792b) --- Doc/library/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index ff8c7b83bbddc8..80b53263c8b53f 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1104,7 +1104,7 @@ are always available. They are listed here in alphabetical order. .. function:: print(*objects, sep=' ', end='\\n', file=sys.stdout, flush=False) Print *objects* to the text stream *file*, separated by *sep* and followed - by *end*. *sep*, *end* and *file*, if present, must be given as keyword + by *end*. *sep*, *end*, *file* and *flush*, if present, must be given as keyword arguments. All non-keyword arguments are converted to strings like :func:`str` does and From e2cf9a918439006fb27f67c1939d0370886650e7 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 13 Apr 2017 19:41:26 +0300 Subject: [PATCH 143/340] bpo-30021: Add examples for re.escape(). (#1048) (#1116) And fix the parameter name. (cherry picked from commit 8fc7bc2b7631ee819ee614e47b6f44bacebe1574) --- Doc/library/re.rst | 17 ++++++++++++++--- Doc/tools/susp-ignored.csv | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 6baac6f53d898c..d33fff8ef3217b 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -771,11 +771,22 @@ form. Unmatched groups are replaced with an empty string. -.. function:: escape(string) +.. function:: escape(pattern) - Escape all the characters in pattern except ASCII letters, numbers and ``'_'``. + Escape all the characters in *pattern* except ASCII letters, numbers and ``'_'``. This is useful if you want to match an arbitrary literal string that may - have regular expression metacharacters in it. + have regular expression metacharacters in it. For example:: + + >>> print(re.escape('python.exe')) + python\.exe + + >>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:" + >>> print('[%s]+' % re.escape(legal_chars)) + [abcdefghijklmnopqrstuvwxyz0123456789\!\#\$\%\&\'\*\+\-\.\^_\`\|\~\:]+ + + >>> operators = ['+', '-', '*', '/', '**'] + >>> print('|'.join(map(re.escape, sorted(operators, reverse=True)))) + \/|\-|\+|\*\*|\* .. versionchanged:: 3.3 The ``'_'`` character is no longer escaped. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index dba93bf3a72b3e..c1dcf42a28afa8 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -274,6 +274,8 @@ whatsnew/3.2,,:location,zope9-location = ${zope9:location} whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf whatsnew/changelog,,:gz,": TarFile opened with external fileobj and ""w:gz"" mode didn't" whatsnew/changelog,,::,": Use ""127.0.0.1"" or ""::1"" instead of ""localhost"" as much as" +library/re,,`,!#$%&'*+-.^_`|~: +library/re,,`,\!\#\$\%\&\'\*\+\-\.\^_\`\|\~\: library/tarfile,149,:xz,'x:xz' library/xml.etree.elementtree,290,:sometag,prefix:sometag library/xml.etree.elementtree,301,:fictional," Date: Thu, 13 Apr 2017 16:38:17 -0700 Subject: [PATCH 144/340] [3.5] Fix a typo in Doc/library/functions.rst (GH-1117) (GH-1124) Replace `For object's ... ` with `For objects ...` (cherry picked from commit 873ef20d0007b4b120933473e6252d2309a70102) --- Doc/library/functions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst index 80b53263c8b53f..d6fa35a5ccb98c 100644 --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -604,7 +604,7 @@ are always available. They are listed here in alphabetical order. .. note:: - For object's with custom :meth:`__hash__` methods, note that :func:`hash` + For objects with custom :meth:`__hash__` methods, note that :func:`hash` truncates the return value based on the bit width of the host machine. See :meth:`__hash__` for details. From d7abeb7024b9755c291c29bdc8c4494246e975ad Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 13 Apr 2017 19:26:24 -0700 Subject: [PATCH 145/340] [3.5] bpo-29694: race condition in pathlib mkdir with flags parents=True (GH-1089). (GH-1127) (cherry picked from commit 22a594a0047d7706537ff2ac676cdc0f1dcb329c) --- Lib/pathlib.py | 4 ++-- Lib/test/test_pathlib.py | 30 ++++++++++++++++++++++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Lib/pathlib.py b/Lib/pathlib.py index 16b99cddbc7183..29914b97e7f4f3 100644 --- a/Lib/pathlib.py +++ b/Lib/pathlib.py @@ -1217,8 +1217,8 @@ def mkdir(self, mode=0o777, parents=False, exist_ok=False): except FileNotFoundError: if not parents or self.parent == self: raise - self.parent.mkdir(parents=True) - self._accessor.mkdir(self, mode) + self.parent.mkdir(parents=True, exist_ok=True) + self.mkdir(mode, parents=False, exist_ok=exist_ok) except OSError: # Cannot rely on checking for EEXIST, since the operating system # could give priority to other errors like EACCES or EROFS diff --git a/Lib/test/test_pathlib.py b/Lib/test/test_pathlib.py index 86d3077d5c4458..5e0708ae73b0f8 100644 --- a/Lib/test/test_pathlib.py +++ b/Lib/test/test_pathlib.py @@ -8,6 +8,7 @@ import stat import tempfile import unittest +from unittest import mock from test import support TESTFN = support.TESTFN @@ -1767,6 +1768,35 @@ def test_mkdir_no_parents_file(self): p.mkdir(exist_ok=True) self.assertEqual(cm.exception.errno, errno.EEXIST) + def test_mkdir_concurrent_parent_creation(self): + for pattern_num in range(32): + p = self.cls(BASE, 'dirCPC%d' % pattern_num) + self.assertFalse(p.exists()) + + def my_mkdir(path, mode=0o777): + path = str(path) + # Emulate another process that would create the directory + # just before we try to create it ourselves. We do it + # in all possible pattern combinations, assuming that this + # function is called at most 5 times (dirCPC/dir1/dir2, + # dirCPC/dir1, dirCPC, dirCPC/dir1, dirCPC/dir1/dir2). + if pattern.pop(): + os.mkdir(path, mode) # from another process + concurrently_created.add(path) + os.mkdir(path, mode) # our real call + + pattern = [bool(pattern_num & (1 << n)) for n in range(5)] + concurrently_created = set() + p12 = p / 'dir1' / 'dir2' + try: + with mock.patch("pathlib._normal_accessor.mkdir", my_mkdir): + p12.mkdir(parents=True, exist_ok=False) + except FileExistsError: + self.assertIn(str(p12), concurrently_created) + else: + self.assertNotIn(str(p12), concurrently_created) + self.assertTrue(p.exists()) + @with_symlinks def test_symlink_to(self): P = self.cls(BASE) diff --git a/Misc/NEWS b/Misc/NEWS index 0caeefdfff45a8..c6df1b86097056 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,10 @@ Extension Modules Library ------- + +- bpo-29694: Fixed race condition in pathlib mkdir with flags + parents=True. Patch by Armin Rigo. + - bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in contextlib.contextmanager. Patch by Siddharth Velankar. From 47f24a018f6a9c3ed996d2b83a7ebd0d1f905827 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 14 Apr 2017 13:45:27 +0200 Subject: [PATCH 146/340] Relax test timing (bpo-29861) to avoid sporadic failures (#1120) (#1133) (cherry picked from commit 685cdb9acc3fca04a9897d88b89771ddfd50e772) --- Lib/test/_test_multiprocessing.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index d1ef98dab47332..e41845b404307e 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1990,6 +1990,7 @@ def test_release_task_refs(self): self.pool.map(identity, objs) del objs + time.sleep(DELTA) # let threaded cleanup code run self.assertEqual(set(wr() for wr in refs), {None}) # With a process pool, copies of the objects are returned, check # they were released too. From d960d766cf69152c71aa0fc62fa31af1aa174e1e Mon Sep 17 00:00:00 2001 From: Jack McCracken Date: Fri, 14 Apr 2017 10:45:17 -0400 Subject: [PATCH 147/340] Fix misplaced positional argument in OS X support library (#1135) --- Lib/_osx_support.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/_osx_support.py b/Lib/_osx_support.py index 13fcd8b8d25b3e..03d36c9f600a66 100644 --- a/Lib/_osx_support.py +++ b/Lib/_osx_support.py @@ -210,7 +210,7 @@ def _remove_universal_flags(_config_vars): # Do not alter a config var explicitly overridden by env var if cv in _config_vars and cv not in os.environ: flags = _config_vars[cv] - flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII) + flags = re.sub(r'-arch\s+\w+\s', ' ', flags, flags=re.ASCII) flags = re.sub('-isysroot [^ \t]*', ' ', flags) _save_modified_value(_config_vars, cv, flags) From c40740cf06470a774e98f84537801cd8b7176938 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 14 Apr 2017 18:36:11 -0700 Subject: [PATCH 148/340] [3.5] bpo-29738: Fix memory leak in _get_crl_dp (GH-526) (GH-1143) * Remove conditional on free of `dps`, since `dps` is now allocated for all versions of OpenSSL * Remove call to `x509_check_ca` since it was only used to cache the `crldp` field of the certificate CRL_DIST_POINTS_free is available in all supported versions of OpenSSL (recent 0.9.8+) and LibreSSL. (cherry picked from commit 2849cc34a8db93d448a62d69c462402347b50dcb) --- Modules/_ssl.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 5f7693c2d886f3..9f79d17f6d3f4a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1181,10 +1181,6 @@ _get_crl_dp(X509 *certificate) { int i, j; PyObject *lst, *res = NULL; -#if OPENSSL_VERSION_NUMBER >= 0x10001000L - /* Calls x509v3_cache_extensions and sets up crldp */ - X509_check_ca(certificate); -#endif dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); if (dps == NULL) @@ -1229,9 +1225,7 @@ _get_crl_dp(X509 *certificate) { done: Py_XDECREF(lst); -#if OPENSSL_VERSION_NUMBER < 0x10001000L - sk_DIST_POINT_free(dps); -#endif + CRL_DIST_POINTS_free(dps); return res; } From f40e72dbe60038eae69bc72e207ac47851d96752 Mon Sep 17 00:00:00 2001 From: Michael Seifert Date: Sat, 15 Apr 2017 04:05:00 +0200 Subject: [PATCH 149/340] [3.5] bpo-30059: Include Py_Ellipsis in C API documentation (GH-1018) (GH-1148) --- Doc/c-api/slice.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Doc/c-api/slice.rst b/Doc/c-api/slice.rst index a825164918f446..8b695e065aeffd 100644 --- a/Doc/c-api/slice.rst +++ b/Doc/c-api/slice.rst @@ -56,3 +56,14 @@ Slice Objects .. versionchanged:: 3.2 The parameter type for the *slice* parameter was ``PySliceObject*`` before. + + +Ellipsis Object +--------------- + + +.. c:var:: PyObject *Py_Ellipsis + + The Python ``Ellipsis`` object. This object has no methods. It needs to be + treated just like any other object with respect to reference counts. Like + :c:data:`Py_None` it is a singleton object. From 4f43f87b6246e13e0eefc793a2c5415c915723c3 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Sat, 15 Apr 2017 13:28:08 +0800 Subject: [PATCH 150/340] bpo-30068: add missing iter(self) in _io._IOBase.readlines when hint is present (#1130) (#1151) --- Lib/test/test_io.py | 1 + Misc/NEWS | 8 +++++--- Modules/_io/iobase.c | 25 +++++++++++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index ab24ca110dd929..ff23db5f43699d 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3466,6 +3466,7 @@ def test_io_after_close(self): self.assertRaises(ValueError, f.readinto1, bytearray(1024)) self.assertRaises(ValueError, f.readline) self.assertRaises(ValueError, f.readlines) + self.assertRaises(ValueError, f.readlines, 1) self.assertRaises(ValueError, f.seek, 0) self.assertRaises(ValueError, f.tell) self.assertRaises(ValueError, f.truncate) diff --git a/Misc/NEWS b/Misc/NEWS index c6df1b86097056..d440363ae4c4ba 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,12 +49,14 @@ Extension Modules Library ------- +- bpo-30068: _io._IOBase.readlines will check if it's closed first when + hint is present. + - bpo-29694: Fixed race condition in pathlib mkdir with flags parents=True. Patch by Armin Rigo. -- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in - contextlib.contextmanager. - Patch by Siddharth Velankar. +- bpo-29692: Fixed arbitrary unchaining of RuntimeError exceptions in + contextlib.contextmanager. Patch by Siddharth Velankar. - bpo-29998: Pickling and copying ImportError now preserves name and path attributes. diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 57541a85195045..9c335657710fe9 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -650,7 +650,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) /*[clinic end generated code: output=2f50421677fa3dea input=1961c4a95e96e661]*/ { Py_ssize_t length = 0; - PyObject *result; + PyObject *result, *it = NULL; result = PyList_New(0); if (result == NULL) @@ -664,19 +664,22 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) PyObject *ret = _PyObject_CallMethodId(result, &PyId_extend, "O", self); if (ret == NULL) { - Py_DECREF(result); - return NULL; + goto error; } Py_DECREF(ret); return result; } + it = PyObject_GetIter(self); + if (it == NULL) { + goto error; + } + while (1) { - PyObject *line = PyIter_Next(self); + PyObject *line = PyIter_Next(it); if (line == NULL) { if (PyErr_Occurred()) { - Py_DECREF(result); - return NULL; + goto error; } else break; /* StopIteration raised */ @@ -684,8 +687,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) if (PyList_Append(result, line) < 0) { Py_DECREF(line); - Py_DECREF(result); - return NULL; + goto error; } length += PyObject_Size(line); Py_DECREF(line); @@ -693,7 +695,14 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) if (length > hint) break; } + + Py_DECREF(it); return result; + + error: + Py_XDECREF(it); + Py_DECREF(result); + return NULL; } /*[clinic input] From 49a905958ffc2fcd5d1d1a293ae453d45deeb884 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 16 Apr 2017 12:03:51 +0300 Subject: [PATCH 151/340] [3.5] bpo-29943: Do not replace the function PySlice_GetIndicesEx() with a macro (#1049) if Py_LIMITED_API is not defined. --- Include/sliceobject.h | 2 ++ Misc/NEWS | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Include/sliceobject.h b/Include/sliceobject.h index 36263544607096..579ac073d0f241 100644 --- a/Include/sliceobject.h +++ b/Include/sliceobject.h @@ -45,11 +45,13 @@ PyAPI_FUNC(int) PySlice_GetIndicesEx(PyObject *r, Py_ssize_t length, Py_ssize_t *step, Py_ssize_t *slicelength); #if !defined(Py_LIMITED_API) || (Py_LIMITED_API+0 >= 0x03050400 && Py_LIMITED_API+0 < 0x03060000) || Py_LIMITED_API+0 >= 0x03060100 +#ifdef Py_LIMITED_API #define PySlice_GetIndicesEx(slice, length, start, stop, step, slicelen) ( \ PySlice_Unpack((slice), (start), (stop), (step)) < 0 ? \ ((*(slicelen) = 0), -1) : \ ((*(slicelen) = PySlice_AdjustIndices((length), (start), (stop), *(step))), \ 0)) +#endif PyAPI_FUNC(int) PySlice_Unpack(PyObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step); PyAPI_FUNC(Py_ssize_t) PySlice_AdjustIndices(Py_ssize_t length, diff --git a/Misc/NEWS b/Misc/NEWS index d440363ae4c4ba..146a39c9cf8ae3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -160,8 +160,8 @@ C API ----- - Issue #27867: Function PySlice_GetIndicesEx() is replaced with a macro if - Py_LIMITED_API is not set or set to the value between 0x03050400 - and 0x03060000 (not including) or 0x03060100 or higher. + Py_LIMITED_API is set to the value between 0x03050400 and 0x03060000 (not + including) or 0x03060100 or higher. - Issue #29083: Fixed the declaration of some public API functions. PyArg_VaParse() and PyArg_VaParseTupleAndKeywords() were not available in From e63af29c87b44bb7ada5783cd0ff6ee6d4f9c17c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 19 Apr 2017 22:09:56 +0300 Subject: [PATCH 152/340] [3.5] bpo-30061: Check if PyObject_Size()/PySequence_Size()/PyMapping_Size() (GH-1096) (GH-1180) (#1182) raised an error. (cherry picked from commit bf623ae8843dc30b28c574bec8d29fc14be59d86) (cherry picked from commit 680fea4067537a9b9c79aadd44a3a19e83cd2dbf) --- Lib/test/test_io.py | 16 ++++++++ Misc/NEWS | 5 +++ Modules/_io/iobase.c | 13 +++++-- Modules/_winapi.c | 17 ++++++--- Modules/cjkcodecs/multibytecodec.c | 3 ++ Modules/posixmodule.c | 60 +++++++++++++++++++++--------- Objects/setobject.c | 12 ++++-- 7 files changed, 95 insertions(+), 31 deletions(-) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index ff23db5f43699d..b8937c5a183adf 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -536,6 +536,22 @@ def test_readline(self): with self.open(support.TESTFN, "r") as f: self.assertRaises(TypeError, f.readline, 5.3) + def test_readline_nonsizeable(self): + # Issue #30061 + # Crash when readline() returns an object without __len__ + class R(self.IOBase): + def readline(self): + return None + self.assertRaises((TypeError, StopIteration), next, R()) + + def test_next_nonsizeable(self): + # Issue #30061 + # Crash when __next__() returns an object without __len__ + class R(self.IOBase): + def __next__(self): + return None + self.assertRaises(TypeError, R().readlines, 1) + def test_raw_bytes_io(self): f = self.BytesIO() self.write_ops(f) diff --git a/Misc/NEWS b/Misc/NEWS index 146a39c9cf8ae3..011663daac12a4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,11 @@ Extension Modules Library ------- +- bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when + readline() or __next__() respectively return non-sizeable object. + Fixed possible other errors caused by not checking results of PyObject_Size(), + PySequence_Size(), or PyMapping_Size(). + - bpo-30068: _io._IOBase.readlines will check if it's closed first when hint is present. diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 9c335657710fe9..9acd1461ce2e85 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -625,7 +625,8 @@ iobase_iternext(PyObject *self) if (line == NULL) return NULL; - if (PyObject_Size(line) == 0) { + if (PyObject_Size(line) <= 0) { + /* Error or empty */ Py_DECREF(line); return NULL; } @@ -676,6 +677,7 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) } while (1) { + Py_ssize_t line_length; PyObject *line = PyIter_Next(it); if (line == NULL) { if (PyErr_Occurred()) { @@ -689,11 +691,14 @@ _io__IOBase_readlines_impl(PyObject *self, Py_ssize_t hint) Py_DECREF(line); goto error; } - length += PyObject_Size(line); + line_length = PyObject_Size(line); Py_DECREF(line); - - if (length > hint) + if (line_length < 0) { + goto error; + } + if (line_length > hint - length) break; + length += line_length; } Py_DECREF(it); diff --git a/Modules/_winapi.c b/Modules/_winapi.c index edc6cf4adbb495..cc7b66360df6d4 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -722,17 +722,22 @@ getenvironment(PyObject* environment) return NULL; } - envsize = PyMapping_Length(environment); - keys = PyMapping_Keys(environment); values = PyMapping_Values(environment); if (!keys || !values) goto error; + envsize = PySequence_Fast_GET_SIZE(keys); + if (PySequence_Fast_GET_SIZE(values) != envsize) { + PyErr_SetString(PyExc_RuntimeError, + "environment changed size during iteration"); + goto error; + } + totalsize = 1; /* trailing null character */ for (i = 0; i < envsize; i++) { - PyObject* key = PyList_GET_ITEM(keys, i); - PyObject* value = PyList_GET_ITEM(values, i); + PyObject* key = PySequence_Fast_GET_ITEM(keys, i); + PyObject* value = PySequence_Fast_GET_ITEM(values, i); if (! PyUnicode_Check(key) || ! PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, @@ -760,8 +765,8 @@ getenvironment(PyObject* environment) end = buffer + totalsize; for (i = 0; i < envsize; i++) { - PyObject* key = PyList_GET_ITEM(keys, i); - PyObject* value = PyList_GET_ITEM(values, i); + PyObject* key = PySequence_Fast_GET_ITEM(keys, i); + PyObject* value = PySequence_Fast_GET_ITEM(values, i); if (!PyUnicode_AsUCS4(key, p, end - p, 0)) goto error; p += PyUnicode_GET_LENGTH(key); diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c index f5c842154b9aff..61750edfed99ea 100644 --- a/Modules/cjkcodecs/multibytecodec.c +++ b/Modules/cjkcodecs/multibytecodec.c @@ -1670,6 +1670,9 @@ _multibytecodec_MultibyteStreamWriter_writelines(MultibyteStreamWriterObject *se if (r == -1) return NULL; } + /* PySequence_Length() can fail */ + if (PyErr_Occurred()) + return NULL; Py_RETURN_NONE; } diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 3e446a524e9e93..00da3c086521a4 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6755,7 +6755,7 @@ static PyObject * os_setgroups(PyObject *module, PyObject *groups) /*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/ { - int i, len; + Py_ssize_t i, len; gid_t grouplist[MAX_GROUPS]; if (!PySequence_Check(groups)) { @@ -6763,6 +6763,9 @@ os_setgroups(PyObject *module, PyObject *groups) return NULL; } len = PySequence_Size(groups); + if (len < 0) { + return NULL; + } if (len > MAX_GROUPS) { PyErr_SetString(PyExc_ValueError, "too many groups"); return NULL; @@ -8076,9 +8079,9 @@ os_read_impl(PyObject *module, int fd, Py_ssize_t length) #if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \ || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV) static Py_ssize_t -iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type) +iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, Py_ssize_t cnt, int type) { - int i, j; + Py_ssize_t i, j; Py_ssize_t blen, total = 0; *iov = PyMem_New(struct iovec, cnt); @@ -8155,8 +8158,7 @@ static Py_ssize_t os_readv_impl(PyObject *module, int fd, PyObject *buffers) /*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/ { - int cnt; - Py_ssize_t n; + Py_ssize_t cnt, n; int async_err = 0; struct iovec *iov; Py_buffer *buf; @@ -8168,6 +8170,8 @@ os_readv_impl(PyObject *module, int fd, PyObject *buffers) } cnt = PySequence_Size(buffers); + if (cnt < 0) + return -1; if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0) return -1; @@ -8310,15 +8314,24 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) "sendfile() headers must be a sequence"); return NULL; } else { - Py_ssize_t i = 0; /* Avoid uninitialized warning */ - sf.hdr_cnt = PySequence_Size(headers); - if (sf.hdr_cnt > 0 && - (i = iov_setup(&(sf.headers), &hbuf, - headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0) + Py_ssize_t i = PySequence_Size(headers); + if (i < 0) + return NULL; + if (i > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sendfile() header is too large"); return NULL; + } + if (i > 0) { + sf.hdr_cnt = (int)i; + i = iov_setup(&(sf.headers), &hbuf, + headers, sf.hdr_cnt, PyBUF_SIMPLE); + if (i < 0) + return NULL; #ifdef __APPLE__ - sbytes += i; + sbytes += i; #endif + } } } if (trailers != NULL) { @@ -8327,15 +8340,24 @@ posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict) "sendfile() trailers must be a sequence"); return NULL; } else { - Py_ssize_t i = 0; /* Avoid uninitialized warning */ - sf.trl_cnt = PySequence_Size(trailers); - if (sf.trl_cnt > 0 && - (i = iov_setup(&(sf.trailers), &tbuf, - trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0) + Py_ssize_t i = PySequence_Size(trailers); + if (i < 0) + return NULL; + if (i > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "sendfile() trailer is too large"); return NULL; + } + if (i > 0) { + sf.trl_cnt = (int)i; + i = iov_setup(&(sf.trailers), &tbuf, + trailers, sf.trl_cnt, PyBUF_SIMPLE); + if (i < 0) + return NULL; #ifdef __APPLE__ - sbytes += i; + sbytes += i; #endif + } } } @@ -8605,7 +8627,7 @@ static Py_ssize_t os_writev_impl(PyObject *module, int fd, PyObject *buffers) /*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/ { - int cnt; + Py_ssize_t cnt; Py_ssize_t result; int async_err = 0; struct iovec *iov; @@ -8617,6 +8639,8 @@ os_writev_impl(PyObject *module, int fd, PyObject *buffers) return -1; } cnt = PySequence_Size(buffers); + if (cnt < 0) + return -1; if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) { return -1; diff --git a/Objects/setobject.c b/Objects/setobject.c index 4ef692db332031..3dbdb4ea539306 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -1498,15 +1498,21 @@ set_difference(PySetObject *so, PyObject *other) { PyObject *result; setentry *entry; - Py_ssize_t pos = 0; + Py_ssize_t pos = 0, other_size; - if (!PyAnySet_Check(other) && !PyDict_CheckExact(other)) { + if (PyAnySet_Check(other)) { + other_size = PySet_GET_SIZE(other); + } + else if (PyDict_CheckExact(other)) { + other_size = PyDict_Size(other); + } + else { return set_copy_and_difference(so, other); } /* If len(so) much more than len(other), it's more efficient to simply copy * so and then iterate other looking for common elements. */ - if ((PySet_GET_SIZE(so) >> 2) > PyObject_Size(other)) { + if ((PySet_GET_SIZE(so) >> 2) > other_size) { return set_copy_and_difference(so, other); } From 952a05e4e2cf082b74a1676a2804f1f43a9b7702 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 19 Apr 2017 23:44:43 +0300 Subject: [PATCH 153/340] [3.5] bpo-30070: Fixed leaks and crashes in errors handling in the parser module. (GH-1131). (#1185) (cherry picked from commit a79f4c219531c05fc8f670c1e4bbf12c081935d3) --- Lib/test/test_parser.py | 81 +++++++++++++++++++++++++++++ Misc/NEWS | 2 + Modules/parsermodule.c | 110 ++++++++++++++++++++++++---------------- 3 files changed, 150 insertions(+), 43 deletions(-) diff --git a/Lib/test/test_parser.py b/Lib/test/test_parser.py index ab6577f44d7e15..42ce6b00a3f3aa 100644 --- a/Lib/test/test_parser.py +++ b/Lib/test/test_parser.py @@ -1,4 +1,6 @@ +import copy import parser +import pickle import unittest import sys import operator @@ -386,6 +388,52 @@ def test_junk(self): # not even remotely valid: self.check_bad_tree((1, 2, 3), "") + def test_illegal_terminal(self): + tree = \ + (257, + (269, + (270, + (271, + (277, + (1,))), + (4, ''))), + (4, ''), + (0, '')) + self.check_bad_tree(tree, "too small items in terminal node") + tree = \ + (257, + (269, + (270, + (271, + (277, + (1, b'pass'))), + (4, ''))), + (4, ''), + (0, '')) + self.check_bad_tree(tree, "non-string second item in terminal node") + tree = \ + (257, + (269, + (270, + (271, + (277, + (1, 'pass', '0', 0))), + (4, ''))), + (4, ''), + (0, '')) + self.check_bad_tree(tree, "non-integer third item in terminal node") + tree = \ + (257, + (269, + (270, + (271, + (277, + (1, 'pass', 0, 0))), + (4, ''))), + (4, ''), + (0, '')) + self.check_bad_tree(tree, "too many items in terminal node") + def test_illegal_yield_1(self): # Illegal yield statement: def f(): return 1; yield 1 tree = \ @@ -590,6 +638,24 @@ def test_missing_import_source(self): (4, ''), (0, '')) self.check_bad_tree(tree, "from import fred") + def test_illegal_encoding(self): + # Illegal encoding declaration + tree = \ + (338, + (257, (0, ''))) + self.check_bad_tree(tree, "missed encoding") + tree = \ + (338, + (257, (0, '')), + b'iso-8859-1') + self.check_bad_tree(tree, "non-string encoding") + tree = \ + (338, + (257, (0, '')), + '\udcff') + with self.assertRaises(UnicodeEncodeError): + parser.sequence2st(tree) + class CompileTestCase(unittest.TestCase): @@ -728,6 +794,21 @@ def test_comparisons(self): self.assertRaises(TypeError, operator.lt, st1, 1815) self.assertRaises(TypeError, operator.gt, b'waterloo', st2) + def test_copy_pickle(self): + sts = [ + parser.expr('2 + 3'), + parser.suite('x = 2; y = x + 3'), + parser.expr('list(x**3 for x in range(20))') + ] + for st in sts: + st_copy = copy.copy(st) + self.assertEqual(st_copy.totuple(), st.totuple()) + st_copy = copy.deepcopy(st) + self.assertEqual(st_copy.totuple(), st.totuple()) + for proto in range(pickle.HIGHEST_PROTOCOL+1): + st_copy = pickle.loads(pickle.dumps(st, proto)) + self.assertEqual(st_copy.totuple(), st.totuple()) + check_sizeof = support.check_sizeof @support.cpython_only diff --git a/Misc/NEWS b/Misc/NEWS index 011663daac12a4..d9494c13b3c96b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Extension Modules Library ------- +- bpo-30070: Fixed leaks and crashes in errors handling in the parser module. + - bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when readline() or __next__() respectively return non-sizeable object. Fixed possible other errors caused by not checking results of PyObject_Size(), diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c index 6471b8ee997fcf..fe095e53732abe 100644 --- a/Modules/parsermodule.c +++ b/Modules/parsermodule.c @@ -763,6 +763,9 @@ build_node_children(PyObject *tuple, node *root, int *line_num) Py_ssize_t i; int err; + if (len < 0) { + return NULL; + } for (i = 1; i < len; ++i) { /* elem must always be a sequence, however simple */ PyObject* elem = PySequence_GetItem(tuple, i); @@ -783,7 +786,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num) if (type == -1 && PyErr_Occurred()) { Py_DECREF(temp); Py_DECREF(elem); - return 0; + return NULL; } } Py_DECREF(temp); @@ -795,7 +798,7 @@ build_node_children(PyObject *tuple, node *root, int *line_num) PyErr_SetObject(parser_error, err); Py_XDECREF(err); Py_XDECREF(elem); - return (0); + return NULL; } if (ISTERMINAL(type)) { Py_ssize_t len = PyObject_Size(elem); @@ -804,11 +807,14 @@ build_node_children(PyObject *tuple, node *root, int *line_num) if ((len != 2) && (len != 3)) { err_string("terminal nodes must have 2 or 3 entries"); - return 0; + Py_DECREF(elem); + return NULL; } temp = PySequence_GetItem(elem, 1); - if (temp == NULL) - return 0; + if (temp == NULL) { + Py_DECREF(elem); + return NULL; + } if (!PyUnicode_Check(temp)) { PyErr_Format(parser_error, "second item in terminal node must be a string," @@ -816,46 +822,49 @@ build_node_children(PyObject *tuple, node *root, int *line_num) Py_TYPE(temp)->tp_name); Py_DECREF(temp); Py_DECREF(elem); - return 0; + return NULL; } if (len == 3) { PyObject *o = PySequence_GetItem(elem, 2); - if (o != NULL) { - if (PyLong_Check(o)) { - int num = _PyLong_AsInt(o); - if (num == -1 && PyErr_Occurred()) { - Py_DECREF(o); - Py_DECREF(temp); - Py_DECREF(elem); - return 0; - } - *line_num = num; - } - else { - PyErr_Format(parser_error, - "third item in terminal node must be an" - " integer, found %s", - Py_TYPE(temp)->tp_name); + if (o == NULL) { + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; + } + if (PyLong_Check(o)) { + int num = _PyLong_AsInt(o); + if (num == -1 && PyErr_Occurred()) { Py_DECREF(o); Py_DECREF(temp); Py_DECREF(elem); - return 0; + return NULL; } + *line_num = num; + } + else { + PyErr_Format(parser_error, + "third item in terminal node must be an" + " integer, found %s", + Py_TYPE(temp)->tp_name); Py_DECREF(o); + Py_DECREF(temp); + Py_DECREF(elem); + return NULL; } + Py_DECREF(o); } temp_str = _PyUnicode_AsStringAndSize(temp, &len); if (temp_str == NULL) { Py_DECREF(temp); - Py_XDECREF(elem); - return 0; + Py_DECREF(elem); + return NULL; } strn = (char *)PyObject_MALLOC(len + 1); if (strn == NULL) { Py_DECREF(temp); - Py_XDECREF(elem); + Py_DECREF(elem); PyErr_NoMemory(); - return 0; + return NULL; } (void) memcpy(strn, temp_str, len + 1); Py_DECREF(temp); @@ -865,20 +874,21 @@ build_node_children(PyObject *tuple, node *root, int *line_num) * It has to be one or the other; this is an error. * Raise an exception. */ - PyObject *err = Py_BuildValue("os", elem, "unknown node type."); + PyObject *err = Py_BuildValue("Os", elem, "unknown node type."); PyErr_SetObject(parser_error, err); Py_XDECREF(err); - Py_XDECREF(elem); - return (0); + Py_DECREF(elem); + return NULL; } err = PyNode_AddChild(root, type, strn, *line_num, 0); if (err == E_NOMEM) { - Py_XDECREF(elem); + Py_DECREF(elem); PyObject_FREE(strn); - return (node *) PyErr_NoMemory(); + PyErr_NoMemory(); + return NULL; } if (err == E_OVERFLOW) { - Py_XDECREF(elem); + Py_DECREF(elem); PyObject_FREE(strn); PyErr_SetString(PyExc_ValueError, "unsupported number of child nodes"); @@ -889,14 +899,14 @@ build_node_children(PyObject *tuple, node *root, int *line_num) node* new_child = CHILD(root, i - 1); if (new_child != build_node_children(elem, new_child, line_num)) { - Py_XDECREF(elem); - return (0); + Py_DECREF(elem); + return NULL; } } else if (type == NEWLINE) { /* It's true: we increment the */ ++(*line_num); /* line number *after* the newline! */ } - Py_XDECREF(elem); + Py_DECREF(elem); } return root; } @@ -931,10 +941,23 @@ build_node_tree(PyObject *tuple) if (num == encoding_decl) { encoding = PySequence_GetItem(tuple, 2); + if (encoding == NULL) { + PyErr_SetString(parser_error, "missed encoding"); + return NULL; + } + if (!PyUnicode_Check(encoding)) { + PyErr_Format(parser_error, + "encoding must be a string, found %.200s", + Py_TYPE(encoding)->tp_name); + Py_DECREF(encoding); + return NULL; + } /* tuple isn't borrowed anymore here, need to DECREF */ tuple = PySequence_GetSlice(tuple, 0, 2); - if (tuple == NULL) + if (tuple == NULL) { + Py_DECREF(encoding); return NULL; + } } res = PyNode_New(num); if (res != NULL) { @@ -947,31 +970,33 @@ build_node_tree(PyObject *tuple) const char *temp; temp = _PyUnicode_AsStringAndSize(encoding, &len); if (temp == NULL) { - Py_DECREF(res); + PyNode_Free(res); Py_DECREF(encoding); Py_DECREF(tuple); return NULL; } res->n_str = (char *)PyObject_MALLOC(len + 1); if (res->n_str == NULL) { - Py_DECREF(res); + PyNode_Free(res); Py_DECREF(encoding); Py_DECREF(tuple); PyErr_NoMemory(); return NULL; } (void) memcpy(res->n_str, temp, len + 1); - Py_DECREF(encoding); - Py_DECREF(tuple); } } + if (encoding != NULL) { + Py_DECREF(encoding); + Py_DECREF(tuple); + } } else { /* The tuple is illegal -- if the number is neither TERMINAL nor * NONTERMINAL, we can't use it. Not sure the implementation * allows this condition, but the API doesn't preclude it. */ - PyObject *err = Py_BuildValue("os", tuple, + PyObject *err = Py_BuildValue("Os", tuple, "Illegal component tuple."); PyErr_SetObject(parser_error, err); Py_XDECREF(err); @@ -3433,7 +3458,6 @@ parser__pickler(PyObject *self, PyObject *args) result = Py_BuildValue("O(O)", pickle_constructor, tuple); Py_DECREF(tuple); } - Py_DECREF(empty_dict); Py_DECREF(newargs); } finally: From c97c1914f401359f2a7e6c8e0364e71ad9fb5bc8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 20 Apr 2017 00:51:05 +0300 Subject: [PATCH 154/340] [3.5] bpo-30065: Fixed arguments validation in _posixsubprocess.fork_exec(). (GH-1110) (#1190) (cherry picked from commit 66bffd1) --- Lib/multiprocessing/util.py | 2 +- Lib/subprocess.py | 3 ++- Lib/test/test_capi.py | 6 +++--- Lib/test/test_subprocess.py | 13 ++++++++++- Modules/_posixsubprocess.c | 43 ++++++++++++++++++++----------------- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 1a2c0db40b9cc6..0ce274ceca6057 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -386,7 +386,7 @@ def _close_stdin(): def spawnv_passfds(path, args, passfds): import _posixsubprocess - passfds = sorted(passfds) + passfds = tuple(sorted(map(int, passfds))) errpipe_read, errpipe_write = os.pipe() try: return _posixsubprocess.fork_exec( diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 21655242a47268..281ea8af92257e 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1214,7 +1214,8 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, fds_to_keep.add(errpipe_write) self.pid = _posixsubprocess.fork_exec( args, executable_list, - close_fds, sorted(fds_to_keep), cwd, env_list, + close_fds, tuple(sorted(map(int, fds_to_keep))), + cwd, env_list, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, errpipe_read, errpipe_write, diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 1eadd2249e1729..042e5aaae35064 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -96,7 +96,7 @@ class Z(object): def __len__(self): return 1 self.assertRaises(TypeError, _posixsubprocess.fork_exec, - 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17) + 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) # Issue #15736: overflow in _PySequence_BytesToCharpArray() class Z(object): def __len__(self): @@ -104,7 +104,7 @@ def __len__(self): def __getitem__(self, i): return b'x' self.assertRaises(MemoryError, _posixsubprocess.fork_exec, - 1,Z(),3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17) + 1,Z(),3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) @unittest.skipUnless(_posixsubprocess, '_posixsubprocess required for this test.') def test_subprocess_fork_exec(self): @@ -114,7 +114,7 @@ def __len__(self): # Issue #15738: crash in subprocess_fork_exec() self.assertRaises(TypeError, _posixsubprocess.fork_exec, - Z(),[b'1'],3,[1, 2],5,6,7,8,9,10,11,12,13,14,15,16,17) + Z(),[b'1'],3,(1, 2),5,6,7,8,9,10,11,12,13,14,15,16,17) @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 2dc03ee7001bf3..03a06e051bff2f 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2371,7 +2371,7 @@ def test_fork_exec(self): with self.assertRaises(TypeError): _posixsubprocess.fork_exec( args, exe_list, - True, [], cwd, env_list, + True, (), cwd, env_list, -1, -1, -1, -1, 1, 2, 3, 4, True, True, func) @@ -2383,6 +2383,16 @@ def test_fork_exec(self): def test_fork_exec_sorted_fd_sanity_check(self): # Issue #23564: sanity check the fork_exec() fds_to_keep sanity check. import _posixsubprocess + class BadInt: + first = True + def __init__(self, value): + self.value = value + def __int__(self): + if self.first: + self.first = False + return self.value + raise ValueError + gc_enabled = gc.isenabled() try: gc.enable() @@ -2393,6 +2403,7 @@ def test_fork_exec_sorted_fd_sanity_check(self): (18, 23, 42, 2**63), # Out of range. (5, 4), # Not sorted. (6, 7, 7, 8), # Duplicate. + (BadInt(1), BadInt(2)), ): with self.assertRaises( ValueError, diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c index c0240e2af02f16..48c19538c8488f 100644 --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -112,13 +112,17 @@ _is_fdescfs_mounted_on_dev_fd(void) static int _sanity_check_python_fd_sequence(PyObject *fd_sequence) { - Py_ssize_t seq_idx, seq_len = PySequence_Length(fd_sequence); + Py_ssize_t seq_idx; long prev_fd = -1; - for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) { - PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx); - long iter_fd = PyLong_AsLong(py_fd); + for (seq_idx = 0; seq_idx < PyTuple_GET_SIZE(fd_sequence); ++seq_idx) { + PyObject* py_fd = PyTuple_GET_ITEM(fd_sequence, seq_idx); + long iter_fd; + if (!PyLong_Check(py_fd)) { + return 1; + } + iter_fd = PyLong_AsLong(py_fd); if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { - /* Negative, overflow, not a Long, unsorted, too big for a fd. */ + /* Negative, overflow, unsorted, too big for a fd. */ return 1; } prev_fd = iter_fd; @@ -133,13 +137,12 @@ _is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence) { /* Binary search. */ Py_ssize_t search_min = 0; - Py_ssize_t search_max = PySequence_Length(fd_sequence) - 1; + Py_ssize_t search_max = PyTuple_GET_SIZE(fd_sequence) - 1; if (search_max < 0) return 0; do { long middle = (search_min + search_max) / 2; - long middle_fd = PyLong_AsLong( - PySequence_Fast_GET_ITEM(fd_sequence, middle)); + long middle_fd = PyLong_AsLong(PyTuple_GET_ITEM(fd_sequence, middle)); if (fd == middle_fd) return 1; if (fd > middle_fd) @@ -155,9 +158,9 @@ make_inheritable(PyObject *py_fds_to_keep, int errpipe_write) { Py_ssize_t i, len; - len = PySequence_Length(py_fds_to_keep); + len = PyTuple_GET_SIZE(py_fds_to_keep); for (i = 0; i < len; ++i) { - PyObject* fdobj = PySequence_Fast_GET_ITEM(py_fds_to_keep, i); + PyObject* fdobj = PyTuple_GET_ITEM(py_fds_to_keep, i); long fd = PyLong_AsLong(fdobj); assert(!PyErr_Occurred()); assert(0 <= fd && fd <= INT_MAX); @@ -214,14 +217,13 @@ static void _close_fds_by_brute_force(long start_fd, PyObject *py_fds_to_keep) { long end_fd = safe_get_max_fd(); - Py_ssize_t num_fds_to_keep = PySequence_Length(py_fds_to_keep); + Py_ssize_t num_fds_to_keep = PyTuple_GET_SIZE(py_fds_to_keep); Py_ssize_t keep_seq_idx; int fd_num; /* As py_fds_to_keep is sorted we can loop through the list closing * fds inbetween any in the keep list falling within our range. */ for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) { - PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep, - keep_seq_idx); + PyObject* py_keep_fd = PyTuple_GET_ITEM(py_fds_to_keep, keep_seq_idx); int keep_fd = PyLong_AsLong(py_keep_fd); if (keep_fd < start_fd) continue; @@ -307,7 +309,7 @@ _close_open_fds_safe(int start_fd, PyObject* py_fds_to_keep) /* Close all open file descriptors from start_fd and higher. - * Do not close any in the sorted py_fds_to_keep list. + * Do not close any in the sorted py_fds_to_keep tuple. * * This function violates the strict use of async signal safe functions. :( * It calls opendir(), readdir() and closedir(). Of these, the one most @@ -563,8 +565,9 @@ subprocess_fork_exec(PyObject* self, PyObject *args) #endif if (!PyArg_ParseTuple( - args, "OOpOOOiiiiiiiiiiO:fork_exec", - &process_args, &executable_list, &close_fds, &py_fds_to_keep, + args, "OOpO!OOiiiiiiiiiiO:fork_exec", + &process_args, &executable_list, + &close_fds, &PyTuple_Type, &py_fds_to_keep, &cwd_obj, &env_list, &p2cread, &p2cwrite, &c2pread, &c2pwrite, &errread, &errwrite, &errpipe_read, &errpipe_write, @@ -575,10 +578,6 @@ subprocess_fork_exec(PyObject* self, PyObject *args) PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3"); return NULL; } - if (PySequence_Length(py_fds_to_keep) < 0) { - PyErr_SetString(PyExc_ValueError, "cannot get length of fds_to_keep"); - return NULL; - } if (_sanity_check_python_fd_sequence(py_fds_to_keep)) { PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep"); return NULL; @@ -632,6 +631,10 @@ subprocess_fork_exec(PyObject* self, PyObject *args) goto cleanup; for (arg_num = 0; arg_num < num_args; ++arg_num) { PyObject *borrowed_arg, *converted_arg; + if (PySequence_Fast_GET_SIZE(fast_args) != num_args) { + PyErr_SetString(PyExc_RuntimeError, "args changed during iteration"); + goto cleanup; + } borrowed_arg = PySequence_Fast_GET_ITEM(fast_args, arg_num); if (PyUnicode_FSConverter(borrowed_arg, &converted_arg) == 0) goto cleanup; From 7e56fe35efe3aef0b9aac989255c4f13dfc01b09 Mon Sep 17 00:00:00 2001 From: cocoatomo Date: Thu, 20 Apr 2017 12:56:05 +0900 Subject: [PATCH 155/340] bpo-19225: Remove duplicated description for standard warning categories (GH-1068) --- Doc/c-api/exceptions.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index cf2385f3deb3c7..b8af52062b7226 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -291,16 +291,11 @@ an error value). is the function calling :c:func:`PyErr_WarnEx`, 2 is the function above that, and so forth. - Warning categories must be subclasses of :c:data:`Warning`; the default warning - category is :c:data:`RuntimeWarning`. The standard Python warning categories are - available as global variables whose names are ``PyExc_`` followed by the Python - exception name. These have the type :c:type:`PyObject\*`; they are all class - objects. Their names are :c:data:`PyExc_Warning`, :c:data:`PyExc_UserWarning`, - :c:data:`PyExc_UnicodeWarning`, :c:data:`PyExc_DeprecationWarning`, - :c:data:`PyExc_SyntaxWarning`, :c:data:`PyExc_RuntimeWarning`, and - :c:data:`PyExc_FutureWarning`. :c:data:`PyExc_Warning` is a subclass of - :c:data:`PyExc_Exception`; the other warning categories are subclasses of - :c:data:`PyExc_Warning`. + Warning categories must be subclasses of :c:data:`PyExc_Warning`; + :c:data:`PyExc_Warning` is a subclass of :c:data:`PyExc_Exception`; + the default warning category is :c:data:`PyExc_RuntimeWarning`. The standard + Python warning categories are available as global variables whose names are + enumerated at :ref:`standarwarningcategories`. For information about warning control, see the documentation for the :mod:`warnings` module and the :option:`-W` option in the command line @@ -942,8 +937,10 @@ Notes: Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. -Standard Warnings -================= +.. _standarwarningcategories: + +Standard Warning Categories +=========================== All standard Python warning categories are available as global variables whose names are ``PyExc_`` followed by the Python exception name. These have the type From 6fb0f801d73b1e2794888772d016d978eccf52a6 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 20 Apr 2017 07:37:18 +0300 Subject: [PATCH 156/340] bpo-30078: Add an example of passing a path to unittest (GH-1178) (cherry picked from commit f7e62cf8adfb8ab6a6a870903defe8ff218a0383) --- Lib/unittest/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/unittest/main.py b/Lib/unittest/main.py index 09fefe11649bd3..807604f08dfd14 100644 --- a/Lib/unittest/main.py +++ b/Lib/unittest/main.py @@ -14,6 +14,7 @@ %(prog)s test_module - run tests from test_module %(prog)s module.TestClass - run tests from module.TestClass %(prog)s module.Class.test_method - run specified test method + %(prog)s path/to/test_file.py - run tests from test_file.py """ MODULE_EXAMPLES = """\ From ad2d47d95165a011f411a8afbb3a87513e269775 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 20 Apr 2017 07:40:05 +0300 Subject: [PATCH 157/340] Remove redundant comma in argparse HOWTO (GH-1141) Reported by Sean Canavan on docs@p.o. (cherry picked from commit 8526fb74edf5ac9ca175b7cdcb0d82bb8780d2cf) --- Doc/howto/argparse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/argparse.rst b/Doc/howto/argparse.rst index 3b79b92082a70a..fac1a3573b98a0 100644 --- a/Doc/howto/argparse.rst +++ b/Doc/howto/argparse.rst @@ -221,7 +221,7 @@ before proceeding. Introducing Optional arguments ============================== -So far we, have been playing with positional arguments. Let us +So far we have been playing with positional arguments. Let us have a look on how to add optional ones:: import argparse From 60d27f42a07d0b9d4a2c3fb160cac1683e91f196 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 20 Apr 2017 07:12:50 -0700 Subject: [PATCH 158/340] [3.5] bpo-30109: Fix reindent.py (GH-1207) (GH-1209) Skip the file if it has bad encoding. (cherry picked from commit 58f3c9dc8f5626abe09ac9738c34f6ba99ce2972) --- Lib/test/test_tools/test_reindent.py | 7 +++++++ Tools/scripts/reindent.py | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_tools/test_reindent.py b/Lib/test/test_tools/test_reindent.py index d7c20e1e5c7206..34df0c5d511904 100644 --- a/Lib/test/test_tools/test_reindent.py +++ b/Lib/test/test_tools/test_reindent.py @@ -7,6 +7,7 @@ import os import unittest from test.support.script_helper import assert_python_ok +from test.support import findfile from test.test_tools import scriptsdir, skip_if_missing @@ -23,6 +24,12 @@ def test_help(self): self.assertEqual(out, b'') self.assertGreater(err, b'') + def test_reindent_file_with_bad_encoding(self): + bad_coding_path = findfile('bad_coding.py') + rc, out, err = assert_python_ok(self.script, '-r', bad_coding_path) + self.assertEqual(out, b'') + self.assertNotEqual(err, b'') + if __name__ == '__main__': unittest.main() diff --git a/Tools/scripts/reindent.py b/Tools/scripts/reindent.py index 18424dea1437ac..f6dadaac5a5206 100755 --- a/Tools/scripts/reindent.py +++ b/Tools/scripts/reindent.py @@ -118,7 +118,11 @@ def check(file): if verbose: print("checking", file, "...", end=' ') with open(file, 'rb') as f: - encoding, _ = tokenize.detect_encoding(f.readline) + try: + encoding, _ = tokenize.detect_encoding(f.readline) + except SyntaxError as se: + errprint("%s: SyntaxError: %s" % (file, str(se))) + return try: with open(file, encoding=encoding) as f: r = Reindenter(f) From ed5e0652cad5ae13f33777e822ff0f1aed3942f6 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 20 Apr 2017 20:56:03 -0700 Subject: [PATCH 159/340] [3.5] Add missing .gitignore entries for VS2015 IntelliSense DB (GH-1223) (#1226) (cherry picked from commit 8e675286a92f33837cfffac5914b5175dac5d573) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d267d15c74db40..b324b920984265 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,8 @@ PCbuild/*.suo PCbuild/*.*sdf PCbuild/*-pgi PCbuild/*-pgo +PCbuild/*.VC.db +PCbuild/*.VC.opendb PCbuild/.vs/ PCbuild/amd64/ PCbuild/obj/ From 17db4b99b4d300a9b024ba0efdaa46d05d4f4cd3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 21 Apr 2017 10:55:54 +0300 Subject: [PATCH 160/340] [3.5] bpo-29802: Fix the cleaning up issue in PyUnicode_FSDecoder(). (GH-1217) (#1219) (cherry picked from commit 7a113a0) --- Objects/unicodeobject.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d7c9a34c39451b..d037d80b3d222e 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3654,6 +3654,7 @@ PyUnicode_FSDecoder(PyObject* arg, void* addr) PyObject *output = NULL; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); + *(PyObject**)addr = NULL; return 1; } if (PyUnicode_Check(arg)) { From 503d74a60aa9290cf8d174eab95fdfdea1f2b284 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 21 Apr 2017 19:58:01 -0700 Subject: [PATCH 161/340] bpo-30098: Clarify that run_coroutine_threadsafe expects asyncio.Future (GH-1170) (#1246) (cherry picked from commit ae5b3260dd459845aad8a30491b76d471577785d) --- Lib/asyncio/tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 7b3bdb21865a49..b6bd53cef1aa41 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -565,7 +565,8 @@ def ensure_future(coro_or_future, *, loop=None): elif compat.PY35 and inspect.isawaitable(coro_or_future): return ensure_future(_wrap_awaitable(coro_or_future), loop=loop) else: - raise TypeError('A Future, a coroutine or an awaitable is required') + raise TypeError('An asyncio.Future, a coroutine or an awaitable is ' + 'required') @coroutine From 7badde2bbb93e39ee917e22cd086e81eed076162 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Sat, 22 Apr 2017 19:49:40 +0800 Subject: [PATCH 162/340] [3.5] Fix trailing colon and newline in test.rst (GH-1250) (#1255) (cherry picked from commit 7fae81e1672d0b4110d31ea6a765b54f63a2e54b) --- Doc/library/test.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/test.rst b/Doc/library/test.rst index 59577f0fe8969a..2777128bd82960 100644 --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -570,7 +570,8 @@ The :mod:`test.support` module defines the following functions: def load_tests(*args): return load_package_tests(os.path.dirname(__file__), *args) -.. function:: detect_api_mismatch(ref_api, other_api, *, ignore=()): + +.. function:: detect_api_mismatch(ref_api, other_api, *, ignore=()) Returns the set of attributes, functions or methods of *ref_api* not found on *other_api*, except for a defined list of items to be From c358536fd5e40e8f29ee4f086588a82fccb25a09 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 23 Apr 2017 08:50:20 +0300 Subject: [PATCH 163/340] [3.5] bpo-15718: Document the upper bound constrain on the __len__ return value. (GH-1256) (#1260) (cherry picked from commit 85157cd) --- Doc/reference/datamodel.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index cd28c147b27992..0d108d727e7a19 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1887,6 +1887,14 @@ through the container; for mappings, :meth:`__iter__` should be the same as :meth:`__bool__` method and whose :meth:`__len__` method returns zero is considered to be false in a Boolean context. + .. impl-detail:: + + In CPython, the length is required to be at most :attr:`sys.maxsize`. + If the length is larger than :attr:`!sys.maxsize` some features (such as + :func:`len`) may raise :exc:`OverflowError`. To prevent raising + :exc:`!OverflowError` by truth value testing, an object must define a + :meth:`__bool__` method. + .. method:: object.__length_hint__(self) @@ -1897,6 +1905,7 @@ through the container; for mappings, :meth:`__iter__` should be the same as .. versionadded:: 3.4 + .. note:: Slicing is done exclusively with the following three methods. A call like :: From d51d093b9bbca108f59bad0f1730c48ebf5b2e14 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 23 Apr 2017 21:02:30 -0700 Subject: [PATCH 164/340] [3.5] bpo-29751: Improve PyLong_FromString documentation (GH-915) (#1267) (cherry picked from commit 26896f2832324dde85cdd63d525571ca669f6f0b) --- Doc/c-api/long.rst | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 68f6a8ec49ee7b..78e555cc891873 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -85,13 +85,12 @@ All integers are implemented as "long" integer objects of arbitrary size. Return a new :c:type:`PyLongObject` based on the string value in *str*, which is interpreted according to the radix in *base*. If *pend* is non-*NULL*, *\*pend* will point to the first character in *str* which follows the - representation of the number. If *base* is ``0``, the radix will be - determined based on the leading characters of *str*: if *str* starts with - ``'0x'`` or ``'0X'``, radix 16 will be used; if *str* starts with ``'0o'`` or - ``'0O'``, radix 8 will be used; if *str* starts with ``'0b'`` or ``'0B'``, - radix 2 will be used; otherwise radix 10 will be used. If *base* is not - ``0``, it must be between ``2`` and ``36``, inclusive. Leading spaces are - ignored. If there are no digits, :exc:`ValueError` will be raised. + representation of the number. If *base* is ``0``, *str* is interpreted using + the :ref:`integers` definition; in this case, leading zeros in a + non-zero decimal number raises a :exc:`ValueError`. If *base* is not ``0``, + it must be between ``2`` and ``36``, inclusive. Leading spaces and single + underscores after a base specifier and between digits are ignored. If there + are no digits, :exc:`ValueError` will be raised. .. c:function:: PyObject* PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) From c7b8367076dc7771dabcb9491bd98218c788d489 Mon Sep 17 00:00:00 2001 From: Louie Lu Date: Wed, 26 Apr 2017 16:47:03 +0800 Subject: [PATCH 165/340] bpo-28698: Fix c_wchar_p doc example (GH-1160) (cherry picked from commit 0d637e236d7099f7b724026c8cb7bd83d8e12e6b) --- Doc/library/ctypes.rst | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index b25fbbb1621f4a..3536b32139e71b 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -284,7 +284,7 @@ the correct type and value:: >>> c_int() c_long(0) >>> c_wchar_p("Hello, World") - c_wchar_p('Hello, World') + c_wchar_p(140018365411392) >>> c_ushort(-3) c_ushort(65533) >>> @@ -309,11 +309,15 @@ bytes objects are immutable):: >>> s = "Hello, World" >>> c_s = c_wchar_p(s) >>> print(c_s) - c_wchar_p('Hello, World') + c_wchar_p(139966785747344) + >>> print(c_s.value) + Hello World >>> c_s.value = "Hi, there" - >>> print(c_s) - c_wchar_p('Hi, there') - >>> print(s) # first object is unchanged + >>> print(c_s) # the memory location has changed + c_wchar_p(139966783348904) + >>> print(c_s.value) + Hi, there + >>> print(s) # first object is unchanged Hello, World >>> From 271a289a03ad10c91c5326bde3020f1cdf6a1fff Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Wed, 26 Apr 2017 17:24:35 +0300 Subject: [PATCH 166/340] bpo-29974: Improve typing.TYPE_CHECKING example (GH-982) * Fix PEP 8 (SomeType instead of some_type) * Add a function parameter annotation * Explain, using wording from PEP 484 and PEP 526, why one annotation is in quotes and another is not. Suggested by Ivan Levkevskyi. (cherry picked from commit 87c07fe9d908d0a2143fcc8369255c6ff3241503) --- Doc/library/typing.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 93ea4f9422997a..2ca3bcd5a2cea7 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -963,5 +963,10 @@ The module defines the following classes, functions and decorators: if TYPE_CHECKING: import expensive_mod - def fun(): - local_var: expensive_mod.some_type = other_fun() + def fun(arg: 'expensive_mod.SomeType') -> None: + local_var: expensive_mod.AnotherType = other_fun() + + Note that the first type annotation must be enclosed in quotes, making it a + "forward reference", to hide the ``expensive_mod`` reference from the + interpreter runtime. Type annotations for local variables are not + evaluated, so the second annotation does not need to be enclosed in quotes. From 9a626ec4e58c0bca1b4f71154e9e1da7e6d7e4a7 Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 27 Apr 2017 01:55:21 +0900 Subject: [PATCH 167/340] [3.5] bpo-30142: Remove "callable" from the 2to3fixer documentation. (GH-1304) --- Doc/library/2to3.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Doc/library/2to3.rst b/Doc/library/2to3.rst index ace1bfaf8cb9d6..4c9a528d42e703 100644 --- a/Doc/library/2to3.rst +++ b/Doc/library/2to3.rst @@ -199,13 +199,6 @@ and off individually. They are described here in more detail. because the :class:`memoryview` API is similar but not exactly the same as that of :class:`buffer`. -.. 2to3fixer:: callable - - Converts ``callable(x)`` to ``isinstance(x, collections.Callable)``, adding - an import to :mod:`collections` if needed. Note ``callable(x)`` has returned - in Python 3.2, so if you do not intend to support Python 3.1, you can disable - this fixer. - .. 2to3fixer:: dict Fixes dictionary iteration methods. :meth:`dict.iteritems` is converted to From c4dfe2537fee970dc1bf3eb4fc2a3e007b36531c Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 26 Apr 2017 22:19:09 -0700 Subject: [PATCH 168/340] [3.5] bpo-30182: Use the correct name for ISO in Unicode HOWTO. (GH-1312) (GH-1314) (cherry picked from commit 6fde770e4e940c19cd62de0b6aeb77840690843e) --- Doc/howto/unicode.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/unicode.rst b/Doc/howto/unicode.rst index a48ae1f5faba7e..9649b9c609c255 100644 --- a/Doc/howto/unicode.rst +++ b/Doc/howto/unicode.rst @@ -43,9 +43,9 @@ hold values ranging from 0 to 255. ASCII codes only went up to 127, so some machines assigned values between 128 and 255 to accented characters. Different machines had different codes, however, which led to problems exchanging files. Eventually various commonly used sets of values for the 128--255 range emerged. -Some were true standards, defined by the International Standards Organization, -and some were *de facto* conventions that were invented by one company or -another and managed to catch on. +Some were true standards, defined by the International Organization for +Standardization, and some were *de facto* conventions that were invented by one +company or another and managed to catch on. 255 characters aren't very many. For example, you can't fit both the accented characters used in Western Europe and the Cyrillic alphabet used for Russian From 0eda2d43a7d5b262c979b944592999015a822395 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 27 Apr 2017 21:32:09 +0200 Subject: [PATCH 169/340] bpo-30175: Skip client cert tests of test_imaplib (#1320) (#1324) * bpo-30175: Skip client cert tests of test_imaplib The IMAP server cyrus.andrew.cmu.edu doesn't accept our randomly generated client x509 certificate anymore. * bpo-30188: Catch EOFError in NetworkedNNTPTests test_nntplib fails randomly with EOFError in NetworkedNNTPTests.setUpClass(). Catch EOFError to skip tests in that case. (cherry picked from commit 5bccca58b9b2b3a925b16750bedbd907695ea8d7) --- Lib/test/test_imaplib.py | 6 ++++++ Lib/test/test_nntplib.py | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index a29b40ac235b95..7a821f3e973e4d 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -917,11 +917,17 @@ def test_logincapa(self): _server = self.imap_class(self.host, self.port) self.check_logincapa(_server) + @unittest.skipIf(True, + "bpo-30175: FIXME: cyrus.andrew.cmu.edu doesn't accept " + "our randomly generated client x509 certificate anymore") def test_logincapa_with_client_certfile(self): with transient_internet(self.host): _server = self.imap_class(self.host, self.port, certfile=CERTFILE) self.check_logincapa(_server) + @unittest.skipIf(True, + "bpo-30175: FIXME: cyrus.andrew.cmu.edu doesn't accept " + "our randomly generated client x509 certificate anymore") def test_logincapa_with_client_ssl_context(self): with transient_internet(self.host): _server = self.imap_class( diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 66ef930a545deb..22fb45a5e702fe 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -286,7 +286,12 @@ class NetworkedNNTPTests(NetworkedNNTPTestsMixin, unittest.TestCase): def setUpClass(cls): support.requires("network") with support.transient_internet(cls.NNTP_HOST): - cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT, usenetrc=False) + try: + cls.server = cls.NNTP_CLASS(cls.NNTP_HOST, timeout=TIMEOUT, + usenetrc=False) + except EOFError: + raise unittest.SkipTest("%s got EOF error on connecting " + "to %r" % (cls, cls.NNTP_HOST)) @classmethod def tearDownClass(cls): From d855e53eabca0e8b2b39d25670c37bbdb4ab2e4c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 28 Apr 2017 04:27:11 +0200 Subject: [PATCH 170/340] bpo-30131: test_logging now joins queue threads (#1298) (#1318) QueueListenerTest of test_logging now closes the multiprocessing Queue and joins its thread to prevent leaking dangling threads to following tests. Add also @support.reap_threads to detect earlier if a test leaks threads (and try to "cleanup" these threads). (cherry picked from commit 8ca2f2faefa8dba323a2e4c4b86efb633d7a53cf) --- Lib/test/test_logging.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 1c850456b14d49..dd7100c6161901 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -3067,6 +3067,7 @@ def setup_and_log(log_queue, ident): handler.close() @patch.object(logging.handlers.QueueListener, 'handle') + @support.reap_threads def test_handle_called_with_queue_queue(self, mock_handle): for i in range(self.repeat): log_queue = queue.Queue() @@ -3076,10 +3077,13 @@ def test_handle_called_with_queue_queue(self, mock_handle): @support.requires_multiprocessing_queue @patch.object(logging.handlers.QueueListener, 'handle') + @support.reap_threads def test_handle_called_with_mp_queue(self, mock_handle): for i in range(self.repeat): log_queue = multiprocessing.Queue() self.setup_and_log(log_queue, '%s_%s' % (self.id(), i)) + log_queue.close() + log_queue.join_thread() self.assertEqual(mock_handle.call_count, 5 * self.repeat, 'correct number of handled log messages') @@ -3092,6 +3096,7 @@ def get_all_from_queue(log_queue): return [] @support.requires_multiprocessing_queue + @support.reap_threads def test_no_messages_in_queue_after_stop(self): """ Five messages are logged then the QueueListener is stopped. This @@ -3104,6 +3109,9 @@ def test_no_messages_in_queue_after_stop(self): self.setup_and_log(queue, '%s_%s' %(self.id(), i)) # time.sleep(1) items = list(self.get_all_from_queue(queue)) + queue.close() + queue.join_thread() + expected = [[], [logging.handlers.QueueListener._sentinel]] self.assertIn(items, expected, 'Found unexpected messages in queue: %s' % ( From 98c7a9e662b49029ff051b6699ddc0f542663c96 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 28 Apr 2017 16:59:44 +0200 Subject: [PATCH 171/340] [3.5] bpo-30107: don't dump core on expected test_io crash (#1235) (#1344) * bpo-30107: Make SuppressCrashReport quiet on macOS (#1279) (#1335) On macOS, SuppressCrashReport now redirects /usr/bin/defaults command stderr into a pipe to not pollute stderr. It fixes a test_io.test_daemon_threads_shutdown_stderr_deadlock() failure when the CrashReporter domain doesn't exists. Message logged into stderr: 2017-04-24 16:57:21.432 defaults[41046:2462851] The domain/default pair of (com.apple.CrashReporter, DialogType) does not exist (cherry picked from commit d819ad9832292d854e9710493ecdf959b69802e3) * bpo-30107: don't dump core on expected test_io crash (#1235) test_io has two unit tests which trigger a deadlock: * test_daemon_threads_shutdown_stdout_deadlock() * test_daemon_threads_shutdown_stderr_deadlock() These tests call Py_FatalError() if the expected bug is triggered which calls abort(). Use test.support.SuppressCrashReport to prevent the creation on a core dump, to fix the warning: Warning -- files was modified by test_io Before: [] After: ['python.core'] --- Lib/test/support/__init__.py | 13 +++++++++---- Lib/test/test_io.py | 5 +++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index d0d126a3a033a5..a5aba3114370ee 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2337,6 +2337,7 @@ def __enter__(self): (0, self.old_value[1])) except (ValueError, OSError): pass + if sys.platform == 'darwin': # Check if the 'Crash Reporter' on OSX was configured # in 'Developer' mode and warn that it will get triggered @@ -2344,10 +2345,14 @@ def __enter__(self): # # This assumes that this context manager is used in tests # that might trigger the next manager. - value = subprocess.Popen(['/usr/bin/defaults', 'read', - 'com.apple.CrashReporter', 'DialogType'], - stdout=subprocess.PIPE).communicate()[0] - if value.strip() == b'developer': + cmd = ['/usr/bin/defaults', 'read', + 'com.apple.CrashReporter', 'DialogType'] + proc = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + with proc: + stdout = proc.communicate()[0] + if stdout.strip() == b'developer': print("this test triggers the Crash Reporter, " "that is intentional", end='', flush=True) diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index b8937c5a183adf..8b4892b2e56b87 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -3688,6 +3688,7 @@ def check_daemon_threads_shutdown_deadlock(self, stream_name): import sys import time import threading + from test.support import SuppressCrashReport file = sys.{stream_name} @@ -3696,6 +3697,10 @@ def run(): file.write('.') file.flush() + crash = SuppressCrashReport() + crash.__enter__() + # don't call __exit__(): the crash occurs at Python shutdown + thread = threading.Thread(target=run) thread.daemon = True thread.start() From 910ba937e90ffe3aa154a5b27dc7e2c3d3c88d1f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 28 Apr 2017 20:05:53 +0300 Subject: [PATCH 172/340] [3.5] bpo-30197: Enhance functions swap_attr() and swap_item() in test.support. (#1341) (#1346) They now work when delete replaced attribute or item inside the with statement. The old value of the attribute or item (or None if it doesn't exist) now will be assigned to the target of the "as" clause, if there is one. (cherry picked from commit d1a1def7bf221b04dcf3fc3a67aa19aa2f622f83) --- Lib/test/support/__init__.py | 16 ++++++++++++---- Lib/test/test_support.py | 29 +++++++++++++++++++++++------ Lib/test/test_tempfile.py | 5 ++--- Misc/NEWS | 6 ++++++ 4 files changed, 43 insertions(+), 13 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a5aba3114370ee..a9f8fd5b3d7449 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2073,12 +2073,15 @@ def swap_attr(obj, attr, new_val): restoring the old value at the end of the block. If `attr` doesn't exist on `obj`, it will be created and then deleted at the end of the block. + + The old value (or None if it doesn't exist) will be assigned to the + target of the "as" clause, if there is one. """ if hasattr(obj, attr): real_val = getattr(obj, attr) setattr(obj, attr, new_val) try: - yield + yield real_val finally: setattr(obj, attr, real_val) else: @@ -2086,7 +2089,8 @@ def swap_attr(obj, attr, new_val): try: yield finally: - delattr(obj, attr) + if hasattr(obj, attr): + delattr(obj, attr) @contextlib.contextmanager def swap_item(obj, item, new_val): @@ -2100,12 +2104,15 @@ def swap_item(obj, item, new_val): restoring the old value at the end of the block. If `item` doesn't exist on `obj`, it will be created and then deleted at the end of the block. + + The old value (or None if it doesn't exist) will be assigned to the + target of the "as" clause, if there is one. """ if item in obj: real_val = obj[item] obj[item] = new_val try: - yield + yield real_val finally: obj[item] = real_val else: @@ -2113,7 +2120,8 @@ def swap_item(obj, item, new_val): try: yield finally: - del obj[item] + if item in obj: + del obj[item] def strip_python_stderr(stderr): """Strip the stderr of a Python process from potential debug output diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py index 5e0f990e400045..70137e1a0be223 100644 --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -283,17 +283,34 @@ def test_python_is_optimized(self): def test_swap_attr(self): class Obj: - x = 1 + pass obj = Obj() - with support.swap_attr(obj, "x", 5): + obj.x = 1 + with support.swap_attr(obj, "x", 5) as x: self.assertEqual(obj.x, 5) + self.assertEqual(x, 1) self.assertEqual(obj.x, 1) + with support.swap_attr(obj, "y", 5) as y: + self.assertEqual(obj.y, 5) + self.assertIsNone(y) + self.assertFalse(hasattr(obj, 'y')) + with support.swap_attr(obj, "y", 5): + del obj.y + self.assertFalse(hasattr(obj, 'y')) def test_swap_item(self): - D = {"item":1} - with support.swap_item(D, "item", 5): - self.assertEqual(D["item"], 5) - self.assertEqual(D["item"], 1) + D = {"x":1} + with support.swap_item(D, "x", 5) as x: + self.assertEqual(D["x"], 5) + self.assertEqual(x, 1) + self.assertEqual(D["x"], 1) + with support.swap_item(D, "y", 5) as y: + self.assertEqual(D["y"], 5) + self.assertIsNone(y) + self.assertNotIn("y", D) + with support.swap_item(D, "y", 5): + del D["y"] + self.assertNotIn("y", D) class RefClass: attribute1 = None diff --git a/Lib/test/test_tempfile.py b/Lib/test/test_tempfile.py index 51df1ecd7d18e6..d0cf04b0cb67ca 100644 --- a/Lib/test/test_tempfile.py +++ b/Lib/test/test_tempfile.py @@ -273,13 +273,12 @@ def raise_OSError(*args, **kwargs): tempfile._get_default_tempdir() self.assertEqual(os.listdir(our_temp_directory), []) - open = io.open def bad_writer(*args, **kwargs): - fp = open(*args, **kwargs) + fp = orig_open(*args, **kwargs) fp.write = raise_OSError return fp - with support.swap_attr(io, "open", bad_writer): + with support.swap_attr(io, "open", bad_writer) as orig_open: # test again with failing write() with self.assertRaises(FileNotFoundError): tempfile._get_default_tempdir() diff --git a/Misc/NEWS b/Misc/NEWS index d9494c13b3c96b..4c90aa83dfb0da 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -199,6 +199,12 @@ Build Tests ----- +- bpo-30197: Enhanced functions swap_attr() and swap_item() in the + test.support module. They now work when delete replaced attribute or item + inside the with statement. The old value of the attribute or item (or None + if it doesn't exist) now will be assigned to the target of the "as" clause, + if there is one. + - Issue #29571: to match the behaviour of the ``re.LOCALE`` flag, test_re.test_locale_flag now uses ``locale.getpreferredencoding(False)`` to determine the candidate encoding for the test regex (allowing it to correctly From 52630ae17aa5bd8bffdb430b6515d07ffbaabc9e Mon Sep 17 00:00:00 2001 From: csabella Date: Sat, 29 Apr 2017 20:43:11 -0400 Subject: [PATCH 173/340] [3.5] bpo-30208: DOC: fix small typos in IDLE (#1357) (cherry picked from commit d9af73330f46d79cc0c56d369f65ebeec3cb5334) --- Doc/library/idle.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index a629bc50dbc749..80dd6fac4b2c60 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -244,7 +244,7 @@ Go to File/Line single: stack viewer Debugger (toggle) - When actived, code entered in the Shell or run from an Editor will run + When activated, code entered in the Shell or run from an Editor will run under the debugger. In the Editor, breakpoints can be set with the context menu. This feature is still incomplete and somewhat experimental. @@ -372,7 +372,7 @@ the :kbd:`Command` key on Mac OSX. * :kbd:`C-l` center window around the insertion point - * :kbd:`C-b` go backwards one character without deleting (usually you can + * :kbd:`C-b` go backward one character without deleting (usually you can also use the cursor key for this) * :kbd:`C-f` go forward one character without deleting (usually you can @@ -394,7 +394,7 @@ After a block-opening statement, the next line is indented by 4 spaces (in the Python Shell window by one tab). After certain keywords (break, return etc.) the next line is dedented. In leading indentation, :kbd:`Backspace` deletes up to 4 spaces if they are there. :kbd:`Tab` inserts spaces (in the Python -Shell window one tab), number depends on Indent width. Currently tabs +Shell window one tab), number depends on Indent width. Currently, tabs are restricted to four spaces due to Tcl/Tk limitations. See also the indent/dedent region commands in the edit menu. @@ -418,7 +418,7 @@ If there is only one possible completion for the characters entered, a :kbd:`C-space` will open a completions window. In an empty string, this will contain the files in the current directory. On a blank line, it will contain the built-in and user-defined functions and -classes in the current name spaces, plus any modules imported. If some +classes in the current namespaces, plus any modules imported. If some characters have been entered, the ACW will attempt to be more specific. If a string of characters is typed, the ACW selection will jump to the @@ -557,7 +557,7 @@ IDLE-console differences As much as possible, the result of executing Python code with IDLE is the same as executing the same code in a console window. However, the different -interface and operation occasionally affects visible results. For instance, +interface and operation occasionally affect visible results. For instance, ``sys.modules`` starts with more entries. IDLE also replaces ``sys.stdin``, ``sys.stdout``, and ``sys.stderr`` with @@ -583,7 +583,7 @@ If firewall software complains anyway, you can ignore it. If the attempt to make the socket connection fails, Idle will notify you. Such failures are sometimes transient, but if persistent, the problem -may be either a firewall blocking the connecton or misconfiguration of +may be either a firewall blocking the connection or misconfiguration of a particular system. Until the problem is fixed, one can run Idle with the -n command line switch. @@ -619,14 +619,14 @@ Setting preferences The font preferences, highlighting, keys, and general preferences can be changed via Configure IDLE on the Option menu. Keys can be user defined; -IDLE ships with four built in key sets. In addition a user can create a +IDLE ships with four built-in key sets. In addition, a user can create a custom key set in the Configure IDLE dialog under the keys tab. Extensions ^^^^^^^^^^ -IDLE contains an extension facility. Peferences for extensions can be +IDLE contains an extension facility. Preferences for extensions can be changed with Configure Extensions. See the beginning of config-extensions.def in the idlelib directory for further information. The default extensions are currently: From e37d163ab215964898705d0bdb9c5457fad53708 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 29 Apr 2017 22:18:51 -0700 Subject: [PATCH 174/340] [3.5] Improve the grammar in windows.rst (GH-1330) (GH-1359) (cherry picked from commit 80a3da4d4aad0b51893e1e2f696b6252eca80e07) --- Doc/using/windows.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/using/windows.rst b/Doc/using/windows.rst index a4a6a30c362523..1db86075e743d1 100644 --- a/Doc/using/windows.rst +++ b/Doc/using/windows.rst @@ -517,9 +517,9 @@ Shebang Lines If the first line of a script file starts with ``#!``, it is known as a "shebang" line. Linux and other Unix like operating systems have native -support for such lines and are commonly used on such systems to indicate how -a script should be executed. This launcher allows the same facilities to be -using with Python scripts on Windows and the examples above demonstrate their +support for such lines and they are commonly used on such systems to indicate +how a script should be executed. This launcher allows the same facilities to +be used with Python scripts on Windows and the examples above demonstrate their use. To allow shebang lines in Python scripts to be portable between Unix and From 03a7ab77d2f75323e1f3e8b6a1c164e701d58bfb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 May 2017 11:16:21 +0200 Subject: [PATCH 175/340] bpo-30104: Use -fno-strict-aliasing on clang (#1376) (#1377) Python/dtoa.c is not compiled correctly with clang 4.0 and optimization level -O2 or higher, because of an aliasing issue on the double/ULong[2] union. Only compile dtoa.c with -fno-strict-aliasing. LLVM bug report: https://bugs.llvm.org//show_bug.cgi?id=31928 (cherry picked from commit 809101f14f27ddb394cd77c477470761ecf99f41) --- Makefile.pre.in | 9 +++++++++ configure | 35 ++++++++++++++++++++++++++++------- configure.ac | 34 +++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index e1436c3bfdca91..f0450effad0f5a 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -103,6 +103,8 @@ ARFLAGS= @ARFLAGS@ CFLAGSFORSHARED=@CFLAGSFORSHARED@ # C flags used for building the interpreter object files PY_CORE_CFLAGS= $(PY_CFLAGS) $(PY_CFLAGS_NODIST) $(PY_CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE +# Strict or non-strict aliasing flags used to compile dtoa.c, see above +CFLAGS_ALIASING=@CFLAGS_ALIASING@ # Machine-dependent subdirectories @@ -1532,6 +1534,13 @@ config.status: $(srcdir)/configure .c.o: $(CC) -c $(PY_CORE_CFLAGS) -o $@ $< +# bpo-30104: dtoa.c uses union to cast double to unsigned long[2]. clang 4.0 +# with -O2 or higher and strict aliasing miscompiles the ratio() function +# causing rounding issues. Compile dtoa.c using -fno-strict-aliasing on clang. +# https://bugs.llvm.org//show_bug.cgi?id=31928 +Python/dtoa.o: Python/dtoa.c + $(CC) -c $(PY_CORE_CFLAGS) $(CFLAGS_ALIASING) -o $@ $< + # Run reindent on the library reindent: ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/reindent.py -r $(srcdir)/Lib diff --git a/configure b/configure index c84a8ec9e04a1a..f5fe5f459c394f 100755 --- a/configure +++ b/configure @@ -666,6 +666,7 @@ OTHER_LIBTOOL_OPT UNIVERSAL_ARCH_FLAGS CFLAGS_NODIST BASECFLAGS +CFLAGS_ALIASING OPT LLVM_PROF_FOUND target_os @@ -6859,6 +6860,7 @@ esac # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line + if test "${OPT-unset}" = "unset" then case $GCC in @@ -6871,30 +6873,49 @@ then WRAP="-fwrapv" fi - # Clang also needs -fwrapv case $CC in - *clang*) WRAP="-fwrapv" - ;; + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi esac + if test -n "${cc_is_clang}" + then + # Clang also needs -fwrapv + WRAP="-fwrapv" + # bpo-30104: disable strict aliasing to compile correctly dtoa.c, + # see Makefile.pre.in for more information + CFLAGS_ALIASING="-fno-strict-aliasing" + fi + case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then # Optimization messes up debuggers, so turn it off for # debug builds. if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then - OPT="-g -Og -Wall $STRICT_PROTO" + OPT="-g -Og -Wall" else - OPT="-g -O0 -Wall $STRICT_PROTO" + OPT="-g -O0 -Wall" fi else - OPT="-g $WRAP -O3 -Wall $STRICT_PROTO" + OPT="-g $WRAP -O3 -Wall" fi ;; *) - OPT="-O3 -Wall $STRICT_PROTO" + OPT="-O3 -Wall" ;; esac + + OPT="$OPT $STRICT_PROTO" + case $ac_sys_system in SCO_SV*) OPT="$OPT -m486 -DSCO5" ;; diff --git a/configure.ac b/configure.ac index 779fe3764c7f5a..21284d01684587 100644 --- a/configure.ac +++ b/configure.ac @@ -1403,6 +1403,7 @@ esac # tweak OPT based on compiler and platform, only if the user didn't set # it on the command line AC_SUBST(OPT) +AC_SUBST(CFLAGS_ALIASING) if test "${OPT-unset}" = "unset" then case $GCC in @@ -1415,30 +1416,49 @@ then WRAP="-fwrapv" fi - # Clang also needs -fwrapv case $CC in - *clang*) WRAP="-fwrapv" - ;; + *clang*) + cc_is_clang=1 + ;; + *) + if $CC --version 2>&1 | grep -q clang + then + cc_is_clang=1 + else + cc_is_clang= + fi esac + if test -n "${cc_is_clang}" + then + # Clang also needs -fwrapv + WRAP="-fwrapv" + # bpo-30104: disable strict aliasing to compile correctly dtoa.c, + # see Makefile.pre.in for more information + CFLAGS_ALIASING="-fno-strict-aliasing" + fi + case $ac_cv_prog_cc_g in yes) if test "$Py_DEBUG" = 'true' ; then # Optimization messes up debuggers, so turn it off for # debug builds. if "$CC" -v --help 2>/dev/null |grep -- -Og > /dev/null; then - OPT="-g -Og -Wall $STRICT_PROTO" + OPT="-g -Og -Wall" else - OPT="-g -O0 -Wall $STRICT_PROTO" + OPT="-g -O0 -Wall" fi else - OPT="-g $WRAP -O3 -Wall $STRICT_PROTO" + OPT="-g $WRAP -O3 -Wall" fi ;; *) - OPT="-O3 -Wall $STRICT_PROTO" + OPT="-O3 -Wall" ;; esac + + OPT="$OPT $STRICT_PROTO" + case $ac_sys_system in SCO_SV*) OPT="$OPT -m486 -DSCO5" ;; From 092f4602c329e23b863692249cc630a3eba5b6b5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 May 2017 11:45:45 +0200 Subject: [PATCH 176/340] bpo-30108: Restore sys.path in test_site (#1197) (#1379) Add setUpModule() and tearDownModule() functions to test_site to save/restore sys.path at the module level to prevent warning if the user site directory is created, since site.addsitedir() modifies sys.path. (cherry picked from commit b85c136903c6d2368162f7c4a58f258c9c69ead0) --- Lib/test/test_site.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index da20a3d21a936f..755eb9cdb84958 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -26,14 +26,27 @@ import site -if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE): - # need to add user site directory for tests - try: - os.makedirs(site.USER_SITE) - site.addsitedir(site.USER_SITE) - except PermissionError as exc: - raise unittest.SkipTest('unable to create user site directory (%r): %s' - % (site.USER_SITE, exc)) + +OLD_SYS_PATH = None + + +def setUpModule(): + global OLD_SYS_PATH + OLD_SYS_PATH = sys.path[:] + + if site.ENABLE_USER_SITE and not os.path.isdir(site.USER_SITE): + # need to add user site directory for tests + try: + os.makedirs(site.USER_SITE) + # modify sys.path: will be restored by tearDownModule() + site.addsitedir(site.USER_SITE) + except PermissionError as exc: + raise unittest.SkipTest('unable to create user site directory (%r): %s' + % (site.USER_SITE, exc)) + + +def tearDownModule(): + sys.path[:] = OLD_SYS_PATH class HelperFunctionsTests(unittest.TestCase): From 3ceeb84b5a90e327ef55190105e82c926b0b8aab Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 May 2017 16:26:04 +0200 Subject: [PATCH 177/340] bpo-30132: distutils BuildExtTestCase use temp_cwd (#1387) (#1388) BuildExtTestCase of test_distutils now uses support.temp_cwd() in setUp() to remove files created in the current working in all BuildExtTestCase unit tests, not only test_build_ext(). Fix the following warning: Warning -- files was modified by test_distutils Before: [] After: ['vc140.pdb'] (cherry picked from commit 30768958490c658fba0fe24f1cabbdad44be22ff) --- Lib/distutils/tests/test_build_ext.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index f3df564e37347d..ce13227126f74f 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -37,6 +37,13 @@ def setUp(self): from distutils.command import build_ext build_ext.USER_BASE = site.USER_BASE + # bpo-30132: On Windows, a .pdb file may be created in the current + # working directory. Create a temporary working directory to cleanup + # everything at the end of the test. + self.temp_cwd = support.temp_cwd() + self.temp_cwd.__enter__() + self.addCleanup(self.temp_cwd.__exit__, None, None, None) + def build_ext(self, *args, **kwargs): return build_ext(*args, **kwargs) From 89a54c73746417bae003a9985668fa665040d5d9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 May 2017 16:48:36 +0200 Subject: [PATCH 178/340] bpo-30199: test_ssl closes all asyncore channels (#1381) (#1389) AsyncoreEchoServer of test_ssl now calls asyncore.close_all(ignore_all=True) to ensure that asyncore.socket_map is cleared once the test completes, even if ConnectionHandler was not correctly unregistered. Fix the following warning: Warning -- asyncore.socket_map was modified by test_ssl Before: {} After: {6: } (cherry picked from commit 1dae7450c68bad498e57800387b24cb103c461fa) --- Lib/test/test_ssl.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 551558304fcdd6..ffb7314f577c19 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -2034,7 +2034,7 @@ class AsyncoreEchoServer(threading.Thread): class EchoServer (asyncore.dispatcher): - class ConnectionHandler (asyncore.dispatcher_with_send): + class ConnectionHandler(asyncore.dispatcher_with_send): def __init__(self, conn, certfile): self.socket = ssl.wrap_socket(conn, server_side=True, @@ -2125,6 +2125,8 @@ def __exit__(self, *args): self.join() if support.verbose: sys.stdout.write(" cleanup: successfully joined.\n") + # make sure that ConnectionHandler is removed from socket_map + asyncore.close_all(ignore_all=True) def start (self, flag=None): self.flag = flag From 9b854debea4dbd91c9ffc36f084a90fa225d5197 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 2 May 2017 23:06:39 +0200 Subject: [PATCH 179/340] Issue 27372: Stop test_idle from changing locale, so test passes. (#1397) In 3.6, the warning is now called an error, making it harder to ignore. (cherry picked from commit 7c1534141d3a159a32db9742e1d201d5c7a9ba81) --- Lib/idlelib/EditorWindow.py | 8 +++- Lib/idlelib/IOBinding.py | 86 ++++++++++++++++++++----------------- Lib/idlelib/__init__.py | 1 + Lib/test/test_idle.py | 15 ++++--- 4 files changed, 62 insertions(+), 48 deletions(-) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py index 9944da3e7084c7..861353669d7520 100644 --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -25,9 +25,9 @@ # The default tab setting for a Text widget, in average-width characters. TK_TABWIDTH_DEFAULT = 8 - _py_version = ' (%s)' % platform.python_version() + def _sphinx_version(): "Format sys.version_info to produce the Sphinx version string used to install the chm docs" major, minor, micro, level, serial = sys.version_info @@ -92,11 +92,12 @@ class EditorWindow(object): from idlelib.Percolator import Percolator from idlelib.ColorDelegator import ColorDelegator, color_config from idlelib.UndoDelegator import UndoDelegator - from idlelib.IOBinding import IOBinding, filesystemencoding, encoding + from idlelib.IOBinding import IOBinding, encoding from idlelib import Bindings from tkinter import Toplevel from idlelib.MultiStatusBar import MultiStatusBar + filesystemencoding = sys.getfilesystemencoding() # for file names help_url = None def __init__(self, flist=None, filename=None, key=None, root=None): @@ -1686,5 +1687,8 @@ def _editor_window(parent): # htest # # edit.text.bind("<>", edit.close_event) if __name__ == '__main__': + import unittest + unittest.main('idlelib.idle_test.test_editor', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_editor_window) diff --git a/Lib/idlelib/IOBinding.py b/Lib/idlelib/IOBinding.py index 84f39a2fee8e55..efd0d5e68ca4d2 100644 --- a/Lib/idlelib/IOBinding.py +++ b/Lib/idlelib/IOBinding.py @@ -10,57 +10,60 @@ import tkinter.messagebox as tkMessageBox from tkinter.simpledialog import askstring +import idlelib from idlelib.configHandler import idleConf - -# Try setting the locale, so that we can find out -# what encoding to use -try: - import locale - locale.setlocale(locale.LC_CTYPE, "") -except (ImportError, locale.Error): - pass - -# Encoding for file names -filesystemencoding = sys.getfilesystemencoding() ### currently unused - -locale_encoding = 'ascii' -if sys.platform == 'win32': - # On Windows, we could use "mbcs". However, to give the user - # a portable encoding name, we need to find the code page - try: - locale_encoding = locale.getdefaultlocale()[1] - codecs.lookup(locale_encoding) - except LookupError: - pass +if idlelib.testing: # Set True by test.test_idle to avoid setlocale. + encoding = 'utf-8' else: + # Try setting the locale, so that we can find out + # what encoding to use try: - # Different things can fail here: the locale module may not be - # loaded, it may not offer nl_langinfo, or CODESET, or the - # resulting codeset may be unknown to Python. We ignore all - # these problems, falling back to ASCII - locale_encoding = locale.nl_langinfo(locale.CODESET) - if locale_encoding is None or locale_encoding is '': - # situation occurs on Mac OS X - locale_encoding = 'ascii' - codecs.lookup(locale_encoding) - except (NameError, AttributeError, LookupError): - # Try getdefaultlocale: it parses environment variables, - # which may give a clue. Unfortunately, getdefaultlocale has - # bugs that can cause ValueError. + import locale + locale.setlocale(locale.LC_CTYPE, "") + except (ImportError, locale.Error): + pass + + locale_decode = 'ascii' + if sys.platform == 'win32': + # On Windows, we could use "mbcs". However, to give the user + # a portable encoding name, we need to find the code page try: locale_encoding = locale.getdefaultlocale()[1] + codecs.lookup(locale_encoding) + except LookupError: + pass + else: + try: + # Different things can fail here: the locale module may not be + # loaded, it may not offer nl_langinfo, or CODESET, or the + # resulting codeset may be unknown to Python. We ignore all + # these problems, falling back to ASCII + locale_encoding = locale.nl_langinfo(locale.CODESET) if locale_encoding is None or locale_encoding is '': # situation occurs on Mac OS X locale_encoding = 'ascii' codecs.lookup(locale_encoding) - except (ValueError, LookupError): - pass + except (NameError, AttributeError, LookupError): + # Try getdefaultlocale: it parses environment variables, + # which may give a clue. Unfortunately, getdefaultlocale has + # bugs that can cause ValueError. + try: + locale_encoding = locale.getdefaultlocale()[1] + if locale_encoding is None or locale_encoding is '': + # situation occurs on Mac OS X + locale_encoding = 'ascii' + codecs.lookup(locale_encoding) + except (ValueError, LookupError): + pass -locale_encoding = locale_encoding.lower() + locale_encoding = locale_encoding.lower() -encoding = locale_encoding ### KBK 07Sep07 This is used all over IDLE, check! - ### 'encoding' is used below in encode(), check! + encoding = locale_encoding + # Encoding is used in multiple files; locale_encoding nowhere. + # The only use of 'encoding' below is in _decode as initial value + # of deprecated block asking user for encoding. + # Perhaps use elsewhere should be reviewed. coding_re = re.compile(r'^[ \t\f]*#.*?coding[:=][ \t]*([-\w.]+)', re.ASCII) blank_re = re.compile(r'^[ \t\f]*(?:[#\r\n]|$)', re.ASCII) @@ -301,7 +304,7 @@ def _decode(self, two_lines, bytes): "The file's encoding is invalid for Python 3.x.\n" "IDLE will convert it to UTF-8.\n" "What is the current encoding of the file?", - initialvalue = locale_encoding, + initialvalue = encoding, parent = self.editwin.text) if enc: @@ -561,5 +564,8 @@ def savecopy(self, event): IOBinding(editwin) if __name__ == "__main__": + import unittest + unittest.main('idlelib.idle_test.test_iomenu', verbosity=2, exit=False) + from idlelib.idle_test.htest import run run(_io_binding) diff --git a/Lib/idlelib/__init__.py b/Lib/idlelib/__init__.py index 711f61bb6928d5..208ced13a621b7 100644 --- a/Lib/idlelib/__init__.py +++ b/Lib/idlelib/__init__.py @@ -6,3 +6,4 @@ The other files are private implementations. Their details are subject to change. See PEP 434 for more. Import them at your own risk. """ +testing = False # Set True by test.test_idle. diff --git a/Lib/test/test_idle.py b/Lib/test/test_idle.py index 141e89e4931881..7df98ff4366a03 100644 --- a/Lib/test/test_idle.py +++ b/Lib/test/test_idle.py @@ -2,15 +2,18 @@ from test import support from test.support import import_module -# Skip test if _thread or _tkinter wasn't built or idlelib was deleted. +# Skip test if _thread or _tkinter wasn't built, or idlelib is missing, +# or if tcl/tk version before 8.5, which is needed for ttk widgets. + import_module('threading') # imported by PyShell, imports _thread tk = import_module('tkinter') # imports _tkinter -idletest = import_module('idlelib.idle_test') +idlelib = import_module('idlelib') +idlelib.testing = True # Avoid locale-changed test error -# Without test_main present, regrtest.runtest_inner (line1219) calls -# unittest.TestLoader().loadTestsFromModule(this_module) which calls -# load_tests() if it finds it. (Unittest.main does the same.) -load_tests = idletest.load_tests +# Without test_main present, test.libregrtest.runtest.runtest_inner +# calls (line 173) unittest.TestLoader().loadTestsFromModule(module) +# which calls load_tests() if it finds it. (Unittest.main does the same.) +from idlelib.idle_test import load_tests if __name__ == '__main__': unittest.main(verbosity=2, exit=False) From 360fb81367bb409bb7a1d261d88fcf82cee528f0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 3 May 2017 00:06:17 +0200 Subject: [PATCH 180/340] [3.5] bpo-30232: Support Git worktree in configure.ac (#1398) (#1401) * bpo-30232: Support Git worktree in configure.ac (#1391) Don't test if .git/HEAD file exists, but only if the .git file (or directory) exists. (cherry picked from commit 5facdbb29169c2799c42f887cef4cd9d087b0167) * bpo-30232: Regenerate configure (#1396) Run autoconf. (cherry picked from commit 9ed34a89532763cf89f5e11fffb91ef7dee29fed) (cherry picked from commit 4dae0d111dd7bb34ec730eea2327a3219acff211) --- configure | 2 +- configure.ac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure b/configure index f5fe5f459c394f..a6d83f266008c9 100755 --- a/configure +++ b/configure @@ -2840,7 +2840,7 @@ fi -if test -e $srcdir/.git/HEAD +if test -e $srcdir/.git then # Extract the first word of "git", so it can be a program name with args. set dummy git; ac_word=$2 diff --git a/configure.ac b/configure.ac index 21284d01684587..22ac805a66a3f6 100644 --- a/configure.ac +++ b/configure.ac @@ -29,7 +29,7 @@ AC_SUBST(GITVERSION) AC_SUBST(GITTAG) AC_SUBST(GITBRANCH) -if test -e $srcdir/.git/HEAD +if test -e $srcdir/.git then AC_CHECK_PROG(HAS_GIT, git, found, not-found) else From 0d9d61828bbd6cbc289489bf1d439fa91eca3743 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 3 May 2017 00:22:28 +0200 Subject: [PATCH 181/340] Backport bpo-30205 to 3.5 (#1404) --- Lib/test/test_socket.py | 4 ++++ Misc/NEWS | 2 ++ Modules/socketmodule.c | 6 +++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index b72fc8fbf0cadd..c652c6fd01428f 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4589,6 +4589,10 @@ def bind(self, sock, path): else: raise + def testUnbound(self): + # Issue #30205 + self.assertIn(self.sock.getsockname(), (None, '')) + def testStrAddr(self): # Test binding to and retrieving a normal string pathname. path = os.path.abspath(support.TESTFN) diff --git a/Misc/NEWS b/Misc/NEWS index 4c90aa83dfb0da..c428d77f17b754 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Extension Modules Library ------- +- bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux. + - bpo-30070: Fixed leaks and crashes in errors handling in the parser module. - bpo-30061: Fixed crashes in IOBase methods __next__() and readlines() when diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index af6cc94415b686..47abe8d3f2c6ee 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1183,9 +1183,9 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) { struct sockaddr_un *a = (struct sockaddr_un *) addr; #ifdef linux - if (a->sun_path[0] == 0) { /* Linux abstract namespace */ - addrlen -= offsetof(struct sockaddr_un, sun_path); - return PyBytes_FromStringAndSize(a->sun_path, addrlen); + size_t linuxaddrlen = addrlen - offsetof(struct sockaddr_un, sun_path); + if (linuxaddrlen > 0 && a->sun_path[0] == 0) { /* Linux abstract namespace */ + return PyBytes_FromStringAndSize(a->sun_path, linuxaddrlen); } else #endif /* linux */ From 22982350235f8c5821b71661a5616423e1c7fcc0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 3 May 2017 02:12:34 +0200 Subject: [PATCH 182/340] regrtest: always show before/after of modified env (#1407) Buildbots don't run tests with -vv and so only log "xxx was modified by test_xxx" which is not enough to debug such random issue. In many cases, I'm unable to reproduce the warning and so unable to fix it. Always logging the value before and value after should help to debug such warning on buildbots. (cherry picked from commit ec4b17239d899550be4ee6104b61751bb3c70382) --- Lib/test/regrtest.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 12909ec4778319..d7ca07b6647986 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -1267,10 +1267,9 @@ def __exit__(self, exc_type, exc_val, exc_tb): print("Warning -- {} was modified by {}".format( name, self.testname), file=sys.stderr) - if self.verbose > 1 and not self.pgo: - print(" Before: {}\n After: {} ".format( - original, current), - file=sys.stderr) + print(" Before: {}\n After: {} ".format( + original, current), + file=sys.stderr) return False From f99623a5bee30b18a8fa55a9061753064d8a88f4 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 2 May 2017 21:36:01 -0700 Subject: [PATCH 183/340] [3.5] Fix typo in selectors.rst (GH-1383) (#1415) decriptor -> descriptor (cherry picked from commit b0d82036549074357717d130a772d1e2ebc8ea01) --- Doc/library/selectors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/selectors.rst b/Doc/library/selectors.rst index 1624d88aaed38d..6d864a836de075 100644 --- a/Doc/library/selectors.rst +++ b/Doc/library/selectors.rst @@ -68,7 +68,7 @@ constants below: .. class:: SelectorKey A :class:`SelectorKey` is a :class:`~collections.namedtuple` used to - associate a file object to its underlying file decriptor, selected event + associate a file object to its underlying file descriptor, selected event mask and attached data. It is returned by several :class:`BaseSelector` methods. From 23b312b087582cec5cc8c528d267eb42061601ac Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 3 May 2017 12:04:57 +0200 Subject: [PATCH 184/340] [3.6] bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS (#463) (#1424) Skip some tests of select.poll when running on macOS due to unresolved issues with the underlying system poll function on some macOS versions. (cherry picked from commit de04644627f82d9dc48b3423def7ff5b4aa1926a) (cherry picked from commit 1d391f926b37484b8d4b326003a72c0084db19ec) --- Lib/test/eintrdata/eintr_tester.py | 2 ++ Lib/test/test_asyncore.py | 3 +++ Misc/NEWS | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py index e3f1aa519e0fe9..81b6277a0401ff 100644 --- a/Lib/test/eintrdata/eintr_tester.py +++ b/Lib/test/eintrdata/eintr_tester.py @@ -424,6 +424,8 @@ def test_select(self): self.stop_alarm() self.assertGreaterEqual(dt, self.sleep_time) + @unittest.skipIf(sys.platform == "darwin", + "poll may fail on macOS; see issue #28087") @unittest.skipUnless(hasattr(select, 'poll'), 'need select.poll') def test_poll(self): poller = select.poll() diff --git a/Lib/test/test_asyncore.py b/Lib/test/test_asyncore.py index 38579168cfd47d..18f1ea23fae8cc 100644 --- a/Lib/test/test_asyncore.py +++ b/Lib/test/test_asyncore.py @@ -656,6 +656,9 @@ def test_handle_expt(self): if HAS_UNIX_SOCKETS and self.family == socket.AF_UNIX: self.skipTest("Not applicable to AF_UNIX sockets.") + if sys.platform == "darwin" and self.use_poll: + self.skipTest("poll may fail on macOS; see issue #28087") + class TestClient(BaseClient): def handle_expt(self): self.socket.recv(1024, socket.MSG_OOB) diff --git a/Misc/NEWS b/Misc/NEWS index c428d77f17b754..c7d273c2414d21 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -201,6 +201,10 @@ Build Tests ----- +- bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS. + Skip some tests of select.poll when running on macOS due to unresolved + issues with the underlying system poll function on some macOS versions. + - bpo-30197: Enhanced functions swap_attr() and swap_item() in the test.support module. They now work when delete replaced attribute or item inside the with statement. The old value of the attribute or item (or None From 5e9c1101924bacf3ead03124b5c1e48551638360 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 3 May 2017 14:11:35 +0200 Subject: [PATCH 185/340] bpo-24725: Skip the test_socket.testFDPassEmpty on OS X (#1427) In OS X 10.11, the test fails consistently due to a platform change since 10.10. Thanks to Jeff Ramnani for the patch. (cherry picked from commit 3c61a448f106c7cafb050ff7be5c5c421273e68f) --- Lib/test/test_socket.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index c652c6fd01428f..58c04d71045d56 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -2844,6 +2844,7 @@ def sendAncillaryIfPossible(self, msg, ancdata): nbytes = self.sendmsgToServer([msg]) self.assertEqual(nbytes, len(msg)) + @unittest.skipIf(sys.platform == "darwin", "skipping, see issue #24725") def testFDPassEmpty(self): # Try to pass an empty FD array. Can receive either no array # or an empty array. From 4b15e45895ca56ac5f7837cacb8cd3ccc26d1f66 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 3 May 2017 09:37:50 -0700 Subject: [PATCH 186/340] [3.5] bpo-28556: Routine updates to typing (GH-1366) (#1417) - Add NoReturn type - Use WrapperDescriptorType (original PR by Jim Fasarakis-Hilliard) - Minor bug-fixes (cherry picked from commit f06e0218ef6007667f5d61184b85a81a0466d3ae) --- Lib/test/test_typing.py | 51 +++++++++++++++++++++++++++++++++++++---- Lib/typing.py | 35 ++++++++++++++++++++++++---- Misc/NEWS | 4 ++++ 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index f0070ec975791a..b3cabda394497e 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -6,7 +6,7 @@ from unittest import TestCase, main, skipUnless, SkipTest from copy import copy, deepcopy -from typing import Any +from typing import Any, NoReturn from typing import TypeVar, AnyStr from typing import T, KT, VT # Not in __all__. from typing import Union, Optional @@ -102,10 +102,6 @@ def test_cannot_instantiate(self): with self.assertRaises(TypeError): type(Any)() - def test_cannot_subscript(self): - with self.assertRaises(TypeError): - Any[int] - def test_any_works_with_alias(self): # These expressions must simply not fail. typing.Match[Any] @@ -113,6 +109,40 @@ def test_any_works_with_alias(self): typing.IO[Any] +class NoReturnTests(BaseTestCase): + + def test_noreturn_instance_type_error(self): + with self.assertRaises(TypeError): + isinstance(42, NoReturn) + + def test_noreturn_subclass_type_error(self): + with self.assertRaises(TypeError): + issubclass(Employee, NoReturn) + with self.assertRaises(TypeError): + issubclass(NoReturn, Employee) + + def test_repr(self): + self.assertEqual(repr(NoReturn), 'typing.NoReturn') + + def test_not_generic(self): + with self.assertRaises(TypeError): + NoReturn[int] + + def test_cannot_subclass(self): + with self.assertRaises(TypeError): + class A(NoReturn): + pass + with self.assertRaises(TypeError): + class A(type(NoReturn)): + pass + + def test_cannot_instantiate(self): + with self.assertRaises(TypeError): + NoReturn() + with self.assertRaises(TypeError): + type(NoReturn)() + + class TypeVarTests(BaseTestCase): def test_basic_plain(self): @@ -2273,6 +2303,14 @@ def _fields(self): return 'no chance for this' """) + with self.assertRaises(AttributeError): + exec(""" +class XMethBad2(NamedTuple): + x: int + def _source(self): + return 'no chance for this as well' +""") + @skipUnless(PY36, 'Python 3.6 required') def test_namedtuple_keyword_usage(self): LocalEmployee = NamedTuple("LocalEmployee", name=str, age=int) @@ -2420,6 +2458,9 @@ def test_all(self): self.assertNotIn('sys', a) # Check that Text is defined. self.assertIn('Text', a) + # Check previously missing classes. + self.assertIn('SupportsBytes', a) + self.assertIn('SupportsComplex', a) if __name__ == '__main__': diff --git a/Lib/typing.py b/Lib/typing.py index 9a0f49099a3114..645bc6f8ae0edd 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -11,9 +11,9 @@ except ImportError: import collections as collections_abc # Fallback for PY3.2. try: - from types import SlotWrapperType, MethodWrapperType, MethodDescriptorType + from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType except ImportError: - SlotWrapperType = type(object.__init__) + WrapperDescriptorType = type(object.__init__) MethodWrapperType = type(object().__str__) MethodDescriptorType = type(str.join) @@ -63,6 +63,8 @@ # Structural checks, a.k.a. protocols. 'Reversible', 'SupportsAbs', + 'SupportsBytes', + 'SupportsComplex', 'SupportsFloat', 'SupportsInt', 'SupportsRound', @@ -420,6 +422,31 @@ def __subclasscheck__(self, cls): Any = _Any(_root=True) +class _NoReturn(_FinalTypingBase, _root=True): + """Special type indicating functions that never return. + Example:: + + from typing import NoReturn + + def stop() -> NoReturn: + raise Exception('no way') + + This type is invalid in other positions, e.g., ``List[NoReturn]`` + will fail in static type checkers. + """ + + __slots__ = () + + def __instancecheck__(self, obj): + raise TypeError("NoReturn cannot be used with isinstance().") + + def __subclasscheck__(self, cls): + raise TypeError("NoReturn cannot be used with issubclass().") + + +NoReturn = _NoReturn(_root=True) + + class TypeVar(_TypingBase, _root=True): """Type variable. @@ -1450,7 +1477,7 @@ def _get_defaults(func): _allowed_types = (types.FunctionType, types.BuiltinFunctionType, types.MethodType, types.ModuleType, - SlotWrapperType, MethodWrapperType, MethodDescriptorType) + WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) def get_type_hints(obj, globalns=None, localns=None): @@ -2051,7 +2078,7 @@ def _make_nmtuple(name, types): # attributes prohibited to set in NamedTuple class syntax _prohibited = ('__new__', '__init__', '__slots__', '__getnewargs__', '_fields', '_field_defaults', '_field_types', - '_make', '_replace', '_asdict') + '_make', '_replace', '_asdict', '_source') _special = ('__module__', '__name__', '__qualname__', '__annotations__') diff --git a/Misc/NEWS b/Misc/NEWS index c7d273c2414d21..93bd30ffd374d9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,10 @@ Extension Modules Library ------- +- bpo-28556: Various updates to typing module: add typing.NoReturn type, use + WrapperDescriptorType, minor bug-fixes. Original PRs by + Jim Fasarakis-Hilliard and Ivan Levkivskyi. + - bpo-30205: Fix getsockname() for unbound AF_UNIX sockets on Linux. - bpo-30070: Fixed leaks and crashes in errors handling in the parser module. From 5274faf5e360f74690ffb735e919cdba5fdbdf1c Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 3 May 2017 18:41:12 -0700 Subject: [PATCH 187/340] [3.5] bpo-28315: Improve code examples in docs (GH-1372) (#1446) Replace File "", line 1, in ? with File "", line 1, in (cherry picked from commit 8856940cf2e82cb17db2b684cd5732fe658605ca) --- Doc/extending/newtypes.rst | 2 +- Doc/howto/functional.rst | 6 +++--- Doc/library/ctypes.rst | 30 +++++++++++++++--------------- Doc/library/doctest.rst | 6 +++--- Doc/library/fpectl.rst | 2 +- Doc/library/pdb.rst | 2 +- Doc/library/unicodedata.rst | 2 +- Doc/reference/expressions.rst | 2 +- Doc/tutorial/classes.rst | 2 +- Doc/tutorial/controlflow.rst | 2 +- Doc/tutorial/datastructures.rst | 2 +- Doc/tutorial/inputoutput.rst | 2 +- 12 files changed, 30 insertions(+), 30 deletions(-) diff --git a/Doc/extending/newtypes.rst b/Doc/extending/newtypes.rst index b8ce4377877e70..003b4e505d3247 100644 --- a/Doc/extending/newtypes.rst +++ b/Doc/extending/newtypes.rst @@ -124,7 +124,7 @@ our objects and in some error messages, for example:: >>> "" + noddy.new_noddy() Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: cannot add type "noddy.Noddy" to string Note that the name is a dotted name that includes both the module name and the diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index 8ae9679894a578..a82dca7077e905 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -210,7 +210,7 @@ You can experiment with the iteration interface manually: 3 >>> next(it) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in StopIteration >>> @@ -474,7 +474,7 @@ Here's a sample usage of the ``generate_ints()`` generator: 2 >>> next(gen) Traceback (most recent call last): - File "stdin", line 1, in ? + File "stdin", line 1, in File "stdin", line 2, in generate_ints StopIteration @@ -577,7 +577,7 @@ And here's an example of changing the counter: 9 >>> next(it) #doctest: +SKIP Traceback (most recent call last): - File "t.py", line 15, in ? + File "t.py", line 15, in it.next() StopIteration diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst index 3536b32139e71b..97a59a7a5a436b 100644 --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -97,7 +97,7 @@ Functions are accessed as attributes of dll objects:: <_FuncPtr object at 0x...> >>> print(windll.kernel32.MyOwnFunction) # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in File "ctypes.py", line 239, in __getattr__ func = _StdcallFuncPtr(name, self) AttributeError: function 'MyOwnFunction' not found @@ -135,7 +135,7 @@ functions can be accessed by indexing the dll object with the ordinal number:: <_FuncPtr object at 0x...> >>> cdll.kernel32[0] # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in File "ctypes.py", line 310, in __getitem__ func = _StdcallFuncPtr(name, self) AttributeError: function ordinal 0 not found @@ -168,11 +168,11 @@ although an error is raised the function *has* been called:: >>> windll.kernel32.GetModuleHandleA() # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: Procedure probably called with not enough arguments (4 bytes missing) >>> windll.kernel32.GetModuleHandleA(0, 0) # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: Procedure probably called with too many arguments (4 bytes in excess) >>> @@ -181,13 +181,13 @@ The same exception is raised when you call an ``stdcall`` function with the >>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: Procedure probably called with not enough arguments (4 bytes missing) >>> >>> windll.msvcrt.printf(b"spam") # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: Procedure probably called with too many arguments (4 bytes in excess) >>> @@ -200,7 +200,7 @@ argument values:: >>> windll.kernel32.GetModuleHandleA(32) # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in OSError: exception: access violation reading 0x00000020 >>> @@ -373,7 +373,7 @@ from within *IDLE* or *PythonWin*:: 19 >>> printf(b"%f bottles of beer\n", 42.5) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ArgumentError: argument 2: exceptions.TypeError: Don't know how to convert parameter 2 >>> @@ -436,7 +436,7 @@ prototype for a C function), and tries to convert the arguments to valid types:: >>> printf(b"%d %d %d", 1, 2, 3) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ArgumentError: argument 2: exceptions.TypeError: wrong type >>> printf(b"%s %d %f\n", b"X", 2, 3) X 2 3.000000 @@ -486,7 +486,7 @@ single character Python bytes object into a C char:: 'def' >>> strchr(b"abcdef", b"def") Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ArgumentError: argument 2: exceptions.TypeError: one character string expected >>> print(strchr(b"abcdef", b"x")) None @@ -512,7 +512,7 @@ useful to check for error return values and automatically raise an exception:: 486539264 >>> GetModuleHandle("something silly") # doctest: +WINDOWS Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in File "", line 3, in ValidHandle OSError: [Errno 126] The specified module could not be found. >>> @@ -583,7 +583,7 @@ Here is a simple example of a POINT structure, which contains two integers named 0 5 >>> POINT(1, 2, 3) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: too many initializers >>> @@ -786,7 +786,7 @@ new type:: >>> PI(42) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: expected c_long instead of int >>> PI(c_int(42)) @@ -862,7 +862,7 @@ but not instances of other types:: >>> bar.values = (c_byte * 4)() Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: incompatible types, c_byte_Array_4 instance instead of LP_c_long instance >>> @@ -913,7 +913,7 @@ work:: ... ("next", POINTER(cell))] ... Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in File "", line 2, in cell NameError: name 'cell' is not defined >>> diff --git a/Doc/library/doctest.rst b/Doc/library/doctest.rst index 15b12f7aa786ea..587a0a09a94791 100644 --- a/Doc/library/doctest.rst +++ b/Doc/library/doctest.rst @@ -408,7 +408,7 @@ Simple example:: >>> [1, 2, 3].remove(42) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: list.remove(x): x not in list That doctest succeeds if :exc:`ValueError` is raised, with the ``list.remove(x): @@ -432,7 +432,7 @@ multi-line detail:: >>> raise ValueError('multi\n line\ndetail') Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: multi line detail @@ -591,7 +591,7 @@ doctest decides whether actual output matches an example's expected output: >>> (1, 2)[3] = 'moo' Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: object doesn't support item assignment passes under Python 2.3 and later Python versions with the flag specified, diff --git a/Doc/library/fpectl.rst b/Doc/library/fpectl.rst index e4b528cf0b0b6f..96607165ba4e3e 100644 --- a/Doc/library/fpectl.rst +++ b/Doc/library/fpectl.rst @@ -89,7 +89,7 @@ The following example demonstrates how to start up and test operation of the >>> import math >>> math.exp(1000) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in FloatingPointError: in math_1 diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index ba9e547317f9db..7bc729c28d7d90 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -76,7 +76,7 @@ The typical usage to inspect a crashed program is:: >>> import mymodule >>> mymodule.test() Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in File "./mymodule.py", line 4, in test test2() File "./mymodule.py", line 3, in test2 diff --git a/Doc/library/unicodedata.rst b/Doc/library/unicodedata.rst index 6cd8132f8a9870..51b0b66ebae497 100644 --- a/Doc/library/unicodedata.rst +++ b/Doc/library/unicodedata.rst @@ -158,7 +158,7 @@ Examples: 9 >>> unicodedata.decimal('a') Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: not a decimal >>> unicodedata.category('A') # 'L'etter, 'u'ppercase 'Lu' diff --git a/Doc/reference/expressions.rst b/Doc/reference/expressions.rst index d4d007330c7972..437a35062585a5 100644 --- a/Doc/reference/expressions.rst +++ b/Doc/reference/expressions.rst @@ -745,7 +745,7 @@ keyword arguments (and any ``**expression`` arguments -- see below). So:: 2 1 >>> f(a=1, *(2,)) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: f() got multiple values for keyword argument 'a' >>> f(1, *(2,)) 1 2 diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index e134d5d62ea667..073444cf8b3985 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -784,7 +784,7 @@ using the :func:`next` built-in function; this example shows how it all works:: 'c' >>> next(it) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in next(it) StopIteration diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index 12989b2a53069b..fbe4e924f0c5b9 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -472,7 +472,7 @@ Here's an example that fails due to this restriction:: ... >>> function(0, a=0) Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in TypeError: function() got multiple values for keyword argument 'a' When a final formal parameter of the form ``**name`` is present, it receives a diff --git a/Doc/tutorial/datastructures.rst b/Doc/tutorial/datastructures.rst index 6140ece046b975..1a73ac9d05936a 100644 --- a/Doc/tutorial/datastructures.rst +++ b/Doc/tutorial/datastructures.rst @@ -261,7 +261,7 @@ it must be parenthesized. :: [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] >>> # the tuple must be parenthesized, otherwise an error is raised >>> [x, x**2 for x in range(6)] - File "", line 1, in ? + File "", line 1, in [x, x**2 for x in range(6)] ^ SyntaxError: invalid syntax diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index dd9c7cd7315d6e..5add11a8a49b8b 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -361,7 +361,7 @@ attempts to use the file object will automatically fail. :: >>> f.close() >>> f.read() Traceback (most recent call last): - File "", line 1, in ? + File "", line 1, in ValueError: I/O operation on closed file It is good practice to use the :keyword:`with` keyword when dealing with file From 943861f09ab6bffcd1d97efcd0dd6c87c7f26800 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 4 May 2017 06:50:43 +0300 Subject: [PATCH 188/340] [3.5] bpo-30184: Add tests for invalid use of PyArg_ParseTupleAndKeywords. (GH-1316). (#1442) (cherry picked from commit 5f161fd86dd5bb936a1a2a13391b13b7e59ec201) --- Lib/test/test_capi.py | 34 +++++++++++++++++++++++++++------- Modules/_testcapimodule.c | 4 ++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index 042e5aaae35064..f4048583ed1173 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -487,9 +487,8 @@ def test_skipitem(self): # test the format unit when not skipped format = c + "i" try: - # (note: the format string must be bytes!) _testcapi.parse_tuple_and_keywords(tuple_1, dict_b, - format.encode("ascii"), keywords) + format, keywords) when_not_skipped = False except TypeError as e: s = "argument 1 (impossible)" @@ -501,7 +500,7 @@ def test_skipitem(self): optional_format = "|" + format try: _testcapi.parse_tuple_and_keywords(empty_tuple, dict_b, - optional_format.encode("ascii"), keywords) + optional_format, keywords) when_skipped = False except RuntimeError as e: s = "impossible: '{}'".format(format) @@ -514,15 +513,36 @@ def test_skipitem(self): self.assertIs(when_skipped, when_not_skipped, message) def test_parse_tuple_and_keywords(self): - # parse_tuple_and_keywords error handling tests + # Test handling errors in the parse_tuple_and_keywords helper itself self.assertRaises(TypeError, _testcapi.parse_tuple_and_keywords, (), {}, 42, []) self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, - (), {}, b'', 42) + (), {}, '', 42) self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, - (), {}, b'', [''] * 42) + (), {}, '', [''] * 42) self.assertRaises(ValueError, _testcapi.parse_tuple_and_keywords, - (), {}, b'', [42]) + (), {}, '', [42]) + + def test_bad_use(self): + # Test handling invalid format and keywords in + # PyArg_ParseTupleAndKeywords() + self.assertRaises((TypeError, SystemError), _testcapi.parse_tuple_and_keywords, + (1,), {}, '||O', ['a']) + self.assertRaises((RuntimeError, SystemError), _testcapi.parse_tuple_and_keywords, + (1, 2), {}, '|O|O', ['a', 'b']) + self.assertRaises((TypeError, SystemError), _testcapi.parse_tuple_and_keywords, + (), {'a': 1}, '$$O', ['a']) + self.assertRaises((RuntimeError, SystemError), _testcapi.parse_tuple_and_keywords, + (), {'a': 1, 'b': 2}, '$O$O', ['a', 'b']) + self.assertRaises((TypeError, SystemError), _testcapi.parse_tuple_and_keywords, + (), {'a': 1}, '$|O', ['a']) + self.assertRaises((RuntimeError, SystemError), _testcapi.parse_tuple_and_keywords, + (), {'a': 1, 'b': 2}, '$O|O', ['a', 'b']) + self.assertRaises((RuntimeError, SystemError), _testcapi.parse_tuple_and_keywords, + (1,), {}, '|O', ['a', 'b']) + self.assertRaises((RuntimeError, SystemError), _testcapi.parse_tuple_and_keywords, + (1,), {}, '|OO', ['a']) + @unittest.skipUnless(threading, 'Threading required for this test.') class TestThreadState(unittest.TestCase): diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 060a92da4b0397..fabcaabe808795 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1548,7 +1548,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) { PyObject *sub_args; PyObject *sub_kwargs; - char *sub_format; + const char *sub_format; PyObject *sub_keywords; Py_ssize_t i, size; @@ -1561,7 +1561,7 @@ parse_tuple_and_keywords(PyObject *self, PyObject *args) double buffers[8][4]; /* double ensures alignment where necessary */ - if (!PyArg_ParseTuple(args, "OOyO:parse_tuple_and_keywords", + if (!PyArg_ParseTuple(args, "OOsO:parse_tuple_and_keywords", &sub_args, &sub_kwargs, &sub_format, &sub_keywords)) return NULL; From 8a1c71053139f20348ea487c0c464694ed3c88c5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 4 May 2017 13:21:16 +0200 Subject: [PATCH 189/340] bpo-30225: Fix is_valid_fd() on macOS Tiger (#1443) (#1450) is_valid_fd() now uses fstat() instead of dup() on macOS to return 0 on a pipe when the other side of the pipe is closed. fstat() fails with EBADF in that case, whereas dup() succeed. (cherry picked from commit 1c4670ea0cc3d208121af11b9b973e6bb268e570) --- Python/pylifecycle.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 87dadc164c2645..422454c8730cbd 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -968,6 +968,14 @@ initsite(void) static int is_valid_fd(int fd) { +#ifdef __APPLE__ + /* bpo-30225: On macOS Tiger, when stdout is redirected to a pipe + and the other side of the pipe is closed, dup(1) succeed, whereas + fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect + such error. */ + struct stat st; + return (fstat(fd, &st) == 0); +#else int fd2; if (fd < 0 || !_PyVerify_fd(fd)) return 0; @@ -977,6 +985,7 @@ is_valid_fd(int fd) close(fd2); _Py_END_SUPPRESS_IPH return fd2 >= 0; +#endif } /* returns Py_None if the fd is not valid */ From 7299088ccf5f72b8494063814b58a180b4250aa7 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 4 May 2017 17:16:48 +0200 Subject: [PATCH 190/340] [3.5] bpo-30185: avoid KeyboardInterrupt tracebacks in forkserver (GH-1319) (#1455) * bpo-30185: avoid KeyboardInterrupt tracebacks in forkserver * Tweak comment. (cherry picked from commit 6dd4d734ed207ba16b017e38f8909de7ef187e29) --- Lib/multiprocessing/forkserver.py | 20 ++++++++++++++------ Misc/NEWS | 3 +++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Lib/multiprocessing/forkserver.py b/Lib/multiprocessing/forkserver.py index ad01ede0e06f8c..1b4c7cbea08297 100644 --- a/Lib/multiprocessing/forkserver.py +++ b/Lib/multiprocessing/forkserver.py @@ -149,8 +149,15 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): util._close_stdin() - # ignoring SIGCHLD means no need to reap zombie processes - handler = signal.signal(signal.SIGCHLD, signal.SIG_IGN) + # ignoring SIGCHLD means no need to reap zombie processes; + # letting SIGINT through avoids KeyboardInterrupt tracebacks + handlers = { + signal.SIGCHLD: signal.SIG_IGN, + signal.SIGINT: signal.SIG_DFL, + } + old_handlers = {sig: signal.signal(sig, val) + for (sig, val) in handlers.items()} + with socket.socket(socket.AF_UNIX, fileno=listener_fd) as listener, \ selectors.DefaultSelector() as selector: _forkserver._forkserver_address = listener.getsockname() @@ -175,7 +182,7 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): code = 1 if os.fork() == 0: try: - _serve_one(s, listener, alive_r, handler) + _serve_one(s, listener, alive_r, old_handlers) except Exception: sys.excepthook(*sys.exc_info()) sys.stderr.flush() @@ -186,11 +193,12 @@ def main(listener_fd, alive_r, preload, main_path=None, sys_path=None): if e.errno != errno.ECONNABORTED: raise -def _serve_one(s, listener, alive_r, handler): - # close unnecessary stuff and reset SIGCHLD handler +def _serve_one(s, listener, alive_r, handlers): + # close unnecessary stuff and reset signal handlers listener.close() os.close(alive_r) - signal.signal(signal.SIGCHLD, handler) + for sig, val in handlers.items(): + signal.signal(sig, val) # receive fds from parent process fds = reduction.recvfds(s, MAXFDS_TO_SEND + 1) diff --git a/Misc/NEWS b/Misc/NEWS index 93bd30ffd374d9..1852d687f7393a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Extension Modules Library ------- +- bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process + when Ctrl-C is received. + - bpo-28556: Various updates to typing module: add typing.NoReturn type, use WrapperDescriptorType, minor bug-fixes. Original PRs by Jim Fasarakis-Hilliard and Ivan Levkivskyi. From ab6b962ef241be97536573d7490ce1cfc74fde18 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 5 May 2017 02:19:59 +0200 Subject: [PATCH 191/340] bpo-23404: make touch becomes make regen-all (#1405) (#1461) (#1465) * bpo-23404: make touch becomes make regen-all (#1405) Don't rebuild generated files based on file modification time anymore, the action is now explicit. Replace "make touch" with "make regen-all". Changes: * Remove "make touch", Tools/hg/hgtouch.py and .hgtouch * Add a new "make regen-all" command to rebuild all generated files * Add subcommands to only generate specific files: - regen-ast: Include/Python-ast.h and Python/Python-ast.c - regen-grammar: Include/graminit.h and Python/graminit.c - regen-importlib: Python/importlib_external.h and Python/importlib.h - regen-opcode: Include/opcode.h - regen-opcode-targets: Python/opcode_targets.h - regen-typeslots: Objects/typeslots.inc * Rename PYTHON_FOR_GEN to PYTHON_FOR_REGEN * pgen is now only built by by "make regen-grammar" * Add $(srcdir)/ prefix to paths to source files to handle correctly compilation outside the source directory Note: $(PYTHON_FOR_REGEN) is no more used nor needed by "make" default target building Python. (cherry picked from commit a5c62a8e9f0de6c4133825a5710984a3cd5e102b) * bpo-30273: Update sysconfig (#1464) The AST_H_DIR variable was removed from Makefile.pre.in by the commit a5c62a8e9f0de6c4133825a5710984a3cd5e102b (bpo-23404). AST_H_DIR was hardcoded to "Include", so replace the removed variable by its content. Remove also ASDLGEN variable from sysconfig example since this variable was also removed. (cherry picked from commit b109a1d3360fc4bb87b9887264e3634632d392ca) (cherry picked from commit 9d02f562961efd12d3c8317a10916db7f77330cc) --- .hgtouch | 17 ---- Doc/library/sysconfig.rst | 1 - Lib/distutils/sysconfig.py | 2 +- Mac/BuildScript/build-installer.py | 3 - Makefile.pre.in | 149 ++++++++++++++--------------- Misc/NEWS | 4 + Tools/hg/hgtouch.py | 130 ------------------------- configure | 32 +++---- configure.ac | 13 +-- 9 files changed, 90 insertions(+), 261 deletions(-) delete mode 100644 .hgtouch delete mode 100644 Tools/hg/hgtouch.py diff --git a/.hgtouch b/.hgtouch deleted file mode 100644 index b9be0f11fdb829..00000000000000 --- a/.hgtouch +++ /dev/null @@ -1,17 +0,0 @@ -# -*- Makefile -*- -# Define dependencies of generated files that are checked into hg. -# The syntax of this file uses make rule dependencies, without actions - -Python/importlib.h: Lib/importlib/_bootstrap.py Programs/_freeze_importlib.c - -Include/opcode.h: Lib/opcode.py Tools/scripts/generate_opcode_h.py - -Include/Python-ast.h: Parser/Python.asdl Parser/asdl.py Parser/asdl_c.py -Python/Python-ast.c: Include/Python-ast.h - -Python/opcode_targets.h: Python/makeopcodetargets.py Lib/opcode.py - -Objects/typeslots.inc: Include/typeslots.h Objects/typeslots.py - -Include/graminit.h: Grammar/Grammar Parser/acceler.c Parser/grammar1.c Parser/listnode.c Parser/node.c Parser/parser.c Parser/bitset.c Parser/metagrammar.c Parser/firstsets.c Parser/grammar.c Parser/pgen.c Objects/obmalloc.c Python/dynamic_annotations.c Python/mysnprintf.c Python/pyctype.c Parser/tokenizer_pgen.c Parser/printgrammar.c Parser/parsetok_pgen.c Parser/pgenmain.c -Python/graminit.c: Include/graminit.h Grammar/Grammar Parser/acceler.c Parser/grammar1.c Parser/listnode.c Parser/node.c Parser/parser.c Parser/bitset.c Parser/metagrammar.c Parser/firstsets.c Parser/grammar.c Parser/pgen.c Objects/obmalloc.c Python/dynamic_annotations.c Python/mysnprintf.c Python/pyctype.c Parser/tokenizer_pgen.c Parser/printgrammar.c Parser/parsetok_pgen.c Parser/pgenmain.c diff --git a/Doc/library/sysconfig.rst b/Doc/library/sysconfig.rst index 02aaab3cf26f5e..4cbe23966bf1e8 100644 --- a/Doc/library/sysconfig.rst +++ b/Doc/library/sysconfig.rst @@ -255,7 +255,6 @@ You can use :mod:`sysconfig` as a script with Python's *-m* option: AIX_GENUINE_CPLUSPLUS = "0" AR = "ar" ARFLAGS = "rc" - ASDLGEN = "./Parser/asdl_c.py" ... This call will print in the standard output the information returned by diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 573724ddd778d1..4f321352151d56 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -97,7 +97,7 @@ def get_python_inc(plat_specific=0, prefix=None): if plat_specific: return base if _sys_home: - incdir = os.path.join(_sys_home, get_config_var('AST_H_DIR')) + incdir = os.path.join(_sys_home, 'Include') else: incdir = os.path.join(get_config_var('srcdir'), 'Include') return os.path.normpath(incdir) diff --git a/Mac/BuildScript/build-installer.py b/Mac/BuildScript/build-installer.py index c76c4f1a269708..fb112741e05a00 100755 --- a/Mac/BuildScript/build-installer.py +++ b/Mac/BuildScript/build-installer.py @@ -1168,9 +1168,6 @@ def buildPython(): shellQuote(WORKDIR)[1:-1], shellQuote(WORKDIR)[1:-1])) - print("Running make touch") - runCommand("make touch") - print("Running make") runCommand("make") diff --git a/Makefile.pre.in b/Makefile.pre.in index f0450effad0f5a..04ef1a12019c15 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -224,7 +224,7 @@ LIBOBJS= @LIBOBJS@ PYTHON= python$(EXE) BUILDPYTHON= python$(BUILDEXE) -PYTHON_FOR_GEN=@PYTHON_FOR_GEN@ +PYTHON_FOR_REGEN=@PYTHON_FOR_REGEN@ PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@ BUILD_GNU_TYPE= @build@ @@ -271,11 +271,6 @@ IO_OBJS= \ Modules/_io/stringio.o ########################################################################## -# Grammar -GRAMMAR_H= Include/graminit.h -GRAMMAR_C= Python/graminit.c -GRAMMAR_INPUT= $(srcdir)/Grammar/Grammar - LIBFFI_INCLUDEDIR= @LIBFFI_INCLUDEDIR@ @@ -337,38 +332,9 @@ PARSER_HEADERS= \ PGENSRCS= $(PSRCS) $(PGSRCS) PGENOBJS= $(POBJS) $(PGOBJS) -########################################################################## -# opcode.h generation -OPCODE_H_DIR= $(srcdir)/Include -OPCODE_H_SCRIPT= $(srcdir)/Tools/scripts/generate_opcode_h.py -OPCODE_H= $(OPCODE_H_DIR)/opcode.h -OPCODE_H_GEN= $(PYTHON_FOR_GEN) $(OPCODE_H_SCRIPT) $(srcdir)/Lib/opcode.py $(OPCODE_H) -# -########################################################################## -# AST -AST_H_DIR= Include -AST_H= $(AST_H_DIR)/Python-ast.h -AST_C_DIR= Python -AST_C= $(AST_C_DIR)/Python-ast.c -AST_ASDL= $(srcdir)/Parser/Python.asdl - -ASDLGEN_FILES= $(srcdir)/Parser/asdl.py $(srcdir)/Parser/asdl_c.py -# Note that a build now requires Python to exist before the build starts. -# Use "hg touch" to fix up screwed up file mtimes in a checkout. -ASDLGEN= $(PYTHON_FOR_GEN) $(srcdir)/Parser/asdl_c.py - ########################################################################## # Python -OPCODETARGETS_H= \ - Python/opcode_targets.h - -OPCODETARGETGEN= \ - $(srcdir)/Python/makeopcodetargets.py - -OPCODETARGETGEN_FILES= \ - $(OPCODETARGETGEN) $(srcdir)/Lib/opcode.py - PYTHON_OBJS= \ Python/_warnings.o \ Python/Python-ast.o \ @@ -551,7 +517,8 @@ coverage-lcov: @echo "lcov report at $(COVERAGE_REPORT)/index.html" @echo -coverage-report: +# Force regeneration of parser and importlib +coverage-report: regen-grammar regen-importlib : # force rebuilding of parser and importlib @touch $(GRAMMAR_INPUT) @touch $(srcdir)/Lib/importlib/_bootstrap.py @@ -721,14 +688,24 @@ Programs/_freeze_importlib.o: Programs/_freeze_importlib.c Makefile Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) -Python/importlib_external.h: @GENERATED_COMMENT@ $(srcdir)/Lib/importlib/_bootstrap_external.py Programs/_freeze_importlib +.PHONY: regen-importlib +regen-importlib: Programs/_freeze_importlib + # Regenerate Python/importlib_external.h + # from Lib/importlib/_bootstrap_external.py using _freeze_importlib ./Programs/_freeze_importlib \ - $(srcdir)/Lib/importlib/_bootstrap_external.py Python/importlib_external.h - -Python/importlib.h: @GENERATED_COMMENT@ $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib + $(srcdir)/Lib/importlib/_bootstrap_external.py \ + $(srcdir)/Python/importlib_external.h + # Regenerate Python/importlib.h from Lib/importlib/_bootstrap.py + # using _freeze_importlib ./Programs/_freeze_importlib \ - $(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h + $(srcdir)/Lib/importlib/_bootstrap.py \ + $(srcdir)/Python/importlib.h + + +############################################################################ +# Regenerate all generated files +regen-all: regen-opcode regen-opcode-targets regen-typeslots regen-grammar regen-ast regen-importlib ############################################################################ # Special rules for object files @@ -787,15 +764,18 @@ Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile $(IO_OBJS): $(IO_H) -$(GRAMMAR_H): @GENERATED_COMMENT@ $(GRAMMAR_INPUT) $(PGEN) - @$(MKDIR_P) Include - $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) -$(GRAMMAR_C): @GENERATED_COMMENT@ $(GRAMMAR_H) - touch $(GRAMMAR_C) - $(PGEN): $(PGENOBJS) $(CC) $(OPT) $(PY_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN) +.PHONY: regen-grammar +regen-grammar: $(PGEN) + # Regenerate Include/graminit.h and Python/graminit.c + # from Grammar/Grammar using pgen + @$(MKDIR_P) Include + $(PGEN) $(srcdir)/Grammar/Grammar \ + $(srcdir)/Include/graminit.h \ + $(srcdir)/Python/graminit.c + Parser/grammar.o: $(srcdir)/Parser/grammar.c \ $(srcdir)/Include/token.h \ $(srcdir)/Include/grammar.h @@ -807,18 +787,28 @@ Parser/printgrammar.o: $(srcdir)/Parser/printgrammar.c Parser/pgenmain.o: $(srcdir)/Include/parsetok.h -$(AST_H): $(AST_ASDL) $(ASDLGEN_FILES) - $(MKDIR_P) $(AST_H_DIR) - $(ASDLGEN) -h $(AST_H_DIR) $(AST_ASDL) - -$(AST_C): $(AST_H) $(AST_ASDL) $(ASDLGEN_FILES) - $(MKDIR_P) $(AST_C_DIR) - $(ASDLGEN) -c $(AST_C_DIR) $(AST_ASDL) - -$(OPCODE_H): $(srcdir)/Lib/opcode.py $(OPCODE_H_SCRIPT) - $(OPCODE_H_GEN) - -Python/compile.o Python/symtable.o Python/ast.o: $(GRAMMAR_H) $(AST_H) +.PHONY=regen-ast +regen-ast: + # Regenerate Include/Python-ast.h using Parser/asdl_c.py -h + $(MKDIR_P) $(srcdir)/Include + $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \ + -h $(srcdir)/Include \ + $(srcdir)/Parser/Python.asdl + # Regenerate Python/Python-ast.c using Parser/asdl_c.py -c + $(MKDIR_P) $(srcdir)/Python + $(PYTHON_FOR_REGEN) $(srcdir)/Parser/asdl_c.py \ + -c $(srcdir)/Python \ + $(srcdir)/Parser/Python.asdl + +.PHONY: regen-opcode +regen-opcode: + # Regenerate Include/opcode.h from Lib/opcode.py + # using Tools/scripts/generate_opcode_h.py + $(PYTHON_FOR_REGEN) $(srcdir)/Tools/scripts/generate_opcode_h.py \ + $(srcdir)/Lib/opcode.py \ + $(srcdir)/Include/opcode.h + +Python/compile.o Python/symtable.o Python/ast.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h Python/getplatform.o: $(srcdir)/Python/getplatform.c $(CC) -c $(PY_CORE_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c @@ -867,16 +857,26 @@ Objects/unicodeobject.o: $(srcdir)/Objects/unicodeobject.c $(UNICODE_DEPS) Objects/dictobject.o: $(srcdir)/Objects/stringlib/eq.h Objects/setobject.o: $(srcdir)/Objects/stringlib/eq.h -$(OPCODETARGETS_H): $(OPCODETARGETGEN_FILES) - $(PYTHON_FOR_GEN) $(OPCODETARGETGEN) $(OPCODETARGETS_H) +.PHONY: regen-opcode-targets +regen-opcode-targets: + # Regenerate Python/opcode_targets.h from Lib/opcode.py + # using Python/makeopcodetargets.py + $(PYTHON_FOR_REGEN) $(srcdir)/Python/makeopcodetargets.py \ + $(srcdir)/Python/opcode_targets.h -Python/ceval.o: $(OPCODETARGETS_H) $(srcdir)/Python/ceval_gil.h +Python/ceval.o: $(srcdir)/Python/opcode_targets.h $(srcdir)/Python/ceval_gil.h -Python/frozen.o: Python/importlib.h Python/importlib_external.h +Python/frozen.o: $(srcdir)/Python/importlib.h $(srcdir)/Python/importlib_external.h Objects/typeobject.o: Objects/typeslots.inc -Objects/typeslots.inc: $(srcdir)/Include/typeslots.h $(srcdir)/Objects/typeslots.py - $(PYTHON_FOR_GEN) $(srcdir)/Objects/typeslots.py < $(srcdir)/Include/typeslots.h Objects/typeslots.inc + +.PHONY: regen-typeslots +regen-typeslots: + # Regenerate Objects/typeslots.inc from Include/typeslotsh + # using Objects/typeslots.py + $(PYTHON_FOR_REGEN) $(srcdir)/Objects/typeslots.py \ + < $(srcdir)/Include/typeslots.h \ + $(srcdir)/Objects/typeslots.inc ############################################################################ # Header files @@ -929,7 +929,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/node.h \ $(srcdir)/Include/object.h \ $(srcdir)/Include/objimpl.h \ - $(OPCODE_H) \ + $(srcdir)/Include/opcode.h \ $(srcdir)/Include/osdefs.h \ $(srcdir)/Include/patchlevel.h \ $(srcdir)/Include/pgen.h \ @@ -970,7 +970,7 @@ PYTHON_HEADERS= \ $(srcdir)/Include/weakrefobject.h \ pyconfig.h \ $(PARSER_HEADERS) \ - $(AST_H) + $(srcdir)/Include/Python-ast.h $(LIBRARY_OBJS) $(MODOBJS) Programs/python.o: $(PYTHON_HEADERS) @@ -1551,9 +1551,12 @@ recheck: $(SHELL) config.status --recheck $(SHELL) config.status -# Rebuild the configure script from configure.ac; also rebuild pyconfig.h.in +# Regenerate configure and pyconfig.h.in +.PHONY: autoconf autoconf: + # Regenerate the configure script from configure.ac using autoconf (cd $(srcdir); autoconf -Wall) + # Regenerate pyconfig.h.in from configure.ac using autoheader (cd $(srcdir); autoheader -Wall) # Create a tags file for vi @@ -1570,14 +1573,6 @@ TAGS:: etags Include/*.h; \ for i in $(SRCDIRS); do etags -a $$i/*.[ch]; done -# This fixes up the mtimes of checked-in generated files, assuming that they -# only *appear* to be outdated because of checkout order. -# This is run while preparing a source release tarball, and can be run manually -# to avoid bootstrap issues. -touch: - cd $(srcdir); \ - hg --config extensions.touch=Tools/hg/hgtouch.py touch -v - # Sanitation targets -- clean leaves libraries, executables and tags # files, which clobber removes as well pycremoval: @@ -1695,7 +1690,7 @@ Python/thread.o: @THREADHEADERS@ .PHONY: maninstall libinstall inclinstall libainstall sharedinstall .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools -.PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean +.PHONY: frameworkaltinstallunixtools recheck clean clobber distclean .PHONY: smelly funny patchcheck touch altmaninstall commoninstall .PHONY: gdbhooks diff --git a/Misc/NEWS b/Misc/NEWS index 1852d687f7393a..8a42a23989fff6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -203,6 +203,10 @@ Documentation Build ----- +- bpo-23404: Don't regenerate generated files based on file modification time + anymore: the action is now explicit. Replace ``make touch`` with + ``make regen-all``. + - bpo-29643: Fix ``--enable-optimization`` didn't work. Tests diff --git a/Tools/hg/hgtouch.py b/Tools/hg/hgtouch.py deleted file mode 100644 index 119d81214826f6..00000000000000 --- a/Tools/hg/hgtouch.py +++ /dev/null @@ -1,130 +0,0 @@ -"""Bring time stamps of generated checked-in files into the right order - -A versioned configuration file .hgtouch specifies generated files, in the -syntax of make rules. - - output: input1 input2 - -In addition to the dependency syntax, #-comments are supported. -""" -from __future__ import with_statement -import errno -import os -import time - -def parse_config(repo): - try: - fp = repo.wfile(".hgtouch") - except IOError, e: - if e.errno != errno.ENOENT: - raise - return {} - result = {} - with fp: - for line in fp: - # strip comments - line = line.split('#')[0].strip() - if ':' not in line: - continue - outputs, inputs = line.split(':', 1) - outputs = outputs.split() - inputs = inputs.split() - for o in outputs: - try: - result[o].extend(inputs) - except KeyError: - result[o] = inputs - return result - -def check_rule(ui, repo, modified, basedir, output, inputs): - """Verify that the output is newer than any of the inputs. - Return (status, stamp), where status is True if the update succeeded, - and stamp is the newest time stamp assigned to any file (might be in - the future). - - If basedir is nonempty, it gives a directory in which the tree is to - be checked. - """ - f_output = repo.wjoin(os.path.join(basedir, output)) - try: - o_time = os.stat(f_output).st_mtime - except OSError: - ui.warn("Generated file %s does not exist\n" % output) - return False, 0 - youngest = 0 # youngest dependency - backdate = None - backdate_source = None - for i in inputs: - f_i = repo.wjoin(os.path.join(basedir, i)) - try: - i_time = os.stat(f_i).st_mtime - except OSError: - ui.warn(".hgtouch input file %s does not exist\n" % i) - return False, 0 - if i in modified: - # input is modified. Need to backdate at least to i_time - if backdate is None or backdate > i_time: - backdate = i_time - backdate_source = i - continue - youngest = max(i_time, youngest) - if backdate is not None: - ui.warn("Input %s for file %s locally modified\n" % (backdate_source, output)) - # set to 1s before oldest modified input - backdate -= 1 - os.utime(f_output, (backdate, backdate)) - return False, 0 - if youngest >= o_time: - ui.note("Touching %s\n" % output) - youngest += 1 - os.utime(f_output, (youngest, youngest)) - return True, youngest - else: - # Nothing to update - return True, 0 - -def do_touch(ui, repo, basedir): - if basedir: - if not os.path.isdir(repo.wjoin(basedir)): - ui.warn("Abort: basedir %r does not exist\n" % basedir) - return - modified = [] - else: - modified = repo.status()[0] - dependencies = parse_config(repo) - success = True - tstamp = 0 # newest time stamp assigned - # try processing all rules in topological order - hold_back = {} - while dependencies: - output, inputs = dependencies.popitem() - # check whether any of the inputs is generated - for i in inputs: - if i in dependencies: - hold_back[output] = inputs - continue - _success, _tstamp = check_rule(ui, repo, modified, basedir, output, inputs) - success = success and _success - tstamp = max(tstamp, _tstamp) - # put back held back rules - dependencies.update(hold_back) - hold_back = {} - now = time.time() - if tstamp > now: - # wait until real time has passed the newest time stamp, to - # avoid having files dated in the future - time.sleep(tstamp-now) - if hold_back: - ui.warn("Cyclic dependency involving %s\n" % (' '.join(hold_back.keys()))) - return False - return success - -def touch(ui, repo, basedir): - "touch generated files that are older than their sources after an update." - do_touch(ui, repo, basedir) - -cmdtable = { - "touch": (touch, - [('b', 'basedir', '', 'base dir of the tree to apply touching')], - "hg touch [-b BASEDIR]") -} diff --git a/configure b/configure index a6d83f266008c9..2091da7fb1bd51 100755 --- a/configure +++ b/configure @@ -747,9 +747,8 @@ UNIVERSALSDK CONFIG_ARGS SOVERSION VERSION -GENERATED_COMMENT PYTHON_FOR_BUILD -PYTHON_FOR_GEN +PYTHON_FOR_REGEN host_os host_vendor host_cpu @@ -3010,11 +3009,11 @@ do set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_PYTHON_FOR_GEN+:} false; then : +if ${ac_cv_prog_PYTHON_FOR_REGEN+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$PYTHON_FOR_GEN"; then - ac_cv_prog_PYTHON_FOR_GEN="$PYTHON_FOR_GEN" # Let the user override the test. + if test -n "$PYTHON_FOR_REGEN"; then + ac_cv_prog_PYTHON_FOR_REGEN="$PYTHON_FOR_REGEN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -3023,7 +3022,7 @@ do test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_PYTHON_FOR_GEN="$ac_prog" + ac_cv_prog_PYTHON_FOR_REGEN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3033,25 +3032,20 @@ IFS=$as_save_IFS fi fi -PYTHON_FOR_GEN=$ac_cv_prog_PYTHON_FOR_GEN -if test -n "$PYTHON_FOR_GEN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_GEN" >&5 -$as_echo "$PYTHON_FOR_GEN" >&6; } +PYTHON_FOR_REGEN=$ac_cv_prog_PYTHON_FOR_REGEN +if test -n "$PYTHON_FOR_REGEN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_FOR_REGEN" >&5 +$as_echo "$PYTHON_FOR_REGEN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - test -n "$PYTHON_FOR_GEN" && break + test -n "$PYTHON_FOR_REGEN" && break done -test -n "$PYTHON_FOR_GEN" || PYTHON_FOR_GEN="not-found" +test -n "$PYTHON_FOR_REGEN" || PYTHON_FOR_REGEN="python3" -if test "$PYTHON_FOR_GEN" = not-found; then - PYTHON_FOR_GEN='@echo "Cannot generate $@, python not found !" && \ - echo "To skip re-generation of $@ run or ." && \ - echo "Otherwise, set python in PATH and run configure or run ." && false &&' -fi if test "$cross_compiling" = yes; then @@ -3072,18 +3066,14 @@ $as_echo_n "checking for python interpreter for cross build... " >&6; } $as_echo "$interp" >&6; } PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib:$(srcdir)/Lib/$(PLATDIR) '$interp fi - # Used to comment out stuff for rebuilding generated files - GENERATED_COMMENT='#' elif test "$cross_compiling" = maybe; then as_fn_error $? "Cross compiling required --host=HOST-TUPLE and --build=ARCH" "$LINENO" 5 else PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' - GENERATED_COMMENT='' fi - if test "$prefix" != "/"; then prefix=`echo "$prefix" | sed -e 's/\/$//g'` fi diff --git a/configure.ac b/configure.ac index 22ac805a66a3f6..e1731dbc222078 100644 --- a/configure.ac +++ b/configure.ac @@ -56,13 +56,8 @@ AC_SUBST(host) # pybuilddir.txt will be created by --generate-posix-vars in the Makefile rm -f pybuilddir.txt -AC_CHECK_PROGS(PYTHON_FOR_GEN, python$PACKAGE_VERSION python3 python, not-found) -if test "$PYTHON_FOR_GEN" = not-found; then - PYTHON_FOR_GEN='@echo "Cannot generate $@, python not found !" && \ - echo "To skip re-generation of $@ run or ." && \ - echo "Otherwise, set python in PATH and run configure or run ." && false &&' -fi -AC_SUBST(PYTHON_FOR_GEN) +AC_CHECK_PROGS(PYTHON_FOR_REGEN, python$PACKAGE_VERSION python3 python, python3) +AC_SUBST(PYTHON_FOR_REGEN) if test "$cross_compiling" = yes; then AC_MSG_CHECKING([for python interpreter for cross build]) @@ -80,16 +75,12 @@ if test "$cross_compiling" = yes; then AC_MSG_RESULT($interp) PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib:$(srcdir)/Lib/$(PLATDIR) '$interp fi - # Used to comment out stuff for rebuilding generated files - GENERATED_COMMENT='#' elif test "$cross_compiling" = maybe; then AC_MSG_ERROR([Cross compiling required --host=HOST-TUPLE and --build=ARCH]) else PYTHON_FOR_BUILD='./$(BUILDPYTHON) -E' - GENERATED_COMMENT='' fi AC_SUBST(PYTHON_FOR_BUILD) -AC_SUBST(GENERATED_COMMENT) dnl Ensure that if prefix is specified, it does not end in a slash. If dnl it does, we get path names containing '//' which is both ugly and From ee2294860e224c2b08cc6847d3c9a0ec3875c3d8 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 5 May 2017 10:40:47 +0300 Subject: [PATCH 192/340] [3.5] bpo-30243: Fixed the possibility of a crash in _json. (GH-1420) (#1470) It was possible to get a core dump by using uninitialized _json objects. Now __new__ methods create initialized objects. __init__ methods are removed.. (cherry picked from commit 76a3e51a403bc84ed536921866c86dd7d07aaa7e) --- Misc/NEWS | 4 +++ Modules/_json.c | 86 ++++++++++++------------------------------------- 2 files changed, 24 insertions(+), 66 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index 8a42a23989fff6..8ea2fd3c88ccdc 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,10 @@ Extension Modules Library ------- +- bpo-30243: Removed the __init__ methods of _json's scanner and encoder. + Misusing them could cause memory leaks or crashes. Now scanner and encoder + objects are completely initialized in the __new__ methods. + - bpo-30185: Avoid KeyboardInterrupt tracebacks in forkserver helper process when Ctrl-C is received. diff --git a/Modules/_json.c b/Modules/_json.c index 8cbf2e405869e0..446795e2299a72 100644 --- a/Modules/_json.c +++ b/Modules/_json.c @@ -89,16 +89,12 @@ static PyObject * _build_rval_index_tuple(PyObject *rval, Py_ssize_t idx); static PyObject * scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static int -scanner_init(PyObject *self, PyObject *args, PyObject *kwds); static void scanner_dealloc(PyObject *self); static int scanner_clear(PyObject *self); static PyObject * encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds); -static int -encoder_init(PyObject *self, PyObject *args, PyObject *kwds); static void encoder_dealloc(PyObject *self); static int @@ -1203,38 +1199,21 @@ static PyObject * scanner_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyScannerObject *s; - s = (PyScannerObject *)type->tp_alloc(type, 0); - if (s != NULL) { - s->strict = NULL; - s->object_hook = NULL; - s->object_pairs_hook = NULL; - s->parse_float = NULL; - s->parse_int = NULL; - s->parse_constant = NULL; - } - return (PyObject *)s; -} - -static int -scanner_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - /* Initialize Scanner object */ PyObject *ctx; static char *kwlist[] = {"context", NULL}; - PyScannerObject *s; - - assert(PyScanner_Check(self)); - s = (PyScannerObject *)self; if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx)) - return -1; + return NULL; - if (s->memo == NULL) { - s->memo = PyDict_New(); - if (s->memo == NULL) - goto bail; + s = (PyScannerObject *)type->tp_alloc(type, 0); + if (s == NULL) { + return NULL; } + s->memo = PyDict_New(); + if (s->memo == NULL) + goto bail; + /* All of these will fail "gracefully" so we don't need to verify them */ s->strict = PyObject_GetAttrString(ctx, "strict"); if (s->strict == NULL) @@ -1255,16 +1234,11 @@ scanner_init(PyObject *self, PyObject *args, PyObject *kwds) if (s->parse_constant == NULL) goto bail; - return 0; + return (PyObject *)s; bail: - Py_CLEAR(s->strict); - Py_CLEAR(s->object_hook); - Py_CLEAR(s->object_pairs_hook); - Py_CLEAR(s->parse_float); - Py_CLEAR(s->parse_int); - Py_CLEAR(s->parse_constant); - return -1; + Py_DECREF(s); + return NULL; } PyDoc_STRVAR(scanner_doc, "JSON scanner object"); @@ -1306,7 +1280,7 @@ PyTypeObject PyScannerType = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - scanner_init, /* tp_init */ + 0, /* tp_init */ 0,/* PyType_GenericAlloc, */ /* tp_alloc */ scanner_new, /* tp_new */ 0,/* PyObject_GC_Del, */ /* tp_free */ @@ -1315,25 +1289,6 @@ PyTypeObject PyScannerType = { static PyObject * encoder_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyEncoderObject *s; - s = (PyEncoderObject *)type->tp_alloc(type, 0); - if (s != NULL) { - s->markers = NULL; - s->defaultfn = NULL; - s->encoder = NULL; - s->indent = NULL; - s->key_separator = NULL; - s->item_separator = NULL; - s->sort_keys = NULL; - s->skipkeys = NULL; - } - return (PyObject *)s; -} - -static int -encoder_init(PyObject *self, PyObject *args, PyObject *kwds) -{ - /* initialize Encoder object */ static char *kwlist[] = {"markers", "default", "encoder", "indent", "key_separator", "item_separator", "sort_keys", "skipkeys", "allow_nan", NULL}; PyEncoderObject *s; @@ -1341,22 +1296,23 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) PyObject *item_separator, *sort_keys, *skipkeys; int allow_nan; - assert(PyEncoder_Check(self)); - s = (PyEncoderObject *)self; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOOOUUOOp:make_encoder", kwlist, &markers, &defaultfn, &encoder, &indent, &key_separator, &item_separator, &sort_keys, &skipkeys, &allow_nan)) - return -1; + return NULL; if (markers != Py_None && !PyDict_Check(markers)) { PyErr_Format(PyExc_TypeError, "make_encoder() argument 1 must be dict or None, " "not %.200s", Py_TYPE(markers)->tp_name); - return -1; + return NULL; } + s = (PyEncoderObject *)type->tp_alloc(type, 0); + if (s == NULL) + return NULL; + s->markers = markers; s->defaultfn = defaultfn; s->encoder = encoder; @@ -1383,7 +1339,7 @@ encoder_init(PyObject *self, PyObject *args, PyObject *kwds) Py_INCREF(s->item_separator); Py_INCREF(s->sort_keys); Py_INCREF(s->skipkeys); - return 0; + return (PyObject *)s; } static PyObject * @@ -1914,7 +1870,7 @@ PyTypeObject PyEncoderType = { 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - encoder_init, /* tp_init */ + 0, /* tp_init */ 0, /* tp_alloc */ encoder_new, /* tp_new */ 0, /* tp_free */ @@ -1957,10 +1913,8 @@ PyInit__json(void) PyObject *m = PyModule_Create(&jsonmodule); if (!m) return NULL; - PyScannerType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyScannerType) < 0) goto fail; - PyEncoderType.tp_new = PyType_GenericNew; if (PyType_Ready(&PyEncoderType) < 0) goto fail; Py_INCREF((PyObject*)&PyScannerType); From 0c9aa6ffd318c04ce23997b4704477d4a4d82829 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 5 May 2017 10:08:05 +0200 Subject: [PATCH 193/340] bpo-30264: ExpatParser closes the source on error (#1451) (#1475) ExpatParser.parse() of xml.sax.xmlreader now always closes the source: close the file object or the urllib object if source is a string (not an open file-like object). The change fixes a ResourceWarning on parsing error. Add test_parse_close_source() unit test. (cherry picked from commit ef9c0e732fc50aefbdd7c5a80e04e14b31684e66) --- Lib/test/test_sax.py | 24 ++++++++++++++++++------ Lib/xml/sax/expatreader.py | 33 ++++++++++++++++++++++----------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_sax.py b/Lib/test/test_sax.py index 2411895d9d12b1..2eb62905ffa882 100644 --- a/Lib/test/test_sax.py +++ b/Lib/test/test_sax.py @@ -4,6 +4,7 @@ from xml.sax import make_parser, ContentHandler, \ SAXException, SAXReaderNotAvailable, SAXParseException import unittest +from unittest import mock try: make_parser() except SAXReaderNotAvailable: @@ -175,12 +176,8 @@ def test_parse_bytes(self): with self.assertRaises(SAXException): self.check_parse(BytesIO(xml_bytes(self.data, 'iso-8859-1', None))) make_xml_file(self.data, 'iso-8859-1', None) - with support.check_warnings(('unclosed file', ResourceWarning)): - # XXX Failed parser leaks an opened file. - with self.assertRaises(SAXException): - self.check_parse(TESTFN) - # Collect leaked file. - gc.collect() + with self.assertRaises(SAXException): + self.check_parse(TESTFN) with open(TESTFN, 'rb') as f: with self.assertRaises(SAXException): self.check_parse(f) @@ -194,6 +191,21 @@ def test_parse_InputSource(self): input.setEncoding('iso-8859-1') self.check_parse(input) + def test_parse_close_source(self): + builtin_open = open + fileobj = None + + def mock_open(*args): + nonlocal fileobj + fileobj = builtin_open(*args) + return fileobj + + with mock.patch('xml.sax.saxutils.open', side_effect=mock_open): + make_xml_file(self.data, 'iso-8859-1', None) + with self.assertRaises(SAXException): + self.check_parse(TESTFN) + self.assertTrue(fileobj.closed) + def check_parseString(self, s): from xml.sax import parseString result = StringIO() diff --git a/Lib/xml/sax/expatreader.py b/Lib/xml/sax/expatreader.py index 98b5ca953983c7..421358fa5bc7f0 100644 --- a/Lib/xml/sax/expatreader.py +++ b/Lib/xml/sax/expatreader.py @@ -105,9 +105,16 @@ def parse(self, source): source = saxutils.prepare_input_source(source) self._source = source - self.reset() - self._cont_handler.setDocumentLocator(ExpatLocator(self)) - xmlreader.IncrementalParser.parse(self, source) + try: + self.reset() + self._cont_handler.setDocumentLocator(ExpatLocator(self)) + xmlreader.IncrementalParser.parse(self, source) + except: + # bpo-30264: Close the source on error to not leak resources: + # xml.sax.parse() doesn't give access to the underlying parser + # to the caller + self._close_source() + raise def prepareParser(self, source): if source.getSystemId() is not None: @@ -213,6 +220,17 @@ def feed(self, data, isFinal = 0): # FIXME: when to invoke error()? self._err_handler.fatalError(exc) + def _close_source(self): + source = self._source + try: + file = source.getCharacterStream() + if file is not None: + file.close() + finally: + file = source.getByteStream() + if file is not None: + file.close() + def close(self): if (self._entity_stack or self._parser is None or isinstance(self._parser, _ClosedParser)): @@ -232,14 +250,7 @@ def close(self): parser.ErrorColumnNumber = self._parser.ErrorColumnNumber parser.ErrorLineNumber = self._parser.ErrorLineNumber self._parser = parser - try: - file = self._source.getCharacterStream() - if file is not None: - file.close() - finally: - file = self._source.getByteStream() - if file is not None: - file.close() + self._close_source() def _reset_cont_handler(self): self._parser.ProcessingInstructionHandler = \ From c8faabce6ef318f3b425c6defd846e274d61e2ef Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 6 May 2017 15:11:20 +0300 Subject: [PATCH 194/340] [3.5] Revert bpo-26293 for zipfile breakage. See also bpo-29094. (GH-1484). (#1486) (cherry picked from commit 3763ea865cee5bbabcce11cd577811135e0fc747) --- Lib/zipfile.py | 27 +++++++++++++-------------- Misc/NEWS | 2 ++ 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 048f60a708e092..56a2479fb3850a 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1028,7 +1028,6 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True - self._start_disk = 0 try: self.start_dir = self.fp.tell() except (AttributeError, OSError): @@ -1054,7 +1053,7 @@ def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True): # set the modified flag so central directory gets written # even if no files are added to the archive self._didModify = True - self.start_dir = self._start_disk = self.fp.tell() + self.start_dir = self.fp.tell() else: raise RuntimeError("Mode must be 'r', 'w', 'x', or 'a'") except: @@ -1098,18 +1097,17 @@ def _RealGetContents(self): offset_cd = endrec[_ECD_OFFSET] # offset of central directory self._comment = endrec[_ECD_COMMENT] # archive comment - # self._start_disk: Position of the start of ZIP archive - # It is zero, unless ZIP was concatenated to another file - self._start_disk = endrec[_ECD_LOCATION] - size_cd - offset_cd + # "concat" is zero, unless zip was concatenated to another file + concat = endrec[_ECD_LOCATION] - size_cd - offset_cd if endrec[_ECD_SIGNATURE] == stringEndArchive64: # If Zip64 extension structures are present, account for them - self._start_disk -= (sizeEndCentDir64 + sizeEndCentDir64Locator) + concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator) if self.debug > 2: - inferred = self._start_disk + offset_cd - print("given, inferred, offset", offset_cd, inferred, self._start_disk) + inferred = concat + offset_cd + print("given, inferred, offset", offset_cd, inferred, concat) # self.start_dir: Position of start of central directory - self.start_dir = offset_cd + self._start_disk + self.start_dir = offset_cd + concat fp.seek(self.start_dir, 0) data = fp.read(size_cd) fp = io.BytesIO(data) @@ -1149,7 +1147,7 @@ def _RealGetContents(self): t>>11, (t>>5)&0x3F, (t&0x1F) * 2 ) x._decodeExtra() - x.header_offset = x.header_offset + self._start_disk + x.header_offset = x.header_offset + concat self.filelist.append(x) self.NameToInfo[x.filename] = x @@ -1629,10 +1627,11 @@ def _write_end_record(self): file_size = zinfo.file_size compress_size = zinfo.compress_size - header_offset = zinfo.header_offset - self._start_disk - if header_offset > ZIP64_LIMIT: - extra.append(header_offset) + if zinfo.header_offset > ZIP64_LIMIT: + extra.append(zinfo.header_offset) header_offset = 0xffffffff + else: + header_offset = zinfo.header_offset extra_data = zinfo.extra min_version = 0 @@ -1679,7 +1678,7 @@ def _write_end_record(self): # Write end-of-zip-archive record centDirCount = len(self.filelist) centDirSize = pos2 - self.start_dir - centDirOffset = self.start_dir - self._start_disk + centDirOffset = self.start_dir requires_zip64 = None if centDirCount > ZIP_FILECOUNT_LIMIT: requires_zip64 = "Files count" diff --git a/Misc/NEWS b/Misc/NEWS index 8ea2fd3c88ccdc..1ec6a097604887 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Extension Modules Library ------- +- Revert bpo-26293 for zipfile breakage. See also bpo-29094. + - bpo-30243: Removed the __init__ methods of _json's scanner and encoder. Misusing them could cause memory leaks or crashes. Now scanner and encoder objects are completely initialized in the __new__ methods. From f5f7870d9322b46ab87c45b2c4c46f6b10ecbd70 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Tue, 9 May 2017 12:17:09 +0800 Subject: [PATCH 195/340] bpo-29990: Fix range checking in GB18030 decoder (#1495) (#1508) When decoding a 4-byte GB18030 sequence, the first and third byte cannot exceed 0xFE. --- Lib/test/test_codecencodings_cn.py | 6 ++++++ Misc/NEWS | 2 ++ Modules/cjkcodecs/_codecs_cn.c | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py index d0e3a15d162370..f135bb26e7b044 100644 --- a/Lib/test/test_codecencodings_cn.py +++ b/Lib/test/test_codecencodings_cn.py @@ -49,6 +49,12 @@ class Test_GB18030(multibytecodec_support.TestBase, unittest.TestCase): (b"abc\x84\x32\x80\x80def", "replace", 'abc\ufffd2\ufffd\ufffddef'), (b"abc\x81\x30\x81\x30def", "strict", 'abc\x80def'), (b"abc\x86\x30\x81\x30def", "replace", 'abc\ufffd0\ufffd0def'), + # issue29990 + (b"\xff\x30\x81\x30", "strict", None), + (b"\x81\x30\xff\x30", "strict", None), + (b"abc\x81\x39\xff\x39\xc1\xc4", "replace", "abc\ufffd\x39\ufffd\x39\u804a"), + (b"abc\xab\x36\xff\x30def", "replace", 'abc\ufffd\x36\ufffd\x30def'), + (b"abc\xbf\x38\xff\x32\xc1\xc4", "ignore", "abc\x38\x32\u804a"), ) has_iso10646 = True diff --git a/Misc/NEWS b/Misc/NEWS index 1ec6a097604887..06e464ffc89d80 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Extension Modules Library ------- +- bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma Lin. + - Revert bpo-26293 for zipfile breakage. See also bpo-29094. - bpo-30243: Removed the __init__ methods of _json's scanner and encoder. diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index 1a070f2f393219..bda175c55d1323 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -279,7 +279,9 @@ DECODER(gb18030) REQUIRE_INBUF(4); c3 = INBYTE3; c4 = INBYTE4; - if (c < 0x81 || c3 < 0x81 || c4 < 0x30 || c4 > 0x39) + if (c < 0x81 || c > 0xFE || + c3 < 0x81 || c3 > 0xFE || + c4 < 0x30 || c4 > 0x39) return 1; c -= 0x81; c2 -= 0x30; c3 -= 0x81; c4 -= 0x30; From 8489409bbfabb2ddc30ed55c9f4d679a3710ebe4 Mon Sep 17 00:00:00 2001 From: torsava Date: Tue, 9 May 2017 17:12:35 +0200 Subject: [PATCH 196/340] [3.5] bpo-29243: Fix Makefile with respect to --enable-optimizations (GH-1478) (#1520) * bpo-29243: Fix Makefile with respect to --enable-optimizations When using the Profile Guided Optimization (./configure --enable-optimizations) Python is built not only during `make` but rebuilt again during `make test`, `make install` and others. This patch fixes the issue. Note that this fix produces no change at all in the Makefile if configure is run witout --enable-optimizations. * !squash. (cherry picked from commit a1054c3b0037d4c2a5492e79fc193f36245366c7) --- Makefile.pre.in | 14 +++++++------- Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in index 04ef1a12019c15..144c1f8629bcd5 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -984,7 +984,7 @@ TESTTIMEOUT= 3600 # Run a basic set of regression tests. # This excludes some tests that are particularly resource-intensive. -test: all platform +test: @DEF_MAKE_RULE@ platform $(TESTRUNNER) $(TESTOPTS) # Run the full test suite twice - once without .pyc files, and once with. @@ -994,7 +994,7 @@ test: all platform # the bytecode read from a .pyc file had the bug, sometimes the directly # generated bytecode. This is sometimes a very shy bug needing a lot of # sample data. -testall: all platform +testall: @DEF_MAKE_RULE@ platform -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f $(TESTPYTHON) -E $(srcdir)/Lib/compileall.py -find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f @@ -1003,7 +1003,7 @@ testall: all platform # Run the test suite for both architectures in a Universal build on OSX. # Must be run on an Intel box. -testuniversal: all platform +testuniversal: @DEF_MAKE_RULE@ platform if [ `arch` != 'i386' ];then \ echo "This can only be used on OSX/i386" ;\ exit 1 ;\ @@ -1026,7 +1026,7 @@ QUICKTESTOPTS= $(TESTOPTS) -x test_subprocess test_io test_lib2to3 \ test_multiprocessing_forkserver \ test_mailbox test_socket test_poll \ test_select test_zipfile test_concurrent_futures -quicktest: all platform +quicktest: @DEF_MAKE_RULE@ platform $(TESTRUNNER) $(QUICKTESTOPTS) @@ -1378,7 +1378,7 @@ LIBPL= @LIBPL@ # pkgconfig directory LIBPC= $(LIBDIR)/pkgconfig -libainstall: all python-config +libainstall: @DEF_MAKE_RULE@ python-config @for i in $(LIBDIR) $(LIBPL) $(LIBPC); \ do \ if test ! -d $(DESTDIR)$$i; then \ @@ -1639,7 +1639,7 @@ distclean: clobber -exec rm -f {} ';' # Check for smelly exported symbols (not starting with Py/_Py) -smelly: all +smelly: @DEF_MAKE_RULE@ nm -p $(LIBRARY) | \ sed -n "/ [TDB] /s/.* //p" | grep -v "^_*Py" | sort -u; \ @@ -1677,7 +1677,7 @@ funny: -o -print # Perform some verification checks on any modified files. -patchcheck: all +patchcheck: @DEF_MAKE_RULE@ $(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py # Dependencies diff --git a/Misc/ACKS b/Misc/ACKS index babd4950da6797..2d2436c9c3b8c1 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1096,6 +1096,7 @@ Jason Orendorff Douglas Orr William Orr Michele Orrù +Tomáš Orsava Oleg Oshmyan Denis S. Otkidach Peter Otten diff --git a/Misc/NEWS b/Misc/NEWS index 06e464ffc89d80..889386dba05de4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -211,6 +211,10 @@ Documentation Build ----- +- bpo-29243: Prevent unnecessary rebuilding of Python during ``make test``, + ``make install`` and some other make targets when configured with + ``--enable-optimizations``. + - bpo-23404: Don't regenerate generated files based on file modification time anymore: the action is now explicit. Replace ``make touch`` with ``make regen-all``. From 9721729952d5844505fda01efd1c4149acb59220 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 10 May 2017 02:38:09 +0200 Subject: [PATCH 197/340] test_eintr: less verbose, the test is now stable (#1521) Backport the change from the master branch. --- Lib/test/test_eintr.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_eintr.py b/Lib/test/test_eintr.py index aabad835a0a802..25f86d31de3548 100644 --- a/Lib/test/test_eintr.py +++ b/Lib/test/test_eintr.py @@ -1,7 +1,5 @@ import os import signal -import subprocess -import sys import unittest from test import support @@ -16,14 +14,8 @@ def test_all(self): # Run the tester in a sub-process, to make sure there is only one # thread (for reliable signal delivery). tester = support.findfile("eintr_tester.py", subdir="eintrdata") - - if support.verbose: - args = [sys.executable, tester] - with subprocess.Popen(args) as proc: - exitcode = proc.wait() - self.assertEqual(exitcode, 0) - else: - script_helper.assert_python_ok(tester) + # use -u to try to get the full output if the test hangs or crash + script_helper.assert_python_ok("-u", tester) if __name__ == "__main__": From 639e295650a51894412c9d976958792010d3bcf8 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Wed, 10 May 2017 19:11:09 +0800 Subject: [PATCH 198/340] =?UTF-8?q?bpo-30281:=20Fix=20the=20default=20valu?= =?UTF-8?q?e=20for=20stop=20in=20PySlice=5FUnpack()=20(#1530)=20(#1480?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Objects/sliceobject.c | 8 +++++--- Python/ceval.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 6a690213d14518..32599476bba0c0 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -197,6 +197,8 @@ PySlice_Unpack(PyObject *_r, PySliceObject *r = (PySliceObject*)_r; /* this is harder to get right than you might think */ + assert(PY_SSIZE_T_MIN + 1 <= -PY_SSIZE_T_MAX); + if (r->step == Py_None) { *step = 1; } @@ -217,14 +219,14 @@ PySlice_Unpack(PyObject *_r, } if (r->start == Py_None) { - *start = *step < 0 ? PY_SSIZE_T_MAX-1 : 0;; + *start = *step < 0 ? PY_SSIZE_T_MAX : 0; } else { if (!_PyEval_SliceIndex(r->start, start)) return -1; } if (r->stop == Py_None) { - *stop = *step < 0 ? -PY_SSIZE_T_MAX : PY_SSIZE_T_MAX; + *stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX; } else { if (!_PyEval_SliceIndex(r->stop, stop)) return -1; @@ -258,7 +260,7 @@ PySlice_AdjustIndices(Py_ssize_t length, *stop = (step < 0) ? -1 : 0; } } - else if (*stop >= length) { + else if (*stop >= length) { *stop = (step < 0) ? length - 1 : length; } diff --git a/Python/ceval.c b/Python/ceval.c index 3070a90b43dbfb..47c5eff64f235e 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -5095,7 +5095,7 @@ ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) /* Extract a slice index from a PyLong or an object with the nb_index slot defined, and store in *pi. Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX, - and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1. + and silently boost values less than PY_SSIZE_T_MIN to PY_SSIZE_T_MIN. Return 0 on error, 1 on success. */ int From dab10f4f5b52c6de1aac3a8b5dc87d2eb0223a6c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 10 May 2017 14:13:37 +0200 Subject: [PATCH 199/340] [3.5] bpo-30320, bpo-25277: backport test_eintr enhancements from master to 3.5 (#1532) * bpo-30320: test_eintr now uses pthread_sigmask() (#1523) Rewrite sigwaitinfo() and sigtimedwait() unit tests for EINTR using pthread_sigmask() to fix a race condition between the child and the parent process. Remove the pipe which was used as a weak workaround against the race condition. sigtimedwait() is now tested with a child process sending a signal instead of testing the timeout feature which is more unstable (especially regarding to clock resolution depending on the platform). (cherry picked from commit 211a392cc15f9a7b1b8ce65d8f6c9f8237d1b77f) * test_eintr: Fix ResourceWarning warnings (cherry picked from commit c50cccfcc3b3a9ef3fe7a78b7e7271930dc24aee) * test_eintr: remove unused import * bpo-25277: Add a watchdog to test_eintr Set a timeout of 10 minutes in test_eintr using faulthandler. --- Lib/test/eintrdata/eintr_tester.py | 69 ++++++++++++++++-------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py index 81b6277a0401ff..ad68bd799fa7cb 100644 --- a/Lib/test/eintrdata/eintr_tester.py +++ b/Lib/test/eintrdata/eintr_tester.py @@ -9,7 +9,7 @@ """ import contextlib -import io +import faulthandler import os import select import signal @@ -50,6 +50,10 @@ def setUpClass(cls): signal.setitimer(signal.ITIMER_REAL, cls.signal_delay, cls.signal_period) + # Issue #25277: Use faulthandler to try to debug a hang on FreeBSD + if hasattr(faulthandler, 'dump_traceback_later'): + faulthandler.dump_traceback_later(10 * 60, exit=True) + @classmethod def stop_alarm(cls): signal.setitimer(signal.ITIMER_REAL, 0, 0) @@ -58,6 +62,8 @@ def stop_alarm(cls): def tearDownClass(cls): cls.stop_alarm() signal.signal(signal.SIGALRM, cls.orig_handler) + if hasattr(faulthandler, 'cancel_dump_traceback_later'): + faulthandler.cancel_dump_traceback_later() def subprocess(self, *args, **kw): cmd_args = (sys.executable, '-c') + args @@ -77,6 +83,9 @@ def _test_wait_multiple(self, wait_func): processes = [self.new_sleep_process() for _ in range(num)] for _ in range(num): wait_func() + # Call the Popen method to avoid a ResourceWarning + for proc in processes: + proc.wait() def test_wait(self): self._test_wait_multiple(os.wait) @@ -88,6 +97,8 @@ def test_wait3(self): def _test_wait_single(self, wait_func): proc = self.new_sleep_process() wait_func(proc.pid) + # Call the Popen method to avoid a ResourceWarning + proc.wait() def test_waitpid(self): self._test_wait_single(lambda pid: os.waitpid(pid, 0)) @@ -358,59 +369,55 @@ def test_sleep(self): @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") +# bpo-30320: Need pthread_sigmask() to block the signal, otherwise the test +# is vulnerable to a race condition between the child and the parent processes. +@unittest.skipUnless(hasattr(signal, 'pthread_sigmask'), + 'need signal.pthread_sigmask()') class SignalEINTRTest(EINTRBaseTest): """ EINTR tests for the signal module. """ - @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), - 'need signal.sigtimedwait()') - def test_sigtimedwait(self): - t0 = time.monotonic() - signal.sigtimedwait([signal.SIGUSR1], self.sleep_time) - dt = time.monotonic() - t0 - self.assertGreaterEqual(dt, self.sleep_time) - - @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), - 'need signal.sigwaitinfo()') - def test_sigwaitinfo(self): - # Issue #25277, #25868: give a few milliseconds to the parent process - # between os.write() and signal.sigwaitinfo() to works around a race - # condition - self.sleep_time = 0.100 - + def check_sigwait(self, wait_func): signum = signal.SIGUSR1 pid = os.getpid() old_handler = signal.signal(signum, lambda *args: None) self.addCleanup(signal.signal, signum, old_handler) - rpipe, wpipe = os.pipe() - code = '\n'.join(( 'import os, time', 'pid = %s' % os.getpid(), 'signum = %s' % int(signum), 'sleep_time = %r' % self.sleep_time, - 'rpipe = %r' % rpipe, - 'os.read(rpipe, 1)', - 'os.close(rpipe)', 'time.sleep(sleep_time)', 'os.kill(pid, signum)', )) + old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, [signum]) + self.addCleanup(signal.pthread_sigmask, signal.SIG_UNBLOCK, [signum]) + t0 = time.monotonic() - proc = self.subprocess(code, pass_fds=(rpipe,)) - os.close(rpipe) + proc = self.subprocess(code) with kill_on_error(proc): - # sync child-parent - os.write(wpipe, b'x') - os.close(wpipe) + wait_func(signum) + dt = time.monotonic() - t0 + + self.assertEqual(proc.wait(), 0) - # parent + @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'), + 'need signal.sigwaitinfo()') + def test_sigwaitinfo(self): + def wait_func(signum): signal.sigwaitinfo([signum]) - dt = time.monotonic() - t0 - self.assertEqual(proc.wait(), 0) - self.assertGreaterEqual(dt, self.sleep_time) + self.check_sigwait(wait_func) + + @unittest.skipUnless(hasattr(signal, 'sigtimedwait'), + 'need signal.sigwaitinfo()') + def test_sigtimedwait(self): + def wait_func(signum): + signal.sigtimedwait([signum], 120.0) + + self.check_sigwait(wait_func) @unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()") From 5e94dedcddf5e09164bf20f18a3c701eeb96c71e Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Fri, 12 May 2017 14:34:40 +0900 Subject: [PATCH 200/340] bpo-30048: asyncio: fix Task.cancel() was ignored. (GH-1547) * bpo-30048: asyncio: fix Task.cancel() was ignored. (GH-1097) when there are no more `await` or `yield (from)` before return in coroutine, cancel was ignored. example: async def coro(): asyncio.Task.current_task().cancel() return 42 ... res = await coro() # should raise CancelledError (cherry picked from commit 991adca012f5e106c2d4040ce619c696ba6f9c46) * fix test --- Lib/asyncio/tasks.py | 7 ++++++- Lib/test/test_asyncio/test_tasks.py | 18 ++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index b6bd53cef1aa41..89d0989c614a56 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -240,7 +240,12 @@ def _step(self, exc=None): else: result = coro.throw(exc) except StopIteration as exc: - self.set_result(exc.value) + if self._must_cancel: + # Task is cancelled right before coro stops. + self._must_cancel = False + self.set_exception(futures.CancelledError()) + else: + self.set_result(exc.value) except futures.CancelledError: super().cancel() # I.e., Future.cancel(self). except Exception as exc: diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 9872926739f01c..b3d0653e82e573 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -573,6 +573,24 @@ def task(): self.assertFalse(t._must_cancel) # White-box test. self.assertFalse(t.cancel()) + def test_cancel_at_end(self): + """coroutine end right after task is cancelled""" + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + + @asyncio.coroutine + def task(): + t.cancel() + self.assertTrue(t._must_cancel) # White-box test. + return 12 + + t = asyncio.Task(task(), loop=loop) + self.assertRaises( + asyncio.CancelledError, loop.run_until_complete, t) + self.assertTrue(t.done()) + self.assertFalse(t._must_cancel) # White-box test. + self.assertFalse(t.cancel()) + def test_stop_while_run_in_complete(self): def gen(): diff --git a/Misc/NEWS b/Misc/NEWS index 889386dba05de4..41fe80f44c3f12 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Extension Modules Library ------- +- bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is + running coroutine and the coroutine returned without any more ``await``. + - bpo-29990: Fix range checking in GB18030 decoder. Original patch by Ma Lin. - Revert bpo-26293 for zipfile breakage. See also bpo-29094. From 4ee34e144f6c8263edaf5951d4fd80562a02361d Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 13 May 2017 09:45:14 -0700 Subject: [PATCH 201/340] [3.5] bpo-30178: Indent methods and attributes of MimeType class (GH-1306) (#1571) (cherry picked from commit c71168090df435c1eb8c03005b11df764cd7ebd6) --- Doc/library/mimetypes.rst | 86 +++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 464248c3ea7990..67b7a7178534d3 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -186,78 +186,78 @@ than one MIME-type database; it provides an interface similar to the one of the loaded "on top" of the default database. -.. attribute:: MimeTypes.suffix_map + .. attribute:: MimeTypes.suffix_map - Dictionary mapping suffixes to suffixes. This is used to allow recognition of - encoded files for which the encoding and the type are indicated by the same - extension. For example, the :file:`.tgz` extension is mapped to :file:`.tar.gz` - to allow the encoding and type to be recognized separately. This is initially a - copy of the global :data:`suffix_map` defined in the module. + Dictionary mapping suffixes to suffixes. This is used to allow recognition of + encoded files for which the encoding and the type are indicated by the same + extension. For example, the :file:`.tgz` extension is mapped to :file:`.tar.gz` + to allow the encoding and type to be recognized separately. This is initially a + copy of the global :data:`suffix_map` defined in the module. -.. attribute:: MimeTypes.encodings_map + .. attribute:: MimeTypes.encodings_map - Dictionary mapping filename extensions to encoding types. This is initially a - copy of the global :data:`encodings_map` defined in the module. + Dictionary mapping filename extensions to encoding types. This is initially a + copy of the global :data:`encodings_map` defined in the module. -.. attribute:: MimeTypes.types_map + .. attribute:: MimeTypes.types_map - Tuple containing two dictionaries, mapping filename extensions to MIME types: - the first dictionary is for the non-standards types and the second one is for - the standard types. They are initialized by :data:`common_types` and - :data:`types_map`. + Tuple containing two dictionaries, mapping filename extensions to MIME types: + the first dictionary is for the non-standards types and the second one is for + the standard types. They are initialized by :data:`common_types` and + :data:`types_map`. -.. attribute:: MimeTypes.types_map_inv + .. attribute:: MimeTypes.types_map_inv - Tuple containing two dictionaries, mapping MIME types to a list of filename - extensions: the first dictionary is for the non-standards types and the - second one is for the standard types. They are initialized by - :data:`common_types` and :data:`types_map`. + Tuple containing two dictionaries, mapping MIME types to a list of filename + extensions: the first dictionary is for the non-standards types and the + second one is for the standard types. They are initialized by + :data:`common_types` and :data:`types_map`. -.. method:: MimeTypes.guess_extension(type, strict=True) + .. method:: MimeTypes.guess_extension(type, strict=True) - Similar to the :func:`guess_extension` function, using the tables stored as part - of the object. + Similar to the :func:`guess_extension` function, using the tables stored as part + of the object. -.. method:: MimeTypes.guess_type(url, strict=True) + .. method:: MimeTypes.guess_type(url, strict=True) - Similar to the :func:`guess_type` function, using the tables stored as part of - the object. + Similar to the :func:`guess_type` function, using the tables stored as part of + the object. -.. method:: MimeTypes.guess_all_extensions(type, strict=True) + .. method:: MimeTypes.guess_all_extensions(type, strict=True) - Similar to the :func:`guess_all_extensions` function, using the tables stored - as part of the object. + Similar to the :func:`guess_all_extensions` function, using the tables stored + as part of the object. -.. method:: MimeTypes.read(filename, strict=True) + .. method:: MimeTypes.read(filename, strict=True) - Load MIME information from a file named *filename*. This uses :meth:`readfp` to - parse the file. + Load MIME information from a file named *filename*. This uses :meth:`readfp` to + parse the file. - If *strict* is ``True``, information will be added to list of standard types, - else to the list of non-standard types. + If *strict* is ``True``, information will be added to list of standard types, + else to the list of non-standard types. -.. method:: MimeTypes.readfp(fp, strict=True) + .. method:: MimeTypes.readfp(fp, strict=True) - Load MIME type information from an open file *fp*. The file must have the format of - the standard :file:`mime.types` files. + Load MIME type information from an open file *fp*. The file must have the format of + the standard :file:`mime.types` files. - If *strict* is ``True``, information will be added to the list of standard - types, else to the list of non-standard types. + If *strict* is ``True``, information will be added to the list of standard + types, else to the list of non-standard types. -.. method:: MimeTypes.read_windows_registry(strict=True) + .. method:: MimeTypes.read_windows_registry(strict=True) - Load MIME type information from the Windows registry. Availability: Windows. + Load MIME type information from the Windows registry. Availability: Windows. - If *strict* is ``True``, information will be added to the list of standard - types, else to the list of non-standard types. + If *strict* is ``True``, information will be added to the list of standard + types, else to the list of non-standard types. - .. versionadded:: 3.2 + .. versionadded:: 3.2 From 9b7fe9986ff60b702ae63b00dd06557781b0b48e Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 13 May 2017 13:56:13 -0700 Subject: [PATCH 202/340] [3.5] Move Codecov's configuration file under .github (GH-1494) (#1575) (cherry picked from commit cbddf58c797f850a5b06f317a4bb7ab69c6e9715) --- .codecov.yml => .github/codecov.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .codecov.yml => .github/codecov.yml (100%) diff --git a/.codecov.yml b/.github/codecov.yml similarity index 100% rename from .codecov.yml rename to .github/codecov.yml From f3291eeb90da2ddb37efea30dfc9406983b0f681 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Sun, 14 May 2017 18:31:32 +0300 Subject: [PATCH 203/340] bpo-30358: Document sort argument of profile.runctx() (GH-1566) (cherry picked from commit 99776296230ddd8429ebad2d07854b8c27ea10ab) --- Doc/library/profile.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/profile.rst b/Doc/library/profile.rst index b4b1479e2ceba4..5796e3acb6a797 100644 --- a/Doc/library/profile.rst +++ b/Doc/library/profile.rst @@ -215,11 +215,11 @@ functions: and gathers profiling statistics from the execution. If no file name is present, then this function automatically creates a :class:`~pstats.Stats` - instance and prints a simple profiling report. If the sort value is specified + instance and prints a simple profiling report. If the sort value is specified, it is passed to this :class:`~pstats.Stats` instance to control how the results are sorted. -.. function:: runctx(command, globals, locals, filename=None) +.. function:: runctx(command, globals, locals, filename=None, sort=-1) This function is similar to :func:`run`, with added arguments to supply the globals and locals dictionaries for the *command* string. This routine From 51ab4ada8fc99c24d434a533693375169c097006 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 15 May 2017 13:17:13 +0800 Subject: [PATCH 204/340] bpo-30110: fix resource leak in test_asyncio.test_events (#1413) (#1585) --- Lib/test/test_asyncio/test_events.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 802763bd11ff61..492a84a2313baf 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -2194,8 +2194,10 @@ def tearDown(self): def test_get_event_loop_new_process(self): async def main(): pool = concurrent.futures.ProcessPoolExecutor() - return await self.loop.run_in_executor( + result = await self.loop.run_in_executor( pool, _test_get_event_loop_new_process__sub_proc) + pool.shutdown() + return result self.unpatch_get_running_loop() From dd2a09cf98845b1460f0e049ad0ffeeb5c6c6476 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 15 May 2017 13:17:41 +0800 Subject: [PATCH 205/340] bpo-30242: resolve some undefined behaviours in struct (#1418) (#1587) --- Modules/_struct.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Modules/_struct.c b/Modules/_struct.c index f965541a5bbd71..22731295679a9d 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -519,7 +519,7 @@ np_ubyte(char *p, PyObject *v, const formatdef *f) "ubyte format requires 0 <= number <= 255"); return -1; } - *p = (char)x; + *(unsigned char *)p = (unsigned char)x; return 0; } @@ -850,6 +850,7 @@ bp_int(char *p, PyObject *v, const formatdef *f) { long x; Py_ssize_t i; + unsigned char *q = (unsigned char *)p; if (get_long(v, &x) < 0) return -1; i = f->size; @@ -862,7 +863,7 @@ bp_int(char *p, PyObject *v, const formatdef *f) #endif } do { - p[--i] = (char)x; + q[--i] = (unsigned char)(x & 0xffL); x >>= 8; } while (i > 0); return 0; @@ -873,6 +874,7 @@ bp_uint(char *p, PyObject *v, const formatdef *f) { unsigned long x; Py_ssize_t i; + unsigned char *q = (unsigned char *)p; if (get_ulong(v, &x) < 0) return -1; i = f->size; @@ -883,7 +885,7 @@ bp_uint(char *p, PyObject *v, const formatdef *f) RANGE_ERROR(x, f, 1, maxint - 1); } do { - p[--i] = (char)x; + q[--i] = (unsigned char)(x & 0xffUL); x >>= 8; } while (i > 0); return 0; @@ -1070,6 +1072,7 @@ lp_int(char *p, PyObject *v, const formatdef *f) { long x; Py_ssize_t i; + unsigned char *q = (unsigned char *)p; if (get_long(v, &x) < 0) return -1; i = f->size; @@ -1082,7 +1085,7 @@ lp_int(char *p, PyObject *v, const formatdef *f) #endif } do { - *p++ = (char)x; + *q++ = (unsigned char)(x & 0xffL); x >>= 8; } while (--i > 0); return 0; @@ -1093,6 +1096,7 @@ lp_uint(char *p, PyObject *v, const formatdef *f) { unsigned long x; Py_ssize_t i; + unsigned char *q = (unsigned char *)p; if (get_ulong(v, &x) < 0) return -1; i = f->size; @@ -1103,7 +1107,7 @@ lp_uint(char *p, PyObject *v, const formatdef *f) RANGE_ERROR(x, f, 1, maxint - 1); } do { - *p++ = (char)x; + *q++ = (unsigned char)(x & 0xffUL); x >>= 8; } while (--i > 0); return 0; From 72e5aa1ef812358b3b113e784e7365fec13dfd69 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Mon, 15 May 2017 22:41:03 -0700 Subject: [PATCH 206/340] bpo-29651 - Cover edge case of square brackets in urllib docs (#1128) (#1597) (cherry picked from commit f6e863d868a621594df2a8abe072b5d4766e7137) --- Doc/library/urllib.parse.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst index 499b2110c46f9d..6f722a88975c51 100644 --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -117,6 +117,9 @@ or on combining URL components into a URL string. See section :ref:`urlparse-result-object` for more information on the result object. + Unmatched square brackets in the :attr:`netloc` attribute will raise a + :exc:`ValueError`. + .. versionchanged:: 3.2 Added IPv6 URL parsing capabilities. @@ -230,6 +233,9 @@ or on combining URL components into a URL string. See section :ref:`urlparse-result-object` for more information on the result object. + Unmatched square brackets in the :attr:`netloc` attribute will raise a + :exc:`ValueError`. + .. function:: urlunsplit(parts) From 24b5ed230df65f6a1f9d8dd0c4409377576113d9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 16 May 2017 18:16:45 +0300 Subject: [PATCH 207/340] [3.5] bpo-30375: Correct the stacklevel of regex compiling warnings. (GH-1595) (#1605) Warnings emitted when compile a regular expression now always point to the line in the user code. Previously they could point into inners of the re module if emitted from inside of groups or conditionals.. (cherry picked from commit c7ac7280c321b3c1679fe5f657a6be0f86adf173) --- Lib/sre_parse.py | 32 ++++++++++++++++---------------- Lib/test/test_re.py | 8 ++++++-- Misc/NEWS | 4 ++++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 4ff50d1006a607..df947842e847dc 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -309,7 +309,7 @@ def isname(name): return False return True -def _class_escape(source, escape): +def _class_escape(source, escape, nested): # handle escape code inside character class code = ESCAPES.get(escape) if code: @@ -353,13 +353,13 @@ def _class_escape(source, escape): if c in ASCIILETTERS: import warnings warnings.warn('bad escape %s' % escape, - DeprecationWarning, stacklevel=8) + DeprecationWarning, stacklevel=nested + 6) return LITERAL, ord(escape[1]) except ValueError: pass raise source.error("bad escape %s" % escape, len(escape)) -def _escape(source, escape, state): +def _escape(source, escape, state, nested): # handle escape code in expression code = CATEGORIES.get(escape) if code: @@ -420,13 +420,13 @@ def _escape(source, escape, state): if c in ASCIILETTERS: import warnings warnings.warn('bad escape %s' % escape, - DeprecationWarning, stacklevel=8) + DeprecationWarning, stacklevel=nested + 6) return LITERAL, ord(escape[1]) except ValueError: pass raise source.error("bad escape %s" % escape, len(escape)) -def _parse_sub(source, state, nested=True): +def _parse_sub(source, state, nested): # parse an alternation: a|b|c items = [] @@ -434,7 +434,7 @@ def _parse_sub(source, state, nested=True): sourcematch = source.match start = source.tell() while True: - itemsappend(_parse(source, state)) + itemsappend(_parse(source, state, nested + 1)) if not sourcematch("|"): break @@ -476,10 +476,10 @@ def _parse_sub(source, state, nested=True): subpattern.append((BRANCH, (None, items))) return subpattern -def _parse_sub_cond(source, state, condgroup): - item_yes = _parse(source, state) +def _parse_sub_cond(source, state, condgroup, nested): + item_yes = _parse(source, state, nested + 1) if source.match("|"): - item_no = _parse(source, state) + item_no = _parse(source, state, nested + 1) if source.next == "|": raise source.error("conditional backref with more than two branches") else: @@ -488,7 +488,7 @@ def _parse_sub_cond(source, state, condgroup): subpattern.append((GROUPREF_EXISTS, (condgroup, item_yes, item_no))) return subpattern -def _parse(source, state): +def _parse(source, state, nested): # parse a simple pattern subpattern = SubPattern(state) @@ -521,7 +521,7 @@ def _parse(source, state): continue if this[0] == "\\": - code = _escape(source, this, state) + code = _escape(source, this, state, nested + 1) subpatternappend(code) elif this not in SPECIAL_CHARS: @@ -546,7 +546,7 @@ def _parse(source, state): if this == "]" and set != start: break elif this[0] == "\\": - code1 = _class_escape(source, this) + code1 = _class_escape(source, this, nested + 1) else: code1 = LITERAL, _ord(this) if sourcematch("-"): @@ -562,7 +562,7 @@ def _parse(source, state): setappend((LITERAL, _ord("-"))) break if that[0] == "\\": - code2 = _class_escape(source, that) + code2 = _class_escape(source, that, nested + 1) else: code2 = LITERAL, _ord(that) if code1[0] != LITERAL or code2[0] != LITERAL: @@ -713,7 +713,7 @@ def _parse(source, state): lookbehindgroups = state.lookbehindgroups if lookbehindgroups is None: state.lookbehindgroups = state.groups - p = _parse_sub(source, state) + p = _parse_sub(source, state, nested + 1) if dir < 0: if lookbehindgroups is None: state.lookbehindgroups = None @@ -773,9 +773,9 @@ def _parse(source, state): except error as err: raise source.error(err.msg, len(name) + 1) from None if condgroup: - p = _parse_sub_cond(source, state, condgroup) + p = _parse_sub_cond(source, state, condgroup, nested + 1) else: - p = _parse_sub(source, state) + p = _parse_sub(source, state, nested + 1) if not source.match(")"): raise source.error("missing ), unterminated subpattern", source.tell() - start) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 9acd5abbfd7776..839bf275af3537 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -638,14 +638,18 @@ def test_other_escapes(self): re.purge() # for warnings for c in 'ceghijklmopqyzCEFGHIJKLMNOPQRTVXY': with self.subTest(c): - with self.assertWarns(DeprecationWarning): + with self.assertWarns(DeprecationWarning) as warns: self.assertEqual(re.fullmatch('\\%c' % c, c).group(), c) self.assertIsNone(re.match('\\%c' % c, 'a')) + self.assertRegex(str(warns.warnings[0].message), 'bad escape') + self.assertEqual(warns.warnings[0].filename, __file__) for c in 'ceghijklmopqyzABCEFGHIJKLMNOPQRTVXYZ': with self.subTest(c): - with self.assertWarns(DeprecationWarning): + with self.assertWarns(DeprecationWarning) as warns: self.assertEqual(re.fullmatch('[\\%c]' % c, c).group(), c) self.assertIsNone(re.match('[\\%c]' % c, 'a')) + self.assertRegex(str(warns.warnings[0].message), 'bad escape') + self.assertEqual(warns.warnings[0].filename, __file__) def test_string_boundaries(self): # See http://bugs.python.org/issue10713 diff --git a/Misc/NEWS b/Misc/NEWS index 41fe80f44c3f12..6b4b401aa62615 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,10 @@ Extension Modules Library ------- +- bpo-30375: Warnings emitted when compile a regular expression now always + point to the line in the user code. Previously they could point into inners + of the re module if emitted from inside of groups or conditionals. + - bpo-30048: Fixed ``Task.cancel()`` can be ignored when the task is running coroutine and the coroutine returned without any more ``await``. From 27dfbf0b4745e76f3c3d9c672c53438699c3f97f Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Tue, 16 May 2017 08:36:38 -0700 Subject: [PATCH 208/340] Remove unused variable in test_urllibnet. (#1598) (#1599) (cherry picked from commit 1bd7d299bd2a91f8267f97a413568ab8fe7fdfbb) --- Lib/test/test_urllibnet.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_urllibnet.py b/Lib/test/test_urllibnet.py index 8379f1a512e94f..b9b1eaaad47eeb 100644 --- a/Lib/test/test_urllibnet.py +++ b/Lib/test/test_urllibnet.py @@ -12,6 +12,7 @@ support.requires('network') + class URLTimeoutTest(unittest.TestCase): # XXX this test doesn't seem to test anything useful. @@ -26,7 +27,7 @@ def tearDown(self): def testURLread(self): with support.transient_internet("www.example.com"): f = urllib.request.urlopen("http://www.example.com/") - x = f.read() + f.read() class urlopenNetworkTests(unittest.TestCase): @@ -189,6 +190,7 @@ def test_data_header(self): def test_reporthook(self): records = [] + def recording_reporthook(blocks, block_size, total_size): records.append((blocks, block_size, total_size)) From 083f13e34c0b9f9ed4ed64fed3989d4af97843b3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 17 May 2017 00:29:42 +0300 Subject: [PATCH 209/340] [3.5] bpo-30380: Fix Sphinx 1.6.1 warnings. (GH-1613) (GH-1615) --- Doc/howto/urllib2.rst | 10 +++++----- Doc/library/pyexpat.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/xml.dom.minidom.rst | 2 +- Doc/library/xml.etree.elementtree.rst | 2 +- Doc/tools/susp-ignored.csv | 10 +++++----- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index 18b5c6556be1c9..8d383e03ee8a28 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -34,8 +34,8 @@ handling common situations - like basic authentication, cookies, proxies and so on. These are provided by objects called handlers and openers. urllib.request supports fetching URLs for many "URL schemes" (identified by the string -before the ":" in URL - for example "ftp" is the URL scheme of -"ftp://python.org/") using their associated network protocols (e.g. FTP, HTTP). +before the ``":"`` in URL - for example ``"ftp"`` is the URL scheme of +``"ftp://python.org/"``) using their associated network protocols (e.g. FTP, HTTP). This tutorial focuses on the most common case, HTTP. For straightforward situations *urlopen* is very easy to use. But as soon as you @@ -511,10 +511,10 @@ than the URL you pass to .add_password() will also match. :: ``top_level_url`` is in fact *either* a full URL (including the 'http:' scheme component and the hostname and optionally the port number) -e.g. "http://example.com/" *or* an "authority" (i.e. the hostname, -optionally including the port number) e.g. "example.com" or "example.com:8080" +e.g. ``"http://example.com/"`` *or* an "authority" (i.e. the hostname, +optionally including the port number) e.g. ``"example.com"`` or ``"example.com:8080"`` (the latter example includes a port number). The authority, if present, must -NOT contain the "userinfo" component - for example "joe:password@example.com" is +NOT contain the "userinfo" component - for example ``"joe:password@example.com"`` is not correct. diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst index 075a8b5139b196..e43b9aecd86835 100644 --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -869,7 +869,7 @@ The ``errors`` module has the following attributes: .. rubric:: Footnotes -.. [#] The encoding string included in XML output should conform to the +.. [1] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl and https://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 6b23b3eb610657..85fafa757ea50a 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -829,7 +829,7 @@ restrictions imposed by *s*. The ``in`` and ``not in`` operations have the same priorities as the comparison operations. The ``+`` (concatenation) and ``*`` (repetition) -operations have the same priority as the corresponding numeric operations. +operations have the same priority as the corresponding numeric operations. [3]_ .. index:: triple: operations on; sequence; types diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst index 2e9e814693df57..40470e8736e7e4 100644 --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -248,7 +248,7 @@ utility to most DOM users. .. rubric:: Footnotes -.. [#] The encoding name included in the XML output should conform to +.. [1] The encoding name included in the XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not valid in an XML document's declaration, even though Python accepts it as an encoding name. diff --git a/Doc/library/xml.etree.elementtree.rst b/Doc/library/xml.etree.elementtree.rst index b54eace41188b0..7d814ad406eb1b 100644 --- a/Doc/library/xml.etree.elementtree.rst +++ b/Doc/library/xml.etree.elementtree.rst @@ -1192,7 +1192,7 @@ Exceptions .. rubric:: Footnotes -.. [#] The encoding string included in XML output should conform to the +.. [1] The encoding string included in XML output should conform to the appropriate standards. For example, "UTF-8" is valid, but "UTF8" is not. See https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl and https://www.iana.org/assignments/character-sets/character-sets.xhtml. diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index c1dcf42a28afa8..8883f5317a4937 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -82,7 +82,7 @@ howto/pyporting,,::,Programming Language :: Python :: 2 howto/pyporting,,::,Programming Language :: Python :: 3 howto/regex,,::, howto/regex,,:foo,(?:foo) -howto/urllib2,,:password,"for example ""joe:password@example.com""" +howto/urllib2,,:password,"""joe:password@example.com""" library/audioop,,:ipos,"# factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)]," library/bisect,32,:hi,all(val >= x for val in a[i:hi]) library/bisect,42,:hi,all(val > x for val in a[i:hi]) @@ -272,8 +272,8 @@ whatsnew/3.2,,:feed,>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe: whatsnew/3.2,,:gz,">>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:" whatsnew/3.2,,:location,zope9-location = ${zope9:location} whatsnew/3.2,,:prefix,zope-conf = ${custom:prefix}/etc/zope.conf -whatsnew/changelog,,:gz,": TarFile opened with external fileobj and ""w:gz"" mode didn't" -whatsnew/changelog,,::,": Use ""127.0.0.1"" or ""::1"" instead of ""localhost"" as much as" +whatsnew/changelog,,:gz,": TarFile opened with external fileobj and " +whatsnew/changelog,,::,::1 library/re,,`,!#$%&'*+-.^_`|~: library/re,,`,\!\#\$\%\&\'\*\+\-\.\^_\`\|\~\: library/tarfile,149,:xz,'x:xz' @@ -288,8 +288,8 @@ library/xml.etree.elementtree,,:actor,"for actor in root.findall('real_person:ac library/xml.etree.elementtree,,:name,"name = actor.find('real_person:name', ns)" library/xml.etree.elementtree,,:character,"for char in actor.findall('role:character', ns):" library/zipapp,31,:main,"$ python -m zipapp myapp -m ""myapp:main""" -library/zipapp,82,:fn,"argument should have the form ""pkg.mod:fn"", where ""pkg.mod"" is a" -library/zipapp,155,:callable,"""pkg.module:callable"" and the archive will be run by importing" +library/zipapp,,:fn,"pkg.mod:fn" +library/zipapp,,:callable,"pkg.module:callable" library/stdtypes,,::,>>> m[::2].tolist() library/sys,,`,# ``wrapper`` creates a ``wrap(coro)`` coroutine: tutorial/venv,77,:c7b9645a6f35,"Python 3.4.3+ (3.4:c7b9645a6f35+, May 22 2015, 09:31:25)" From 77606957e71ce477d2c5569718f0fc36f05c6f59 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Tue, 16 May 2017 14:40:33 -0700 Subject: [PATCH 210/340] bpo-30380: Pin the version of Sphinx used to build the documentation (GH-1612) (GH-1618) --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5fee6cd7673324..fe90bad626ce83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,9 +37,11 @@ matrix: - TESTING=docs before_script: - cd Doc - - make venv + # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures. + # (Updating the version is fine as long as no warnings are raised by doing so.) + - python -m pip install sphinx~=1.6.1 script: - - make check suspicious html PYTHON="./venv/bin/python" SPHINXBUILD="./venv/bin/python -m sphinx" SPHINXOPTS="-q -W" + - make check suspicious html SPHINXOPTS="-q -W" - os: linux language: c compiler: gcc From c9ba45d1b71d86321e5422e8a2cbe6e52aaba6f4 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 16 May 2017 16:02:35 -0700 Subject: [PATCH 211/340] bpo-30329: Catch Windows error 10022 on shutdown() (#1538) (#1621) Catch the Windows socket WSAEINVAL error (code 10022) in imaplib and poplib on shutdown(SHUT_RDWR): An invalid operation was attempted This error occurs sometimes on SSL connections. (cherry picked from commit 83a2c2879839da2e10037f5e4af1bd1dafbf1a52) --- Lib/imaplib.py | 9 ++++++--- Lib/poplib.py | 9 ++++++--- Misc/NEWS | 4 ++++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Lib/imaplib.py b/Lib/imaplib.py index 2f7e9331fbc86c..ef2c6f814c5716 100644 --- a/Lib/imaplib.py +++ b/Lib/imaplib.py @@ -310,9 +310,12 @@ def shutdown(self): self.file.close() try: self.sock.shutdown(socket.SHUT_RDWR) - except OSError as e: - # The server might already have closed the connection - if e.errno != errno.ENOTCONN: + except OSError as exc: + # The server might already have closed the connection. + # On Windows, this may result in WSAEINVAL (error 10022): + # An invalid operation was attempted. + if (exc.errno != errno.ENOTCONN + and getattr(exc, 'winerror', 0) != 10022): raise finally: self.sock.close() diff --git a/Lib/poplib.py b/Lib/poplib.py index f6723904e859e1..516b6f060d2884 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -288,9 +288,12 @@ def close(self): if sock is not None: try: sock.shutdown(socket.SHUT_RDWR) - except OSError as e: - # The server might already have closed the connection - if e.errno != errno.ENOTCONN: + except OSError as exc: + # The server might already have closed the connection. + # On Windows, this may result in WSAEINVAL (error 10022): + # An invalid operation was attempted. + if (exc.errno != errno.ENOTCONN + and getattr(exc, 'winerror', 0) != 10022): raise finally: sock.close() diff --git a/Misc/NEWS b/Misc/NEWS index 6b4b401aa62615..16cb60c9e32a30 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,10 @@ Extension Modules Library ------- +- bpo-30329: imaplib and poplib now catch the Windows socket WSAEINVAL error + (code 10022) on shutdown(SHUT_RDWR): An invalid operation was attempted. + This error occurs sometimes on SSL connections. + - bpo-30375: Warnings emitted when compile a regular expression now always point to the line in the user code. Previously they could point into inners of the re module if emitted from inside of groups or conditionals. From aeb644714d37fb974e3acdf7daef031461e1283f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 16 May 2017 17:05:29 -0700 Subject: [PATCH 212/340] bpo-30357: test_thread now uses threading_cleanup() (#1592) (#1623) test_thread: setUp() now uses support.threading_setup() and support.threading_cleanup() to wait until threads complete to avoid random side effects on following tests. Co-Authored-By: Grzegorz Grzywacz (cherry picked from commit 79ef7f8e88a4972c4aecf95cfc5cd934f1861e08) --- Lib/test/test_thread.py | 4 ++++ Misc/ACKS | 1 + Misc/NEWS | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py index ef3059b68674b4..3909b75ccd4647 100644 --- a/Lib/test/test_thread.py +++ b/Lib/test/test_thread.py @@ -20,6 +20,7 @@ def verbose_print(arg): with _print_mutex: print(arg) + class BasicThreadTest(unittest.TestCase): def setUp(self): @@ -31,6 +32,9 @@ def setUp(self): self.running = 0 self.next_ident = 0 + key = support.threading_setup() + self.addCleanup(support.threading_cleanup, *key) + class ThreadRunningTests(BasicThreadTest): diff --git a/Misc/ACKS b/Misc/ACKS index 2d2436c9c3b8c1..3d9414b6b78316 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -543,6 +543,7 @@ Eric Groo Daniel Andrade Groppe Dag Gruneau Filip Gruszczyński +Grzegorz Grzywacz Thomas Guettler Yuyang Guo Anuj Gupta diff --git a/Misc/NEWS b/Misc/NEWS index 16cb60c9e32a30..9386cb4b33f766 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -235,6 +235,11 @@ Build Tests ----- +- bpo-30357: test_thread: setUp() now uses support.threading_setup() and + support.threading_cleanup() to wait until threads complete to avoid + random side effects on following tests. Initial patch written by Grzegorz + Grzywacz. + - bpo-28087: Skip test_asyncore and test_eintr poll failures on macOS. Skip some tests of select.poll when running on macOS due to unresolved issues with the underlying system poll function on some macOS versions. From f01c0ec9fe571e8afd50d2f5180db3c0d7b613af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 16 May 2017 17:59:24 -0700 Subject: [PATCH 213/340] bpo-30273: update distutils.sysconfig for venv's created from Python (#1515) (#1626) compiled out-of-tree (builddir != srcdir). (see also bpo-15366) (cherry picked from commit dbdea629e2e0e4bd8845aa55041e0a0ca4172cf3) --- Lib/distutils/sysconfig.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index 4f321352151d56..bd19ebf5158b09 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -93,14 +93,11 @@ def get_python_inc(plat_specific=0, prefix=None): # the build directory may not be the source directory, we # must use "srcdir" from the makefile to find the "Include" # directory. - base = _sys_home or project_base if plat_specific: - return base - if _sys_home: - incdir = os.path.join(_sys_home, 'Include') + return _sys_home or project_base else: incdir = os.path.join(get_config_var('srcdir'), 'Include') - return os.path.normpath(incdir) + return os.path.normpath(incdir) python_dir = 'python' + get_python_version() + build_flags return os.path.join(prefix, "include", python_dir) elif os.name == "nt": From 9081b36f330964faa4dee3af03228d2ca7c71835 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Wed, 17 May 2017 22:02:55 +0800 Subject: [PATCH 214/340] bpo-30301: Fix AttributeError when using SimpleQueue.empty() (#1601) (#1627) Under *spawn* and *forkserver* start methods, SimpleQueue.empty() could raise AttributeError due to not setting _poll in __setstate__. --- Lib/multiprocessing/queues.py | 1 + Lib/test/_test_multiprocessing.py | 36 +++++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 40 insertions(+) diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index 786a303b33705a..40ae10a88c1508 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -337,6 +337,7 @@ def __getstate__(self): def __setstate__(self, state): (self._reader, self._writer, self._rlock, self._wlock) = state + self._poll = self._reader.poll def get(self): with self._rlock: diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index e41845b404307e..040212889486ec 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -3868,6 +3868,42 @@ def test_semaphore_tracker(self): self.assertRegex(err, expected) self.assertRegex(err, 'semaphore_tracker: %r: \[Errno' % name1) +class TestSimpleQueue(unittest.TestCase): + + @classmethod + def _test_empty(cls, queue, child_can_start, parent_can_continue): + child_can_start.wait() + # issue 30301, could fail under spawn and forkserver + try: + queue.put(queue.empty()) + queue.put(queue.empty()) + finally: + parent_can_continue.set() + + def test_empty(self): + queue = multiprocessing.SimpleQueue() + child_can_start = multiprocessing.Event() + parent_can_continue = multiprocessing.Event() + + proc = multiprocessing.Process( + target=self._test_empty, + args=(queue, child_can_start, parent_can_continue) + ) + proc.daemon = True + proc.start() + + self.assertTrue(queue.empty()) + + child_can_start.set() + parent_can_continue.wait() + + self.assertFalse(queue.empty()) + self.assertEqual(queue.get(), True) + self.assertEqual(queue.get(), False) + self.assertTrue(queue.empty()) + + proc.join() + # # Mixins # diff --git a/Misc/NEWS b/Misc/NEWS index 9386cb4b33f766..a7a8d79cff1990 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Extension Modules Library ------- +- bpo-30301: Fix AttributeError when using SimpleQueue.empty() under + *spawn* and *forkserver* start methods. + - bpo-30329: imaplib and poplib now catch the Windows socket WSAEINVAL error (code 10022) on shutdown(SHUT_RDWR): An invalid operation was attempted. This error occurs sometimes on SSL connections. From f5633e02433a81a6d0f14fc1c3294e752f4ac1a3 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 17 May 2017 14:49:43 -0700 Subject: [PATCH 215/340] bpo-30387: Fix warning in test_threading (#1634) (#1637) test_is_alive_after_fork() now joins directly the thread to avoid the following warning added by bpo-30357: Warning -- threading_cleanup() failed to cleanup 0 threads after 2 sec (count: 0, dangling: 21) Use also a different exit code to catch generic exit code 1. (cherry picked from commit f8d05b3a24e745ab4a974b891ac1389e2f11ce4d) --- Lib/test/test_threading.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py index 83a99023d7a8ae..edae526d76587c 100644 --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -470,13 +470,15 @@ def test_is_alive_after_fork(self): for i in range(20): t = threading.Thread(target=lambda: None) t.start() - self.addCleanup(t.join) pid = os.fork() if pid == 0: - os._exit(1 if t.is_alive() else 0) + os._exit(11 if t.is_alive() else 10) else: + t.join() + pid, status = os.waitpid(pid, 0) - self.assertEqual(0, status) + self.assertTrue(os.WIFEXITED(status)) + self.assertEqual(10, os.WEXITSTATUS(status)) def test_main_thread(self): main = threading.main_thread() From 9503dd1e1865bb873a1f72f63ae384bba8462c5e Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 18 May 2017 22:12:57 -0700 Subject: [PATCH 216/340] bpo-27103: regrtest disables -W if -R is used (#1660) Workaround for a regrtest bug. --- Lib/test/regrtest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index d7ca07b6647986..6cb9d5ae0e3fc5 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -425,6 +425,11 @@ def _parse_args(args, **kwargs): ns.use_resources.append(r) if ns.random_seed is not None: ns.randomize = True + if ns.huntrleaks and ns.verbose3: + ns.verbose3 = False + print("WARNING: Disable --verbose3 because it's incompatible with " + "--huntrleaks: see http://bugs.python.org/issue27103", + file=sys.stderr) return ns From 4a86fe9d3f5e7af6f019ae22536eec228f04e22e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 20 May 2017 10:23:58 +0300 Subject: [PATCH 217/340] [3.5] bpo-25794: Fix `type.__setattr__()` for non-interned attribute names. (GH-1652) (#1674) Based on patch by Eryk Sun. (cherry picked from commit d896985bb2de49046f9b6879e906d1e4db255e23) --- Lib/test/test_class.py | 27 +++++++++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 39 ++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 4d554a397b4a51..ecc01f277954d5 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -568,5 +568,32 @@ class B(A): a = A(hash(A.f)^(-1)) hash(a.f) + def testSetattrWrapperNameIntern(self): + # Issue #25794: __setattr__ should intern the attribute name + class A: + pass + + def add(self, other): + return 'summa' + + name = str(b'__add__', 'ascii') # shouldn't be optimized + self.assertIsNot(name, '__add__') # not interned + type.__setattr__(A, name, add) + self.assertEqual(A() + 1, 'summa') + + name2 = str(b'__add__', 'ascii') + self.assertIsNot(name2, '__add__') + self.assertIsNot(name2, name) + type.__delattr__(A, name2) + with self.assertRaises(TypeError): + A() + 1 + + def testSetattrNonStringName(self): + class A: + pass + + with self.assertRaises(TypeError): + type.__setattr__(A, b'x', None) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index a7a8d79cff1990..dc7cbcb724d3b9 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-25794: Fixed type.__setattr__() and type.__delattr__() for + non-interned attribute names. Based on patch by Eryk Sun. + - bpo-29935: Fixed error messages in the index() method of tuple, list and deque when pass indices of wrong type. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 7b76e5cd4d40dc..3f526b429b1eb4 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3020,6 +3020,7 @@ type_getattro(PyTypeObject *type, PyObject *name) static int type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) { + int res; if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { PyErr_Format( PyExc_TypeError, @@ -3027,9 +3028,35 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) type->tp_name); return -1; } - if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) - return -1; - return update_slot(type, name); + if (PyUnicode_Check(name)) { + if (PyUnicode_CheckExact(name)) { + if (PyUnicode_READY(name) == -1) + return -1; + Py_INCREF(name); + } + else { + name = _PyUnicode_Copy(name); + if (name == NULL) + return -1; + } + PyUnicode_InternInPlace(&name); + if (!PyUnicode_CHECK_INTERNED(name)) { + PyErr_SetString(PyExc_MemoryError, + "Out of memory interning an attribute name"); + Py_DECREF(name); + return -1; + } + } + else { + /* Will fail in _PyObject_GenericSetAttrWithDict. */ + Py_INCREF(name); + } + res = PyObject_GenericSetAttr((PyObject *)type, name, value); + if (res == 0) { + res = update_slot(type, name); + } + Py_DECREF(name); + return res; } extern void @@ -6849,7 +6876,7 @@ init_slotdefs(void) /* Slots must be ordered by their offset in the PyHeapTypeObject. */ assert(!p[1].name || p->offset <= p[1].offset); p->name_strobj = PyUnicode_InternFromString(p->name); - if (!p->name_strobj) + if (!p->name_strobj || !PyUnicode_CHECK_INTERNED(p->name_strobj)) Py_FatalError("Out of memory interning slotdef names"); } slotdefs_initialized = 1; @@ -6874,6 +6901,9 @@ update_slot(PyTypeObject *type, PyObject *name) slotdef **pp; int offset; + assert(PyUnicode_CheckExact(name)); + assert(PyUnicode_CHECK_INTERNED(name)); + /* Clear the VALID_VERSION flag of 'type' and all its subclasses. This could possibly be unified with the update_subclasses() recursion below, but carefully: @@ -6884,7 +6914,6 @@ update_slot(PyTypeObject *type, PyObject *name) init_slotdefs(); pp = ptrs; for (p = slotdefs; p->name; p++) { - /* XXX assume name is interned! */ if (p->name_strobj == name) *pp++ = p; } From 2f7f533cf6fb57fcedcbc7bd454ac59fbaf2c655 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 20 May 2017 13:06:47 +0300 Subject: [PATCH 218/340] [3.5] bpo-27945: Fixed various segfaults with dict. (GH-1657) (#1678) Based on patches by Duane Griffin and Tim Mitchell. (cherry picked from commit 753bca3934a7618a4fa96e107ad1c5c18633a683) --- Lib/test/test_dict.py | 86 +++++++++++++++++++++++++++++++++++++++++++ Misc/ACKS | 1 + Misc/NEWS | 4 ++ Objects/dictobject.c | 80 +++++++++++++++++++++++++--------------- 4 files changed, 142 insertions(+), 29 deletions(-) diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py index b85d333dcbe49c..f59490ab76162c 100644 --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -976,6 +976,92 @@ def test_free_after_iterating(self): support.check_free_after_iterating(self, lambda d: iter(d.values()), dict) support.check_free_after_iterating(self, lambda d: iter(d.items()), dict) + def test_equal_operator_modifying_operand(self): + # test fix for seg fault reported in issue 27945 part 3. + class X(): + def __del__(self): + dict_b.clear() + + def __eq__(self, other): + dict_a.clear() + return True + + def __hash__(self): + return 13 + + dict_a = {X(): 0} + dict_b = {X(): X()} + self.assertTrue(dict_a == dict_b) + + def test_fromkeys_operator_modifying_dict_operand(self): + # test fix for seg fault reported in issue 27945 part 4a. + class X(int): + def __hash__(self): + return 13 + + def __eq__(self, other): + if len(d) > 1: + d.clear() + return False + + d = {} # this is required to exist so that d can be constructed! + d = {X(1): 1, X(2): 2} + try: + dict.fromkeys(d) # shouldn't crash + except RuntimeError: # implementation defined + pass + + def test_fromkeys_operator_modifying_set_operand(self): + # test fix for seg fault reported in issue 27945 part 4b. + class X(int): + def __hash__(self): + return 13 + + def __eq__(self, other): + if len(d) > 1: + d.clear() + return False + + d = {} # this is required to exist so that d can be constructed! + d = {X(1), X(2)} + try: + dict.fromkeys(d) # shouldn't crash + except RuntimeError: # implementation defined + pass + + def test_dictitems_contains_use_after_free(self): + class X: + def __eq__(self, other): + d.clear() + return NotImplemented + + d = {0: set()} + (0, X()) in d.items() + + def test_init_use_after_free(self): + class X: + def __hash__(self): + pair[:] = [] + return 13 + + pair = [X(), 123] + dict([pair]) + + def test_oob_indexing_dictiter_iternextitem(self): + class X(int): + def __del__(self): + d.clear() + + d = {i: X(i) for i in range(8)} + + def iter_and_mutate(): + for result in d.items(): + if result[0] == 2: + d[2] = None # free d[2] --> X(2).__del__ was called + + self.assertRaises(RuntimeError, iter_and_mutate) + + from test import mapping_tests class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): diff --git a/Misc/ACKS b/Misc/ACKS index 3d9414b6b78316..d91d9c1ee0d641 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -534,6 +534,7 @@ Tim Graham Kim Gräsman Nathaniel Gray Eddy De Greef +Duane Griffin Grant Griffin Andrea Griffini Duncan Grisby diff --git a/Misc/NEWS b/Misc/NEWS index dc7cbcb724d3b9..43e7748e48f142 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Release date: XXXX-XX-XX Core and Builtins ----------------- +- bpo-27945: Fixed various segfaults with dict when input collections are + mutated during searching, inserting or comparing. Based on patches by + Duane Griffin and Tim Mitchell. + - bpo-25794: Fixed type.__setattr__() and type.__delattr__() for non-interned attribute names. Based on patch by Eryk Sun. diff --git a/Objects/dictobject.c b/Objects/dictobject.c index e277ab87e7bfae..ff77beeed7c243 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -787,56 +787,61 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) PyDictKeyEntry *ep; assert(key != dummy); + Py_INCREF(key); + Py_INCREF(value); if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { if (insertion_resize(mp) < 0) - return -1; + goto Fail; } ep = mp->ma_keys->dk_lookup(mp, key, hash, &value_addr); - if (ep == NULL) { - return -1; - } + if (ep == NULL) + goto Fail; + assert(PyUnicode_CheckExact(key) || mp->ma_keys->dk_lookup == lookdict); - Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); old_value = *value_addr; if (old_value != NULL) { assert(ep->me_key != NULL && ep->me_key != dummy); *value_addr = value; Py_DECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ + Py_DECREF(key); } else { if (ep->me_key == NULL) { - Py_INCREF(key); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ - if (insertion_resize(mp) < 0) { - Py_DECREF(key); - Py_DECREF(value); - return -1; - } + if (insertion_resize(mp) < 0) + goto Fail; ep = find_empty_slot(mp, key, hash, &value_addr); } + mp->ma_used++; + *value_addr = value; mp->ma_keys->dk_usable--; assert(mp->ma_keys->dk_usable >= 0); ep->me_key = key; ep->me_hash = hash; + assert(ep->me_key != NULL && ep->me_key != dummy); } else { + mp->ma_used++; + *value_addr = value; if (ep->me_key == dummy) { - Py_INCREF(key); ep->me_key = key; ep->me_hash = hash; Py_DECREF(dummy); } else { assert(_PyDict_HasSplitTable(mp)); + Py_DECREF(key); } } - mp->ma_used++; - *value_addr = value; - assert(ep->me_key != NULL && ep->me_key != dummy); } return 0; + +Fail: + Py_DECREF(value); + Py_DECREF(key); + return -1; } /* @@ -2057,11 +2062,18 @@ PyDict_MergeFromSeq2(PyObject *d, PyObject *seq2, int override) /* Update/merge with this (key, value) pair. */ key = PySequence_Fast_GET_ITEM(fast, 0); value = PySequence_Fast_GET_ITEM(fast, 1); + Py_INCREF(key); + Py_INCREF(value); if (override || PyDict_GetItem(d, key) == NULL) { int status = PyDict_SetItem(d, key, value); - if (status < 0) + if (status < 0) { + Py_DECREF(key); + Py_DECREF(value); goto Fail; + } } + Py_DECREF(key); + Py_DECREF(value); Py_DECREF(fast); Py_DECREF(item); } @@ -2320,14 +2332,15 @@ dict_equal(PyDictObject *a, PyDictObject *b) bval = NULL; else bval = *vaddr; - Py_DECREF(key); if (bval == NULL) { + Py_DECREF(key); Py_DECREF(aval); if (PyErr_Occurred()) return -1; return 0; } cmp = PyObject_RichCompareBool(aval, bval, Py_EQ); + Py_DECREF(key); Py_DECREF(aval); if (cmp <= 0) /* error or not equal */ return cmp; @@ -3152,7 +3165,7 @@ PyTypeObject PyDictIterValue_Type = { static PyObject *dictiter_iternextitem(dictiterobject *di) { - PyObject *key, *value, *result = di->di_result; + PyObject *key, *value, *result; Py_ssize_t i, mask, offset; PyDictObject *d = di->di_dict; PyObject **value_ptr; @@ -3188,22 +3201,27 @@ static PyObject *dictiter_iternextitem(dictiterobject *di) if (i > mask) goto fail; - if (result->ob_refcnt == 1) { + di->len--; + key = d->ma_keys->dk_entries[i].me_key; + value = *value_ptr; + Py_INCREF(key); + Py_INCREF(value); + result = di->di_result; + if (Py_REFCNT(result) == 1) { + PyObject *oldkey = PyTuple_GET_ITEM(result, 0); + PyObject *oldvalue = PyTuple_GET_ITEM(result, 1); + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ Py_INCREF(result); - Py_DECREF(PyTuple_GET_ITEM(result, 0)); - Py_DECREF(PyTuple_GET_ITEM(result, 1)); + Py_DECREF(oldkey); + Py_DECREF(oldvalue); } else { result = PyTuple_New(2); if (result == NULL) return NULL; + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ } - di->len--; - key = d->ma_keys->dk_entries[i].me_key; - value = *value_ptr; - Py_INCREF(key); - Py_INCREF(value); - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ return result; fail: @@ -3696,6 +3714,7 @@ dictitems_iter(_PyDictViewObject *dv) static int dictitems_contains(_PyDictViewObject *dv, PyObject *obj) { + int result; PyObject *key, *value, *found; if (dv->dv_dict == NULL) return 0; @@ -3709,7 +3728,10 @@ dictitems_contains(_PyDictViewObject *dv, PyObject *obj) return -1; return 0; } - return PyObject_RichCompareBool(value, found, Py_EQ); + Py_INCREF(found); + result = PyObject_RichCompareBool(value, found, Py_EQ); + Py_DECREF(found); + return result; } static PySequenceMethods dictitems_as_sequence = { From a2a822614c64b01b0cf5c0ee63a96b3ad4561a85 Mon Sep 17 00:00:00 2001 From: Senthil Kumaran Date: Sat, 20 May 2017 23:22:55 -0700 Subject: [PATCH 219/340] bpo-29976: urllib.parse clarify '' in scheme values. (GH-984) (GH-1693) (cherry picked from commit 906f5330b9c9a74cad1cf27fddaf77e99dff9edd) --- Lib/urllib/parse.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 50641ba69bc83b..5746a4ee019baa 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -38,29 +38,37 @@ "DefragResult", "ParseResult", "SplitResult", "DefragResultBytes", "ParseResultBytes", "SplitResultBytes"] -# A classification of schemes ('' means apply by default) -uses_relative = ['ftp', 'http', 'gopher', 'nntp', 'imap', +# A classification of schemes. +# The empty string classifies URLs with no scheme specified, +# being the default value returned by “urlsplit” and “urlparse”. + +uses_relative = ['', 'ftp', 'http', 'gopher', 'nntp', 'imap', 'wais', 'file', 'https', 'shttp', 'mms', - 'prospero', 'rtsp', 'rtspu', '', 'sftp', + 'prospero', 'rtsp', 'rtspu', 'sftp', 'svn', 'svn+ssh', 'ws', 'wss'] -uses_netloc = ['ftp', 'http', 'gopher', 'nntp', 'telnet', + +uses_netloc = ['', 'ftp', 'http', 'gopher', 'nntp', 'telnet', 'imap', 'wais', 'file', 'mms', 'https', 'shttp', - 'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', '', + 'snews', 'prospero', 'rtsp', 'rtspu', 'rsync', 'svn', 'svn+ssh', 'sftp', 'nfs', 'git', 'git+ssh', 'ws', 'wss'] -uses_params = ['ftp', 'hdl', 'prospero', 'http', 'imap', + +uses_params = ['', 'ftp', 'hdl', 'prospero', 'http', 'imap', 'https', 'shttp', 'rtsp', 'rtspu', 'sip', 'sips', - 'mms', '', 'sftp', 'tel'] + 'mms', 'sftp', 'tel'] # These are not actually used anymore, but should stay for backwards # compatibility. (They are undocumented, but have a public-looking name.) + non_hierarchical = ['gopher', 'hdl', 'mailto', 'news', 'telnet', 'wais', 'imap', 'snews', 'sip', 'sips'] -uses_query = ['http', 'wais', 'imap', 'https', 'shttp', 'mms', - 'gopher', 'rtsp', 'rtspu', 'sip', 'sips', ''] -uses_fragment = ['ftp', 'hdl', 'http', 'gopher', 'news', + +uses_query = ['', 'http', 'wais', 'imap', 'https', 'shttp', 'mms', + 'gopher', 'rtsp', 'rtspu', 'sip', 'sips'] + +uses_fragment = ['', 'ftp', 'hdl', 'http', 'gopher', 'news', 'nntp', 'wais', 'https', 'shttp', 'snews', - 'file', 'prospero', ''] + 'file', 'prospero'] # Characters valid in scheme names scheme_chars = ('abcdefghijklmnopqrstuvwxyz' From bc75b72d393bc40c3243d7099db6c2c39fe632aa Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 21 May 2017 10:35:58 +0300 Subject: [PATCH 220/340] [3.5] bpo-30415: Add new tests for the fnmatch module. (GH-1684) (#1695) (cherry picked from commit 8175547) --- Lib/test/test_fnmatch.py | 64 ++++++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_fnmatch.py b/Lib/test/test_fnmatch.py index fa37f90c27e9a5..e37e4f5d479737 100644 --- a/Lib/test/test_fnmatch.py +++ b/Lib/test/test_fnmatch.py @@ -1,18 +1,19 @@ """Test cases for the fnmatch module.""" import unittest +import os from fnmatch import fnmatch, fnmatchcase, translate, filter class FnmatchTestCase(unittest.TestCase): - def check_match(self, filename, pattern, should_match=1, fn=fnmatch): + def check_match(self, filename, pattern, should_match=True, fn=fnmatch): if should_match: self.assertTrue(fn(filename, pattern), "expected %r to match pattern %r" % (filename, pattern)) else: - self.assertTrue(not fn(filename, pattern), + self.assertFalse(fn(filename, pattern), "expected %r not to match pattern %r" % (filename, pattern)) @@ -26,15 +27,15 @@ def test_fnmatch(self): check('abc', '*') check('abc', 'ab[cd]') check('abc', 'ab[!de]') - check('abc', 'ab[de]', 0) - check('a', '??', 0) - check('a', 'b', 0) + check('abc', 'ab[de]', False) + check('a', '??', False) + check('a', 'b', False) # these test that '\' is handled correctly in character sets; # see SF bug #409651 check('\\', r'[\]') check('a', r'[!\]') - check('\\', r'[!\]', 0) + check('\\', r'[!\]', False) # test that filenames with newlines in them are handled correctly. # http://bugs.python.org/issue6665 @@ -51,14 +52,38 @@ def test_mix_bytes_str(self): def test_fnmatchcase(self): check = self.check_match - check('AbC', 'abc', 0, fnmatchcase) - check('abc', 'AbC', 0, fnmatchcase) + check('abc', 'abc', True, fnmatchcase) + check('AbC', 'abc', False, fnmatchcase) + check('abc', 'AbC', False, fnmatchcase) + check('AbC', 'AbC', True, fnmatchcase) + + check('usr/bin', 'usr/bin', True, fnmatchcase) + check('usr\\bin', 'usr/bin', False, fnmatchcase) + check('usr/bin', 'usr\\bin', False, fnmatchcase) + check('usr\\bin', 'usr\\bin', True, fnmatchcase) def test_bytes(self): self.check_match(b'test', b'te*') self.check_match(b'test\xff', b'te*\xff') self.check_match(b'foo\nbar', b'foo*') + def test_case(self): + ignorecase = os.path.normcase('ABC') == os.path.normcase('abc') + check = self.check_match + check('abc', 'abc') + check('AbC', 'abc', ignorecase) + check('abc', 'AbC', ignorecase) + check('AbC', 'AbC') + + def test_sep(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + check = self.check_match + check('usr/bin', 'usr/bin') + check('usr\\bin', 'usr/bin', normsep) + check('usr/bin', 'usr\\bin', normsep) + check('usr\\bin', 'usr\\bin') + + class TranslateTestCase(unittest.TestCase): def test_translate(self): @@ -75,7 +100,28 @@ def test_translate(self): class FilterTestCase(unittest.TestCase): def test_filter(self): - self.assertEqual(filter(['a', 'b'], 'a'), ['a']) + self.assertEqual(filter(['Python', 'Ruby', 'Perl', 'Tcl'], 'P*'), + ['Python', 'Perl']) + self.assertEqual(filter([b'Python', b'Ruby', b'Perl', b'Tcl'], b'P*'), + [b'Python', b'Perl']) + + def test_mix_bytes_str(self): + self.assertRaises(TypeError, filter, ['test'], b'*') + self.assertRaises(TypeError, filter, [b'test'], '*') + + def test_case(self): + ignorecase = os.path.normcase('P') == os.path.normcase('p') + self.assertEqual(filter(['Test.py', 'Test.rb', 'Test.PL'], '*.p*'), + ['Test.py', 'Test.PL'] if ignorecase else ['Test.py']) + self.assertEqual(filter(['Test.py', 'Test.rb', 'Test.PL'], '*.P*'), + ['Test.py', 'Test.PL'] if ignorecase else ['Test.PL']) + + def test_sep(self): + normsep = os.path.normcase('\\') == os.path.normcase('/') + self.assertEqual(filter(['usr/bin', 'usr', 'usr\\lib'], 'usr/*'), + ['usr/bin', 'usr\\lib'] if normsep else ['usr/bin']) + self.assertEqual(filter(['usr/bin', 'usr', 'usr\\lib'], 'usr\\*'), + ['usr/bin', 'usr\\lib'] if normsep else ['usr\\lib']) if __name__ == "__main__": From 65440f8278351e16350be716dff61f5f786f7060 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Tue, 23 May 2017 01:02:33 +0800 Subject: [PATCH 221/340] bpo-30003: Fix handling escape characters in HZ codec (#1556) (#1718) --- Lib/test/test_codecencodings_cn.py | 4 ++++ Misc/NEWS | 3 +++ Modules/cjkcodecs/_codecs_cn.c | 25 ++++++++++++------------- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_codecencodings_cn.py b/Lib/test/test_codecencodings_cn.py index f135bb26e7b044..5101b5ceb1926b 100644 --- a/Lib/test/test_codecencodings_cn.py +++ b/Lib/test/test_codecencodings_cn.py @@ -87,6 +87,10 @@ class Test_HZ(multibytecodec_support.TestBase, unittest.TestCase): (b'ab~{\x81\x81\x41\x44~}cd', 'replace', 'ab\uFFFD\uFFFD\u804Acd'), (b'ab~{\x41\x44~}cd', 'replace', 'ab\u804Acd'), (b"ab~{\x79\x79\x41\x44~}cd", "replace", "ab\ufffd\ufffd\u804acd"), + # issue 30003 + ('ab~cd', 'strict', b'ab~~cd'), # escape ~ + (b'~{Dc~~:C~}', 'strict', None), # ~~ only in ASCII mode + (b'~{Dc~\n:C~}', 'strict', None), # ~\n only in ASCII mode ) if __name__ == "__main__": diff --git a/Misc/NEWS b/Misc/NEWS index 43e7748e48f142..823178d7090461 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-30003: Fix handling escape characters in HZ codec. Based on patch + by Ma Lin. + - bpo-30301: Fix AttributeError when using SimpleQueue.empty() under *spawn* and *forkserver* start methods. diff --git a/Modules/cjkcodecs/_codecs_cn.c b/Modules/cjkcodecs/_codecs_cn.c index bda175c55d1323..1fcc220b8db0f4 100644 --- a/Modules/cjkcodecs/_codecs_cn.c +++ b/Modules/cjkcodecs/_codecs_cn.c @@ -350,15 +350,17 @@ ENCODER(hz) DBCHAR code; if (c < 0x80) { - if (state->i == 0) { - WRITEBYTE1((unsigned char)c); - NEXT(1, 1); - } - else { - WRITEBYTE3('~', '}', (unsigned char)c); - NEXT(1, 3); + if (state->i) { + WRITEBYTE2('~', '}'); + NEXT_OUT(2); state->i = 0; } + WRITEBYTE1((unsigned char)c); + NEXT(1, 1); + if (c == '~') { + WRITEBYTE1('~'); + NEXT_OUT(1); + } continue; } @@ -409,17 +411,14 @@ DECODER(hz) unsigned char c2 = INBYTE2; REQUIRE_INBUF(2); - if (c2 == '~') { + if (c2 == '~' && state->i == 0) OUTCHAR('~'); - NEXT_IN(2); - continue; - } else if (c2 == '{' && state->i == 0) state->i = 1; /* set GB */ + else if (c2 == '\n' && state->i == 0) + ; /* line-continuation */ else if (c2 == '}' && state->i == 1) state->i = 0; /* set ASCII */ - else if (c2 == '\n') - ; /* line-continuation */ else return 1; NEXT_IN(2); From 1d359b8510b2030c103c840995e2388fbd8bdb30 Mon Sep 17 00:00:00 2001 From: delirious-lettuce Date: Mon, 22 May 2017 11:16:32 -0600 Subject: [PATCH 222/340] [3.5] Fix typos in multiple `.rst` files (GH-1668) (#1706) --- Doc/c-api/exceptions.rst | 8 ++++---- Doc/howto/logging-cookbook.rst | 2 +- Doc/library/cmd.rst | 4 ++-- Doc/library/email.contentmanager.rst | 6 +++--- Doc/library/email.errors.rst | 4 ++-- Doc/library/email.message.rst | 2 +- Doc/library/email.mime.rst | 2 +- Doc/library/email.policy.rst | 2 +- Doc/library/sunau.rst | 2 +- Doc/library/sys.rst | 2 +- Doc/library/turtle.rst | 2 +- Doc/library/xml.dom.pulldom.rst | 2 +- Lib/email/architecture.rst | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 2 +- 15 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Doc/c-api/exceptions.rst b/Doc/c-api/exceptions.rst index b8af52062b7226..6454eb5e9bdf76 100644 --- a/Doc/c-api/exceptions.rst +++ b/Doc/c-api/exceptions.rst @@ -295,7 +295,7 @@ an error value). :c:data:`PyExc_Warning` is a subclass of :c:data:`PyExc_Exception`; the default warning category is :c:data:`PyExc_RuntimeWarning`. The standard Python warning categories are available as global variables whose names are - enumerated at :ref:`standarwarningcategories`. + enumerated at :ref:`standardwarningcategories`. For information about warning control, see the documentation for the :mod:`warnings` module and the :option:`-W` option in the command line @@ -937,7 +937,7 @@ Notes: Only defined on Windows; protect code that uses this by testing that the preprocessor macro ``MS_WINDOWS`` is defined. -.. _standarwarningcategories: +.. _standardwarningcategories: Standard Warning Categories =========================== @@ -950,7 +950,7 @@ the variables: .. index:: single: PyExc_Warning single: PyExc_BytesWarning - single: PyExc_DepricationWarning + single: PyExc_DeprecationWarning single: PyExc_FutureWarning single: PyExc_ImportWarning single: PyExc_PendingDeprecationWarning @@ -973,7 +973,7 @@ the variables: +------------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ImportWarning` | :exc:`ImportWarning` | | +------------------------------------------+---------------------------------+----------+ -| :c:data:`PyExc_PendingDepricationWarning`| :exc:`PendingDeprecationWarning`| | +| :c:data:`PyExc_PendingDeprecationWarning`| :exc:`PendingDeprecationWarning`| | +------------------------------------------+---------------------------------+----------+ | :c:data:`PyExc_ResourceWarning` | :exc:`ResourceWarning` | | +------------------------------------------+---------------------------------+----------+ diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst index bb79bb1748fb9c..6498ea56957719 100644 --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -1683,7 +1683,7 @@ Implementing structured logging ------------------------------- Although most logging messages are intended for reading by humans, and thus not -readily machine-parseable, there might be cirumstances where you want to output +readily machine-parseable, there might be circumstances where you want to output messages in a structured format which *is* capable of being parsed by a program (without needing complex regular expressions to parse the log message). This is straightforward to achieve using the logging package. There are a number of diff --git a/Doc/library/cmd.rst b/Doc/library/cmd.rst index f40cfdfd592163..3b4a8ff440e7ae 100644 --- a/Doc/library/cmd.rst +++ b/Doc/library/cmd.rst @@ -266,10 +266,10 @@ immediate playback:: 'Draw circle with given radius an options extent and steps: CIRCLE 50' circle(*parse(arg)) def do_position(self, arg): - 'Print the current turle position: POSITION' + 'Print the current turtle position: POSITION' print('Current position is %d %d\n' % position()) def do_heading(self, arg): - 'Print the current turle heading in degrees: HEADING' + 'Print the current turtle heading in degrees: HEADING' print('Current heading is %d\n' % (heading(),)) def do_color(self, arg): 'Set the color: COLOR BLUE' diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index a9c078bd60bad6..5302b1227c83f3 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -62,7 +62,7 @@ this module. .. class:: EmailMessage(policy=default) If *policy* is specified (it must be an instance of a :mod:`~email.policy` - class) use the rules it specifies to udpate and serialize the representation + class) use the rules it specifies to update and serialize the representation of the message. If *policy* is not set, use the :class:`~email.policy.default` policy, which follows the rules of the email RFCs except for line endings (instead of the RFC mandated ``\r\n``, it uses @@ -108,7 +108,7 @@ this module. the part a candidate match if the value of the header is ``inline``. If none of the candidates matches any of the preferences in - *preferneclist*, return ``None``. + *preferencelist*, return ``None``. Notes: (1) For most applications the only *preferencelist* combinations that really make sense are ``('plain',)``, ``('html', 'plain')``, and the @@ -396,7 +396,7 @@ Currently the email package provides only one concrete content manager, MIME charset name, use the standard charset instead. If *cte* is set, encode the payload using the specified content transfer - encoding, and set the :mailheader:`Content-Transfer-Endcoding` header to + encoding, and set the :mailheader:`Content-Transfer-Encoding` header to that value. For ``str`` objects, if it is not set use heuristics to determine the most compact encoding. Possible values for *cte* are ``quoted-printable``, ``base64``, ``7bit``, ``8bit``, and ``binary``. diff --git a/Doc/library/email.errors.rst b/Doc/library/email.errors.rst index 8470783e816bfd..b5b78f344da256 100644 --- a/Doc/library/email.errors.rst +++ b/Doc/library/email.errors.rst @@ -108,9 +108,9 @@ this class is *not* an exception! return false even though its content type claims to be :mimetype:`multipart`. * :class:`InvalidBase64PaddingDefect` -- When decoding a block of base64 - enocded bytes, the padding was not correct. Enough padding is added to + encoded bytes, the padding was not correct. Enough padding is added to perform the decode, but the resulting decoded bytes may be invalid. * :class:`InvalidBase64CharactersDefect` -- When decoding a block of base64 - enocded bytes, characters outside the base64 alphebet were encountered. + encoded bytes, characters outside the base64 alphabet were encountered. The characters are ignored, but the resulting decoded bytes may be invalid. diff --git a/Doc/library/email.message.rst b/Doc/library/email.message.rst index 2907975357c00a..3dae8a991d5feb 100644 --- a/Doc/library/email.message.rst +++ b/Doc/library/email.message.rst @@ -50,7 +50,7 @@ Here are the methods of the :class:`Message` class: Return the entire message flattened as a string. When optional *unixfrom* is true, the envelope header is included in the returned string. - *unixfrom* defaults to ``False``. For backward compabitility reasons, + *unixfrom* defaults to ``False``. For backward compatibility reasons, *maxheaderlen* defaults to ``0``, so if you want a different value you must override it explicitly (the value specified for *max_line_length* in the policy will be ignored by this method). The *policy* argument may be diff --git a/Doc/library/email.mime.rst b/Doc/library/email.mime.rst index 8297deaf93aa16..bd007c04c5fa81 100644 --- a/Doc/library/email.mime.rst +++ b/Doc/library/email.mime.rst @@ -203,7 +203,7 @@ Here are the classes: Unless the *_charset* argument is explicitly set to ``None``, the MIMEText object created will have both a :mailheader:`Content-Type` header - with a ``charset`` parameter, and a :mailheader:`Content-Transfer-Endcoding` + with a ``charset`` parameter, and a :mailheader:`Content-Transfer-Encoding` header. This means that a subsequent ``set_payload`` call will not result in an encoded payload, even if a charset is passed in the ``set_payload`` command. You can "reset" this behavior by deleting the diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index 2a6047d3a41d48..7010091b53c5aa 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -540,7 +540,7 @@ more closely to the RFCs relevant to their domains. The same as ``SMTP`` except that :attr:`~EmailPolicy.utf8` is ``True``. Useful for serializing messages to a message store without using encoded - words in the headers. Should only be used for SMTP trasmission if the + words in the headers. Should only be used for SMTP transmission if the sender or recipient addresses have non-ASCII characters (the :meth:`smtplib.SMTP.send_message` method handles this automatically). diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst index 1ecc7a7cf92bd0..c8357e4fcc85e2 100644 --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -118,7 +118,7 @@ AU_read objects, as returned by :func:`.open` above, have the following methods: .. method:: AU_read.getnchannels() - Returns number of audio channels (1 for mone, 2 for stereo). + Returns number of audio channels (1 for mono, 2 for stereo). .. method:: AU_read.getsampwidth() diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index d28ea5db9272a4..c2a1109fe31d39 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -1220,7 +1220,7 @@ always available. | | * ``None`` if this information is unknown | +------------------+---------------------------------------------------------+ | :const:`version` | Name and version of the thread library. It is a string, | - | | or ``None`` if these informations are unknown. | + | | or ``None`` if this information is unknown. | +------------------+---------------------------------------------------------+ .. versionadded:: 3.3 diff --git a/Doc/library/turtle.rst b/Doc/library/turtle.rst index 1986972549c503..31761be02b78ee 100644 --- a/Doc/library/turtle.rst +++ b/Doc/library/turtle.rst @@ -1797,7 +1797,7 @@ Input methods :param prompt: string Pop up a dialog window for input of a string. Parameter title is - the title of the dialog window, propmt is a text mostly describing + the title of the dialog window, prompt is a text mostly describing what information to input. Return the string input. If the dialog is canceled, return ``None``. :: diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst index b50255434de945..5c0f469ad7a5cf 100644 --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -108,7 +108,7 @@ DOMEventStream Objects :class:`xml.dom.minidom.Element` if event equals :data:`START_ELEMENT` or :data:`END_ELEMENT` or :class:`xml.dom.minidom.Text` if event equals :data:`CHARACTERS`. - The current node does not contain informations about its children, unless + The current node does not contain information about its children, unless :func:`expandNode` is called. .. method:: expandNode(node) diff --git a/Lib/email/architecture.rst b/Lib/email/architecture.rst index 78572ae63b4d2b..fcd10bde1325bb 100644 --- a/Lib/email/architecture.rst +++ b/Lib/email/architecture.rst @@ -66,7 +66,7 @@ data payloads. Message Lifecycle ----------------- -The general lifecyle of a message is: +The general lifecycle of a message is: Creation A `Message` object can be created by a Parser, or it can be diff --git a/Misc/HISTORY b/Misc/HISTORY index 9655d4cd40d9a3..38f3db5c6a0c5a 100644 --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -3285,7 +3285,7 @@ Library - Issue #11382: Trivial system calls, such as dup() or pipe(), needn't release the GIL. Patch by Charles-François Natali. -- Issue #11223: Add threading._info() function providing informations about +- Issue #11223: Add threading._info() function providing information about the thread implementation. - Issue #11731: simplify/enhance email parser/generator API by introducing diff --git a/Misc/NEWS b/Misc/NEWS index 823178d7090461..23eed2a9b0f464 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -7248,7 +7248,7 @@ Library - Issue #17702: On error, os.environb now suppresses the exception context when raising a new KeyError with the original key. -- Issue #16809: Fixed some tkinter incompabilities with Tcl/Tk 8.6. +- Issue #16809: Fixed some tkinter incompatibilities with Tcl/Tk 8.6. - Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj argument. From 32dcf426ad2ae10e24e92f60e99dbb4939fb2021 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 22 May 2017 22:27:10 -0700 Subject: [PATCH 223/340] [3.5] bpo-21056: Document return type of next method of csv reader (GH-146) (#1750) (cherry picked from commit d618c8c6d31b9b288f8a070417683974eb98e3ba) --- Doc/library/csv.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/library/csv.rst b/Doc/library/csv.rst index 7fb4fc8256aca3..21353e35ad7dd2 100644 --- a/Doc/library/csv.rst +++ b/Doc/library/csv.rst @@ -390,8 +390,10 @@ Reader objects (:class:`DictReader` instances and objects returned by the .. method:: csvreader.__next__() - Return the next row of the reader's iterable object as a list, parsed according - to the current dialect. Usually you should call this as ``next(reader)``. + Return the next row of the reader's iterable object as a list (if the object + was returned from :func:`reader`) or a dict (if it is a :class:`DictReader` + instance), parsed according to the current dialect. Usually you should call + this as ``next(reader)``. Reader objects have the following public attributes: From b090349b6a7011fdd3470de0c4a181f871d60572 Mon Sep 17 00:00:00 2001 From: Vijay Kumar Date: Tue, 23 May 2017 11:45:03 +0530 Subject: [PATCH 224/340] Fix spelling mistakes in tkinter.py (#1752) Ran the docstrings through spell checker, and fixed spelling issues. --- Lib/tkinter/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 1eaab44bfed352..1a3bf889677807 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -865,7 +865,7 @@ def winfo_ismapped(self): return self.tk.getint( self.tk.call('winfo', 'ismapped', self._w)) def winfo_manager(self): - """Return the window mananger name for this widget.""" + """Return the window manager name for this widget.""" return self.tk.call('winfo', 'manager', self._w) def winfo_name(self): """Return the name of this widget.""" @@ -1539,7 +1539,7 @@ def image_names(self): return self.tk.splitlist(self.tk.call('image', 'names')) def image_types(self): - """Return a list of all available image types (e.g. phote bitmap).""" + """Return a list of all available image types (e.g. photo bitmap).""" return self.tk.splitlist(self.tk.call('image', 'types')) @@ -1678,7 +1678,7 @@ def wm_focusmodel(self, model=None): return self.tk.call('wm', 'focusmodel', self._w, model) focusmodel = wm_focusmodel def wm_forget(self, window): # new in Tk 8.5 - """The window will be unmappend from the screen and will no longer + """The window will be unmapped from the screen and will no longer be managed by wm. toplevel windows will be treated like frame windows once they are no longer managed by wm, however, the menu option configuration will be remembered and the menus will return @@ -2382,7 +2382,7 @@ def find_closest(self, x, y, halo=None, start=None): """Return item which is closest to pixel at X, Y. If several match take the top-most. All items closer than HALO are considered overlapping (all are - closests). If START is specified the next below this tag is taken.""" + closest). If START is specified the next below this tag is taken.""" return self.find('closest', x, y, halo, start) def find_enclosed(self, x1, y1, x2, y2): """Return all items in rectangle defined @@ -2442,7 +2442,7 @@ def postscript(self, cnf={}, **kw): """Print the contents of the canvas to a postscript file. Valid options: colormap, colormode, file, fontmap, height, pageanchor, pageheight, pagewidth, pagex, pagey, - rotate, witdh, x, y.""" + rotate, width, x, y.""" return self.tk.call((self._w, 'postscript') + self._options(cnf, kw)) def tag_raise(self, *args): @@ -3386,7 +3386,7 @@ def height(self): return self.tk.getint( self.tk.call('image', 'height', self.name)) def type(self): - """Return the type of the imgage, e.g. "photo" or "bitmap".""" + """Return the type of the image, e.g. "photo" or "bitmap".""" return self.tk.call('image', 'type', self.name) def width(self): """Return the width of the image.""" From 219ed80637102127786d67464822a9ec5878aaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Tue, 23 May 2017 00:36:18 -0700 Subject: [PATCH 225/340] [3.5] call remove_done_callback in finally section (GH-1688) (#1758) (cherry picked from commit 21b3e04c13212b29e8c35ffc36eed8603fde08f4) --- Lib/asyncio/base_events.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 50153f8d4bd291..26a6f1ef859f2d 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -459,7 +459,8 @@ def run_until_complete(self, future): # local task. future.exception() raise - future.remove_done_callback(_run_until_complete_cb) + finally: + future.remove_done_callback(_run_until_complete_cb) if not future.done(): raise RuntimeError('Event loop stopped before Future completed.') From 8af0a214be7c0c921ba5ce5c11043dd5b5da9211 Mon Sep 17 00:00:00 2001 From: Kushal Das Date: Tue, 23 May 2017 09:56:45 -0700 Subject: [PATCH 226/340] [3.5] bpo-30376: Update outdated WindowObject references (GH-1630) (#1747) (cherry picked from commit 93fc20b73eea3da0b6305aaee951e5dd22d5c408) --- Doc/library/curses.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index d51085506c2a96..3442e4e75a3e45 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -290,8 +290,8 @@ The module :mod:`curses` defines the following functions: .. function:: initscr() - Initialize the library. Return a :class:`WindowObject` which represents the - whole screen. + Initialize the library. Return a :ref:`window ` object + which represents the whole screen. .. note:: @@ -383,8 +383,8 @@ The module :mod:`curses` defines the following functions: .. function:: newwin(nlines, ncols) newwin(nlines, ncols, begin_y, begin_x) - Return a new window, whose left-upper corner is at ``(begin_y, begin_x)``, and - whose height/width is *nlines*/*ncols*. + Return a new :ref:`window `, whose left-upper corner + is at ``(begin_y, begin_x)``, and whose height/width is *nlines*/*ncols*. By default, the window will extend from the specified position to the lower right corner of the screen. @@ -1679,10 +1679,10 @@ You can instantiate a :class:`Textbox` object as follows: .. class:: Textbox(win) Return a textbox widget object. The *win* argument should be a curses - :class:`WindowObject` in which the textbox is to be contained. The edit cursor - of the textbox is initially located at the upper left hand corner of the - containing window, with coordinates ``(0, 0)``. The instance's - :attr:`stripspaces` flag is initially on. + :ref:`window ` object in which the textbox is to + be contained. The edit cursor of the textbox is initially located at the + upper left hand corner of the containing window, with coordinates ``(0, 0)``. + The instance's :attr:`stripspaces` flag is initially on. :class:`Textbox` objects have the following methods: From ebbefae14039aa86d4c8a7cfab8f2b5a3ef0d241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Wirtel?= Date: Wed, 24 May 2017 20:49:24 +0200 Subject: [PATCH 227/340] bpo-30394: Fix a socket leak in smtplib.SMTP.__init__() (#1700) (#1789) --- Lib/smtplib.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 5b9e66536a899c..ab3197cc12dcd7 100755 --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -250,6 +250,7 @@ def __init__(self, host='', port=0, local_hostname=None, if host: (code, msg) = self.connect(host, port) if code != 220: + self.close() raise SMTPConnectError(code, msg) if local_hostname is not None: self.local_hostname = local_hostname From aa27f0e94f4d9c5ef589984dc2b32d856e8e038f Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Wed, 24 May 2017 16:11:21 -0500 Subject: [PATCH 228/340] [3.5] bpo-30160: Clarify intended usage of wfile (gh-1300) (GH-1792) The library does not enforce compliance with the HTTP protocol, so violations are not technically disallowed. Extend the stream's description to avoid suggesting that intentional protocol violations are not supported. (cherry picked from commit a083c8e) --- Doc/library/http.server.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst index ae7fb970de1ec4..6e71c8a881118a 100644 --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -105,7 +105,8 @@ of which this module provides three different variants: Contains the output stream for writing a response back to the client. Proper adherence to the HTTP protocol must be used when writing to - this stream. + this stream in order to achieve successful interoperation with HTTP + clients. :class:`BaseHTTPRequestHandler` has the following attributes: From 89004d761361332314beb08b443bff5b092ec36e Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Thu, 25 May 2017 17:19:10 +0200 Subject: [PATCH 229/340] [3.5] bpo-30414: multiprocessing.Queue._feed do not break from main loop on exc (GH-1683) (#1816) * bpo-30414: multiprocesing.Queue._feed do not break from main loop on exc Queue background running thread was not handling exceptions correctly. Any exception occurred inside thread (putting unpickable object) cause feeder to finish running. After that every message put into queue is silently ignored. * bpo-30414: multiprocesing.Queue._feed do not break from main loop on exc Queue background running thread was not handling exceptions correctly. Any exception occurred inside thread (putting unpickable object) cause feeder to finish running. After that every message put into queue is silently ignored. (cherry picked from commit bc50f03db4f58c869b78e98468e374d7e61f1227) --- Lib/multiprocessing/queues.py | 22 ++++++++++------------ Lib/test/_test_multiprocessing.py | 14 ++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index 40ae10a88c1508..2c888c00e7c298 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -221,8 +221,8 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): else: wacquire = None - try: - while 1: + while 1: + try: nacquire() try: if not buffer: @@ -249,21 +249,19 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): wrelease() except IndexError: pass - except Exception as e: - if ignore_epipe and getattr(e, 'errno', 0) == errno.EPIPE: - return - # Since this runs in a daemon thread the resources it uses - # may be become unusable while the process is cleaning up. - # We ignore errors which happen after the process has - # started to cleanup. - try: + except Exception as e: + if ignore_epipe and getattr(e, 'errno', 0) == errno.EPIPE: + return + # Since this runs in a daemon thread the resources it uses + # may be become unusable while the process is cleaning up. + # We ignore errors which happen after the process has + # started to cleanup. if is_exiting(): info('error in queue thread: %s', e) + return else: import traceback traceback.print_exc() - except Exception: - pass _sentinel = object() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 040212889486ec..b24e7d6c32df1d 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -752,6 +752,20 @@ def test_timeout(self): # Windows (usually 15.6 ms) self.assertGreaterEqual(delta, 0.170) + def test_queue_feeder_donot_stop_onexc(self): + # bpo-30414: verify feeder handles exceptions correctly + if self.TYPE != 'processes': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + class NotSerializable(object): + def __reduce__(self): + raise AttributeError + with test.support.captured_stderr(): + q = self.Queue() + q.put(NotSerializable()) + q.put(True) + self.assertTrue(q.get(timeout=0.1)) + # # # diff --git a/Misc/NEWS b/Misc/NEWS index 23eed2a9b0f464..5aed87a30a72d4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-30414: multiprocessing.Queue._feed background running + thread do not break from main loop on exception. + - bpo-30003: Fix handling escape characters in HZ codec. Based on patch by Ma Lin. From d78ad17836cc4288b6bd0e3112da040ead6e9fbe Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 27 May 2017 16:37:25 +0300 Subject: [PATCH 230/340] [3.5] Fix the signature of JSONDecodeError (no end parameter). (GH-1827) (#1829) Unlikely to the simplejson module, json.JSONDecodeError doesn't accept the end argument. (cherry picked from commit 5becf38) --- Doc/library/json.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/json.rst b/Doc/library/json.rst index 517f9cecfd7814..30c2911d901a86 100644 --- a/Doc/library/json.rst +++ b/Doc/library/json.rst @@ -485,7 +485,7 @@ Encoders and Decoders Exceptions ---------- -.. exception:: JSONDecodeError(msg, doc, pos, end=None) +.. exception:: JSONDecodeError(msg, doc, pos) Subclass of :exc:`ValueError` with the following additional attributes: From a815b5a100f38b883b08d39567c5557de2c19a53 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 27 May 2017 16:38:12 +0300 Subject: [PATCH 231/340] [3.5] bpo-30398: Add a docstring for re.error. (GH-1647) (#1831) Also document that some attributes may be None. (cherry picked from commit 12d6b5d) --- Doc/library/re.rst | 6 +++--- Lib/sre_constants.py | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst index d33fff8ef3217b..26d25582c72a86 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -815,15 +815,15 @@ form. .. attribute:: pos - The index of *pattern* where compilation failed. + The index in *pattern* where compilation failed (may be ``None``). .. attribute:: lineno - The line corresponding to *pos*. + The line corresponding to *pos* (may be ``None``). .. attribute:: colno - The column corresponding to *pos*. + The column corresponding to *pos* (may be ``None``). .. versionchanged:: 3.5 Added additional attributes. diff --git a/Lib/sre_constants.py b/Lib/sre_constants.py index fc684ae96fd30a..a6e8a1f08d68a8 100644 --- a/Lib/sre_constants.py +++ b/Lib/sre_constants.py @@ -21,6 +21,17 @@ # should this really be here? class error(Exception): + """Exception raised for invalid regular expressions. + + Attributes: + + msg: The unformatted error message + pattern: The regular expression pattern + pos: The index in the pattern where compilation failed (may be None) + lineno: The line corresponding to pos (may be None) + colno: The column corresponding to pos (may be None) + """ + def __init__(self, msg, pattern=None, pos=None): self.msg = msg self.pattern = pattern From 440bc4f4b2690b99541e87bedfdb0dc4abbc0501 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 27 May 2017 07:19:40 -0700 Subject: [PATCH 232/340] =?UTF-8?q?[3.5]=20bpo-29960=20=5Frandom.Random=20?= =?UTF-8?q?corrupted=20on=20exception=20in=20setstate().=20=E2=80=A6=20(#1?= =?UTF-8?q?288)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 9616a82e7802241a4b74cf7ae38d43c37bf66e48) --- Lib/test/test_random.py | 5 +++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ Modules/_randommodule.c | 5 ++++- 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index e80ed17a8cb6bc..83a663faf96453 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -348,6 +348,7 @@ def test_setstate_first_arg(self): self.assertRaises(ValueError, self.gen.setstate, (1, None, None)) def test_setstate_middle_arg(self): + start_state = self.gen.getstate() # Wrong type, s/b tuple self.assertRaises(TypeError, self.gen.setstate, (2, None, None)) # Wrong length, s/b 625 @@ -361,6 +362,10 @@ def test_setstate_middle_arg(self): self.gen.setstate((2, (1,)*624+(625,), None)) with self.assertRaises((ValueError, OverflowError)): self.gen.setstate((2, (1,)*624+(-1,), None)) + # Failed calls to setstate() should not have changed the state. + bits100 = self.gen.getrandbits(100) + self.gen.setstate(start_state) + self.assertEqual(self.gen.getrandbits(100), bits100) # Little trick to make "tuple(x % (2**32) for x in internalstate)" # raise ValueError. I cannot think of a simple way to achieve this, so diff --git a/Misc/ACKS b/Misc/ACKS index d91d9c1ee0d641..53f6879535b84d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1090,6 +1090,7 @@ Milan Oberkirch Pascal Oberndoerfer Jeffrey Ollie Adam Olsen +Bryan Olson Grant Olson Koray Oner Piet van Oostrum diff --git a/Misc/NEWS b/Misc/NEWS index 5aed87a30a72d4..f399734c71c81e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-29960: Preserve generator state when _random.Random.setstate() + raises an exception. Patch by Bryan Olson. + - bpo-30414: multiprocessing.Queue._feed background running thread do not break from main loop on exception. diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c index 9ce788289572c7..acb116d2bf2125 100644 --- a/Modules/_randommodule.c +++ b/Modules/_randommodule.c @@ -313,6 +313,7 @@ random_setstate(RandomObject *self, PyObject *state) int i; unsigned long element; long index; + PY_UINT32_T new_state[N]; if (!PyTuple_Check(state)) { PyErr_SetString(PyExc_TypeError, @@ -329,7 +330,7 @@ random_setstate(RandomObject *self, PyObject *state) element = PyLong_AsUnsignedLong(PyTuple_GET_ITEM(state, i)); if (element == (unsigned long)-1 && PyErr_Occurred()) return NULL; - self->state[i] = (PY_UINT32_T)element; + new_state[i] = (PY_UINT32_T)element; } index = PyLong_AsLong(PyTuple_GET_ITEM(state, i)); @@ -340,6 +341,8 @@ random_setstate(RandomObject *self, PyObject *state) return NULL; } self->index = (int)index; + for (i = 0; i < N; i++) + self->state[i] = new_state[i]; Py_INCREF(Py_None); return Py_None; From 03c7cfcd52be702957cc174f5cb2ce4c8be8bfca Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 29 May 2017 15:20:47 -0700 Subject: [PATCH 233/340] [3.5] bpo-30361: Use better example for mixed-type operands (GH-1701) (#1857) (cherry picked from commit e405d4b8dfb8b497e1c3d1f0f8e28030040c165e) --- Doc/tutorial/introduction.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst index af277cec19bb7f..85ba896eaa8ed5 100644 --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -100,10 +100,8 @@ give you an error:: There is full support for floating point; operators with mixed type operands convert the integer operand to floating point:: - >>> 3 * 3.75 / 1.5 - 7.5 - >>> 7.0 / 2 - 3.5 + >>> 4 * 3.75 - 1 + 14.0 In interactive mode, the last printed expression is assigned to the variable ``_``. This means that when you are using Python as a desk calculator, it is From 75ea91bb736f2a061a3ebc689ff17629bdc15568 Mon Sep 17 00:00:00 2001 From: csabella Date: Tue, 30 May 2017 16:47:47 -0400 Subject: [PATCH 234/340] bpo-30354: Update data model documentation for super() (GH-1561) (GH-1869) The data model section of the language reference was written well before the zero-argument form of super() was added. To avoid giving the impression that they're doing something unusual, this updates the description of `__new__` and `__init__` to use the zero-argument form. Patch by Cheryl Sabella. (cherry picked from commit 12b1c180986fc744331b8f30d3d2f49a0fdb43dd) --- Doc/reference/datamodel.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 0d108d727e7a19..d015da22888833 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -1088,9 +1088,9 @@ Basic customization (usually an instance of *cls*). Typical implementations create a new instance of the class by invoking the - superclass's :meth:`__new__` method using ``super(currentclass, - cls).__new__(cls[, ...])`` with appropriate arguments and then modifying the - newly-created instance as necessary before returning it. + superclass's :meth:`__new__` method using ``super().__new__(cls[, ...])`` + with appropriate arguments and then modifying the newly-created instance + as necessary before returning it. If :meth:`__new__` returns an instance of *cls*, then the new instance's :meth:`__init__` method will be invoked like ``__init__(self[, ...])``, where @@ -1114,7 +1114,7 @@ Basic customization class constructor expression. If a base class has an :meth:`__init__` method, the derived class's :meth:`__init__` method, if any, must explicitly call it to ensure proper initialization of the base class part of the - instance; for example: ``BaseClass.__init__(self, [args...])``. + instance; for example: ``super().__init__([args...])``. Because :meth:`__new__` and :meth:`__init__` work together in constructing objects (:meth:`__new__` to create it, and :meth:`__init__` to customize it), @@ -1538,8 +1538,8 @@ Class Binding ``A.__dict__['x'].__get__(None, A)``. Super Binding - If ``a`` is an instance of :class:`super`, then the binding ``super(B, - obj).m()`` searches ``obj.__class__.__mro__`` for the base class ``A`` + If ``a`` is an instance of :class:`super`, then the binding ``super(B, obj).m()`` + searches ``obj.__class__.__mro__`` for the base class ``A`` immediately preceding ``B`` and then invokes the descriptor with the call: ``A.__dict__['m'].__get__(obj, obj.__class__)``. From 32213d2beee2991e6cc5a07dd878793e0f191c5a Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 30 May 2017 15:29:07 -0700 Subject: [PATCH 235/340] Build docs in parallel (GH-1842) (GH-1871) (cherry picked from commit eba68e2c42e149acecb15bbeb692786e2540157d) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fe90bad626ce83..cf524e5549289b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,7 +41,7 @@ matrix: # (Updating the version is fine as long as no warnings are raised by doing so.) - python -m pip install sphinx~=1.6.1 script: - - make check suspicious html SPHINXOPTS="-q -W" + - make check suspicious html SPHINXOPTS="-q -W -j4" - os: linux language: c compiler: gcc From 99424d8f2a311916e1626c0420432453068b6169 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Tue, 30 May 2017 22:08:12 -0700 Subject: [PATCH 236/340] [3.5] Fix a trivial typo in global section (GH-1497) (GH-1881) (cherry picked from commit f34c6850203a2406c4950af7a9c8a134145df4ea) --- Doc/reference/simple_stmts.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/reference/simple_stmts.rst b/Doc/reference/simple_stmts.rst index d403c4d546edc1..35c823992aaa6a 100644 --- a/Doc/reference/simple_stmts.rst +++ b/Doc/reference/simple_stmts.rst @@ -872,7 +872,7 @@ definition, function definition, or :keyword:`import` statement. builtin: eval builtin: compile -**Programmer's note:** the :keyword:`global` is a directive to the parser. It +**Programmer's note:** :keyword:`global` is a directive to the parser. It applies only to code parsed at the same time as the :keyword:`global` statement. In particular, a :keyword:`global` statement contained in a string or code object supplied to the built-in :func:`exec` function does not affect the code From ec675d5245812128043d17c0f63ebfc57fe5e1e5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Wed, 31 May 2017 15:52:58 -0700 Subject: [PATCH 237/340] [3.5] Fix Travis config to reinstate test build (GH-1879) (GH-1890) (cherry picked from commit a5aa72ac789052411797c6f079ffff0a9fdbf82c) --- .travis.yml | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index cf524e5549289b..e4e7b3d9b0246a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,25 +11,19 @@ branches: - master - /^\d\.\d$/ -os: - - linux - # macOS builds are disabled as the machines are under-provisioned on Travis, - # adding up to an extra hour completing a full CI run. - -compiler: - - clang - # gcc also works, but to keep the # of concurrent builds down, we use one C - # compiler here and the other to run the coverage build. - -env: - - TESTING=cpython - matrix: fast_finish: true allow_failures: - env: - TESTING=coverage include: + - os: linux + language: c + compiler: clang + # gcc also works, but to keep the # of concurrent builds down, we use one C + # compiler here and the other to run the coverage build. + env: + - TESTING=cpython - os: linux language: python python: 3.6 From 958e815fe014e9a3c64f3568b883c2a7b32a4e2e Mon Sep 17 00:00:00 2001 From: csabella Date: Wed, 31 May 2017 21:53:08 -0400 Subject: [PATCH 238/340] bpo-27618: Clarify that threading.Lock is a factory function (GH-1307) (GH-1895) (cherry picked from commit 56ddfd2eea4d98456a9a99bf2a718f21ee6b2be2) --- Doc/library/threading.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/library/threading.rst b/Doc/library/threading.rst index 2792dfdce04c6c..cda859fe4cbd3a 100644 --- a/Doc/library/threading.rst +++ b/Doc/library/threading.rst @@ -371,8 +371,9 @@ All methods are executed atomically. lock, subsequent attempts to acquire it block, until it is released; any thread may release it. - .. versionchanged:: 3.3 - Changed from a factory function to a class. + Note that ``Lock`` is actually a factory function which returns an instance + of the most efficient version of the concrete Lock class that is supported + by the platform. .. method:: acquire(blocking=True, timeout=-1) From 1721b06a78a4fd7942d9658ac8add6911a1a03e3 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 31 May 2017 19:48:28 -0700 Subject: [PATCH 239/340] bpo-22702: Clarify documentation of str.join & bytes.join (GH-156) (GH-1896) The "iterable iterable" phrasing created confusion between the term reference and the parameter name. This simplifies the phrasing to just use the parameter name without linking directly to the term definition. (cherry picked from commit 08e2f355d04d3cbea5751ce1275306ee3f569b32) --- Doc/library/stdtypes.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 85fafa757ea50a..87d8eb83e0e282 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -1714,10 +1714,10 @@ expression support in the :mod:`re` module). .. method:: str.join(iterable) - Return a string which is the concatenation of the strings in the - :term:`iterable` *iterable*. A :exc:`TypeError` will be raised if there are - any non-string values in *iterable*, including :class:`bytes` objects. The - separator between elements is the string providing this method. + Return a string which is the concatenation of the strings in *iterable*. + A :exc:`TypeError` will be raised if there are any non-string values in + *iterable*, including :class:`bytes` objects. The separator between + elements is the string providing this method. .. method:: str.ljust(width[, fillchar]) @@ -2533,11 +2533,11 @@ arbitrary binary data. bytearray.join(iterable) Return a bytes or bytearray object which is the concatenation of the - binary data sequences in the :term:`iterable` *iterable*. A - :exc:`TypeError` will be raised if there are any values in *iterable* - that are not :term:`bytes-like objects `, including - :class:`str` objects. The separator between elements is the contents - of the bytes or bytearray object providing this method. + binary data sequences in *iterable*. A :exc:`TypeError` will be raised + if there are any values in *iterable* that are not :term:`bytes-like + objects `, including :class:`str` objects. The + separator between elements is the contents of the bytes or + bytearray object providing this method. .. staticmethod:: bytes.maketrans(from, to) From 3419fc2bf1e81d42ef4578e59d3c10f9c239e80f Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 1 Jun 2017 07:12:09 -0700 Subject: [PATCH 240/340] bpo-30499: Remove a deprecated note about sets. (GH-1848) (GH-1906) (cherry picked from commit 0737ee20671d60802a7ef40f653fe449f1921de0) --- Doc/library/stdtypes.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index 87d8eb83e0e282..c4588f2438b8ea 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -3973,9 +3973,7 @@ The constructors for both classes work the same: Note, the *elem* argument to the :meth:`__contains__`, :meth:`remove`, and :meth:`discard` methods may be a set. To support searching for an equivalent - frozenset, the *elem* set is temporarily mutated during the search and then - restored. During the search, the *elem* set should not be read or mutated - since it does not have a meaningful value. + frozenset, a temporary one is created from *elem*. .. _typesmapping: From e20d22671996712eac416dd7bda79b5344d81164 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Thu, 1 Jun 2017 22:19:58 +0800 Subject: [PATCH 241/340] bpo-30378: Fix the problem that SysLogHandler can't handle IPv6 addresses (#1676) (#1902) --- Lib/logging/handlers.py | 25 ++++++++++++++++++++----- Lib/test/test_logging.py | 22 ++++++++++++++++++++-- Misc/NEWS | 3 +++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index e3463312f94065..b9d6e37857ac0e 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -815,11 +815,26 @@ def __init__(self, address=('localhost', SYSLOG_UDP_PORT), self.unixsocket = False if socktype is None: socktype = socket.SOCK_DGRAM - self.socket = socket.socket(socket.AF_INET, socktype) - if socktype == socket.SOCK_STREAM: - self.socket.connect(address) + host, port = address + ress = socket.getaddrinfo(host, port, 0, socktype) + if not ress: + raise OSError("getaddrinfo returns an empty list") + for res in ress: + af, socktype, proto, _, sa = res + err = sock = None + try: + sock = socket.socket(af, socktype, proto) + if socktype == socket.SOCK_STREAM: + sock.connect(sa) + break + except OSError as exc: + err = exc + if sock is not None: + sock.close() + if err is not None: + raise err + self.socket = sock self.socktype = socktype - self.formatter = None def _connect_unixsocket(self, address): use_socktype = self.socktype @@ -858,7 +873,7 @@ def encodePriority(self, facility, priority): priority = self.priority_names[priority] return (facility << 3) | priority - def close (self): + def close(self): """ Closes the socket. """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index dd7100c6161901..382714f1ae94b4 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1571,7 +1571,7 @@ def setUp(self): server.ready.wait() hcls = logging.handlers.SysLogHandler if isinstance(server.server_address, tuple): - self.sl_hdlr = hcls(('localhost', server.port)) + self.sl_hdlr = hcls((server.server_address[0], server.port)) else: self.sl_hdlr = hcls(server.server_address) self.log_output = '' @@ -1627,6 +1627,24 @@ def tearDown(self): SysLogHandlerTest.tearDown(self) os.remove(self.address) +@unittest.skipUnless(support.IPV6_ENABLED, + 'IPv6 support required for this test.') +@unittest.skipUnless(threading, 'Threading required for this test.') +class IPv6SysLogHandlerTest(SysLogHandlerTest): + + """Test for SysLogHandler with IPv6 host.""" + + server_class = TestUDPServer + address = ('::1', 0) + + def setUp(self): + self.server_class.address_family = socket.AF_INET6 + super(IPv6SysLogHandlerTest, self).setUp() + + def tearDown(self): + self.server_class.address_family = socket.AF_INET + super(IPv6SysLogHandlerTest, self).tearDown() + @unittest.skipUnless(threading, 'Threading required for this test.') class HTTPHandlerTest(BaseTest): """Test for HTTPHandler.""" @@ -4271,7 +4289,7 @@ def test_main(): QueueHandlerTest, ShutdownTest, ModuleLevelMiscTest, BasicConfigTest, LoggerAdapterTest, LoggerTest, SMTPHandlerTest, FileHandlerTest, RotatingFileHandlerTest, LastResortTest, LogRecordTest, - ExceptionTest, SysLogHandlerTest, HTTPHandlerTest, + ExceptionTest, SysLogHandlerTest, IPv6SysLogHandlerTest, HTTPHandlerTest, NTEventLogHandlerTest, TimedRotatingFileHandlerTest, UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest, ] diff --git a/Misc/NEWS b/Misc/NEWS index f399734c71c81e..997058b34a5592 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot + handle IPv6 addresses. + - bpo-29960: Preserve generator state when _random.Random.setstate() raises an exception. Patch by Bryan Olson. From cca3d4aa25a7aea0cda90dd2aa012f58c85e7e24 Mon Sep 17 00:00:00 2001 From: Matthias Bussonnier Date: Thu, 1 Jun 2017 20:26:57 -0700 Subject: [PATCH 242/340] bpo-29660: traceback: Document that etype is ignored in some places. (GH-344) (GH-1914) (cherry picked from commit cdb89cd) --- Doc/library/traceback.rst | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Doc/library/traceback.rst b/Doc/library/traceback.rst index 3c1d9bb51dc602..fc052f251b5298 100644 --- a/Doc/library/traceback.rst +++ b/Doc/library/traceback.rst @@ -45,9 +45,9 @@ The module defines the following functions: * if *tb* is not ``None``, it prints a header ``Traceback (most recent call last):`` * it prints the exception *etype* and *value* after the stack trace - * if *etype* is :exc:`SyntaxError` and *value* has the appropriate format, it - prints the line where the syntax error occurred with a caret indicating the - approximate position of the error. + * if *type(value)* is :exc:`SyntaxError` and *value* has the appropriate + format, it prints the line where the syntax error occurred with a caret + indicating the approximate position of the error. The optional *limit* argument has the same meaning as for :func:`print_tb`. If *chain* is true (the default), then chained exceptions (the @@ -55,6 +55,9 @@ The module defines the following functions: printed as well, like the interpreter itself does when printing an unhandled exception. + .. versionchanged:: 3.5 + The *etype* argument is ignored and inferred from the type of *value*. + .. function:: print_exc(limit=None, file=None, chain=True) @@ -131,6 +134,9 @@ The module defines the following functions: containing internal newlines. When these lines are concatenated and printed, exactly the same text is printed as does :func:`print_exception`. + .. versionchanged:: 3.5 + The *etype* argument is ignored and inferred from the type of *value*. + .. function:: format_exc(limit=None, chain=True) @@ -358,6 +364,7 @@ exception and traceback: print("*** print_tb:") traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) print("*** print_exception:") + # exc_type below is ignored on 3.5 and later traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2, file=sys.stdout) print("*** print_exc:") @@ -367,6 +374,7 @@ exception and traceback: print(formatted_lines[0]) print(formatted_lines[-1]) print("*** format_exception:") + # exc_type below is ignored on 3.5 and later print(repr(traceback.format_exception(exc_type, exc_value, exc_traceback))) print("*** extract_tb:") From 6d1e52bd6ed322b1bd8c3d1db683d0ceee8d9f61 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 3 Jun 2017 10:34:15 -0700 Subject: [PATCH 243/340] [3.5] Turn on macOS builds for Travis (GH-1846) (GH-1930) Initially the macOS builds are allowed to fail until such time that they can be determined to be stable and not add an unacceptable amount of time to the overall Travis-passing process. (cherry picked from commit 21c2dd7cf8414c903f0e83cf1d6b7f02f645f422) --- .travis.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index e4e7b3d9b0246a..4dfefb72700dbd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,21 +14,24 @@ branches: matrix: fast_finish: true allow_failures: - - env: - - TESTING=coverage + - env: OPTIONAL=true include: - os: linux language: c compiler: clang # gcc also works, but to keep the # of concurrent builds down, we use one C - # compiler here and the other to run the coverage build. - env: - - TESTING=cpython + # compiler here and the other to run the coverage build. Clang is preferred + # in this instance for its better error messages. + env: TESTING=cpython + - os: osx + language: c + compiler: clang + # Testing under macOS is optional until testing stability has been demonstrated. + env: OPTIONAL=true - os: linux language: python python: 3.6 - env: - - TESTING=docs + env: TESTING=docs before_script: - cd Doc # Sphinx is pinned so that new versions that introduce new warnings won't suddenly cause build failures. @@ -39,8 +42,7 @@ matrix: - os: linux language: c compiler: gcc - env: - - TESTING=coverage + env: OPTIONAL=true before_script: - | if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.(rst|yml)$)|(^Doc)/' From 6636e22002dbfd871b8bda617ca46512f5226b36 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 4 Jun 2017 17:19:32 -0500 Subject: [PATCH 244/340] [3.5] Fix skipping test_UNC_path on AppVeyor due to a different error being raised (GH-1920) We get `ERROR_BAD_NETPATH` (53) on AppVeyor which is translated to ENOENT (2). (cherry picked from commit 7a99625e0d95cd88ed8842d8677b5beea1fde5ae) --- Lib/test/test_import/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 1e33274b873f26..5d8b5621a37fa0 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -555,7 +555,7 @@ def test_UNC_path(self): try: os.listdir(unc) except OSError as e: - if e.errno in (errno.EPERM, errno.EACCES): + if e.errno in (errno.EPERM, errno.EACCES, errno.ENOENT): # See issue #15338 self.skipTest("cannot access administrative share %r" % (unc,)) raise From b9c4f3ce96991fda43caecfbf3aab7f9d47158ed Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 4 Jun 2017 19:51:30 -0500 Subject: [PATCH 245/340] [3.5] Only run AppVeyor on long-lived branches (GH-1941) Also on the short-lived `buildbot-custom` branch. (cherry picked from commit d3bedf356aca04ed9135a84b08) --- .github/appveyor.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 60c2dae444761e..5d11a0788b48ef 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,5 +1,10 @@ version: 3.5.3+.{build} clone_depth: 5 +branches: + only: + - master + - /\d\.\d/ + - buildbot-custom build_script: - cmd: PCbuild\build.bat -e test_script: From 1f04b900861686351977f6a7d51afa5fdc181b82 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 4 Jun 2017 20:09:16 -0700 Subject: [PATCH 246/340] bpo-30530: Update Descriptor How To Documentation (GH-1845) (GH-1954) Update the code example in Functions and Methods section Remove objtype argument in MethodType (cherry picked from commit 1bced56567335745f91676192fc39c06aab30da9) --- Doc/howto/descriptor.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index c2bf473e1ff9ea..2dd6c34e2ced02 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -282,7 +282,7 @@ this:: . . . def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" - return types.MethodType(self, obj, objtype) + return types.MethodType(self, obj) Running the interpreter shows how the function descriptor works in practice:: From b32fb6c1fb6cdf019817176f573e60c0923a6e22 Mon Sep 17 00:00:00 2001 From: csabella Date: Sun, 4 Jun 2017 23:11:58 -0400 Subject: [PATCH 247/340] bpo-30538: Update count() in Functional Programming HOWTO (GH-1919) (GH-1944) * bpo-30538: Update count() in Functional HOWTO * bpo-30538: Update enumerate() arguments in Functional HOWTO (cherry picked from commit 9be4ff359daa67cde6246494f643ed7cd2825d46) --- Doc/howto/functional.rst | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/Doc/howto/functional.rst b/Doc/howto/functional.rst index a82dca7077e905..40601812a77cb5 100644 --- a/Doc/howto/functional.rst +++ b/Doc/howto/functional.rst @@ -653,8 +653,9 @@ This can also be written as a list comprehension: [0, 2, 4, 6, 8] -:func:`enumerate(iter) ` counts off the elements in the iterable, -returning 2-tuples containing the count and each element. :: +:func:`enumerate(iter, start=0) ` counts off the elements in the +iterable returning 2-tuples containing the count (from *start*) and +each element. :: >>> for item in enumerate(['subject', 'verb', 'object']): ... print(item) @@ -747,14 +748,16 @@ The module's functions fall into a few broad classes: Creating new iterators ---------------------- -:func:`itertools.count(n) ` returns an infinite stream of -integers, increasing by 1 each time. You can optionally supply the starting -number, which defaults to 0:: +:func:`itertools.count(start, step) ` returns an infinite +stream of evenly spaced values. You can optionally supply the starting number, +which defaults to 0, and the interval between numbers, which defaults to 1:: itertools.count() => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... itertools.count(10) => 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ... + itertools.count(10, 5) => + 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, ... :func:`itertools.cycle(iter) ` saves a copy of the contents of a provided iterable and returns a new iterator that returns its elements from @@ -1060,10 +1063,10 @@ write the obvious :keyword:`for` loop:: for i in [1,2,3]: product *= i -A related function is `itertools.accumulate(iterable, func=operator.add) `. It performs the same calculation, but instead of +returning only the final result, :func:`accumulate` returns an iterator that +also yields each partial result:: itertools.accumulate([1,2,3,4,5]) => 1, 3, 6, 10, 15 @@ -1235,6 +1238,8 @@ Python documentation Documentation for the :mod:`itertools` module. +Documentation for the :mod:`functools` module. + Documentation for the :mod:`operator` module. :pep:`289`: "Generator Expressions" From 58e5dd1a03b3ce421f07085f8cd6e8566a1ed197 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Mon, 5 Jun 2017 20:02:18 -0500 Subject: [PATCH 248/340] [3.5] bpo-30417: Disable 'cpu' resource on Travis (GH-1928) Also weakens the 'should this be run?' regex to allow all builds when .travis.yml changes. (cherry picked from commit c53b13b270767948fddb58b287149c499f9a03c4) --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4dfefb72700dbd..de243b15bde536 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,7 @@ matrix: env: OPTIONAL=true before_script: - | - if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.(rst|yml)$)|(^Doc)/' + if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.rst$)|(^Doc)|(^Misc)' then echo "Only docs were updated, stopping build process." exit @@ -57,16 +57,16 @@ matrix: ./venv/bin/python -m pip install -U coverage script: # Skip tests that re-run the entire test suite. - - ./venv/bin/python -m coverage run --pylib -m test -uall -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn + - ./venv/bin/python -m coverage run --pylib -m test -uall,-cpu -x test_multiprocessing_fork -x test_multiprocessing_forkserver -x test_multiprocessing_spawn after_script: # Probably should be after_success once test suite updated to run under coverage.py. # Make the `coverage` command available to Codecov w/ a version of Python that can parse all source files. - source ./venv/bin/activate - bash <(curl -s https://codecov.io/bash) -# Travis provides only 2 cores, so don't overdue the parallelism and waste memory. +# Travis provides only 2 cores, so don't overdo the parallelism and waste memory. before_script: - | - if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.(rst|yml)$)|(^Doc)/' + if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.rst$)|(^Doc)|(^Misc)' then echo "Only docs were updated, stopping build process." exit @@ -76,7 +76,7 @@ before_script: script: # `-r -w` implicitly provided through `make buildbottest`. - - make buildbottest TESTOPTS="-j4" + - make buildbottest TESTOPTS="-j4 -uall,-cpu" notifications: email: false From 6d8ab767fcb24586574d6cddbe0b1ea643712b07 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Mon, 5 Jun 2017 22:41:26 -0500 Subject: [PATCH 249/340] [3.5] Install dependencies in Travis OSX build (GH-1952) (cherry picked from commit 167e0fc211c06df) --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index de243b15bde536..3de0b666e7d8b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,6 +28,10 @@ matrix: compiler: clang # Testing under macOS is optional until testing stability has been demonstrated. env: OPTIONAL=true + before_install: + - brew install openssl xz + - export CPPFLAGS="-I$(brew --prefix openssl)/include" + - export LDFLAGS="-L$(brew --prefix openssl)/lib" - os: linux language: python python: 3.6 From 86f8f1f05cd5822b4a4031b90cfdbe5fa1b1159e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 6 Jun 2017 19:23:21 +0300 Subject: [PATCH 250/340] [3.5] bpo-30567: Fix refleak in sys.getwindowsversion (GH-1940) (#1971) (cherry picked from commit 48fb766) --- Python/sysmodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index fc769ad1d8c1d2..d62bbf117d7b41 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -897,10 +897,10 @@ sys_getwindowsversion(PyObject *self) } PyMem_RawFree(verblock); } - PyStructSequence_SET_ITEM(version, pos++, PyTuple_Pack(3, - PyLong_FromLong(realMajor), - PyLong_FromLong(realMinor), - PyLong_FromLong(realBuild) + PyStructSequence_SET_ITEM(version, pos++, Py_BuildValue("(kkk)", + realMajor, + realMinor, + realBuild )); if (PyErr_Occurred()) { From ee9de30aa0dbcfd848e4200944674a084d963588 Mon Sep 17 00:00:00 2001 From: gfyoung Date: Tue, 6 Jun 2017 17:38:08 -0400 Subject: [PATCH 251/340] bpo-29596: Improve clinic howto documentation (GH-1710) (GH-1975) Clarify that `two-pass` buffer can only be dumped once, and it prints out all text sent to it during all processing, even from Clinic blocks *after* the dumping point. --- Doc/howto/clinic.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst index 491c5a2ca4c6e5..8b2fc7453b2402 100644 --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1407,8 +1407,8 @@ Let's start with defining some terminology: ``two-pass`` A buffer like ``buffer``. However, a two-pass buffer can only - be written once, and it prints out all text sent to it during - all of processing, even from Clinic blocks *after* the + be dumped once, and it prints out all text sent to it during + all processing, even from Clinic blocks *after* the dumping point. ``suppress`` The text is suppressed—thrown away. @@ -1471,7 +1471,7 @@ preset configurations, as follows: The default filename is ``"{dirname}/clinic/{basename}.h"``. ``buffer`` - Save up all most of the output from Clinic, to be written into + Save up most of the output from Clinic, to be written into your file near the end. For Python files implementing modules or builtin types, it's recommended that you dump the buffer just above the static structures for your module or From e3a0ce2edea8082c8ae74ae03e04ce5dd1b52de4 Mon Sep 17 00:00:00 2001 From: Matthias Klose Date: Wed, 7 Jun 2017 18:08:57 -0700 Subject: [PATCH 252/340] [3.5] trivial: update config.{guess,sub} from gnu.org. (GH-1987) (#1991) * Update config.{guess,sub} from gnu.org.. (cherry picked from commit 6f46683a6257f22f25d136ed080d58d0c060a43b) --- config.guess | 31 +++++++++++++++++++++---------- config.sub | 23 +++++++++++++++++------ 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/config.guess b/config.guess index 2e9ad7fe8189d2..2193702b12af30 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2016-10-02' +timestamp='2017-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -837,10 +837,11 @@ EOF UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -1303,14 +1304,21 @@ EOF if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub @@ -1334,15 +1342,18 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) + NEO-*:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; - NSR-?:NONSTOP_KERNEL:*:*) + NSR-*:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk${UNAME_RELEASE} + exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; diff --git a/config.sub b/config.sub index 3478c1fd0d3188..40ea5dfe1152f0 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2016 Free Software Foundation, Inc. +# Copyright 1992-2017 Free Software Foundation, Inc. -timestamp='2016-11-19' +timestamp='2017-04-02' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -67,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2016 Free Software Foundation, Inc. +Copyright 1992-2017 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -263,7 +263,7 @@ case $basic_machine in | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ - | i370 | i860 | i960 | ia64 \ + | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ @@ -315,6 +315,7 @@ case $basic_machine in | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ + | wasm32 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) @@ -388,7 +389,7 @@ case $basic_machine in | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ @@ -446,6 +447,7 @@ case $basic_machine in | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ + | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -948,6 +950,9 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -1243,6 +1248,9 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; + wasm32) + basic_machine=wasm32-unknown + ;; w65*) basic_machine=w65-wdc os=-none @@ -1409,7 +1417,7 @@ case $os in | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ - | -onefs* | -tirtos* | -phoenix* | -fuchsia*) + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1638,6 +1646,9 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + pru-*) + os=-elf + ;; *-be) os=-beos ;; From 54ba41ecc5711f89841342c5f9dd555ee13404b5 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Thu, 8 Jun 2017 04:14:44 -0700 Subject: [PATCH 253/340] [3.5] bpo-30594: Fixed refcounting in newPySSLSocket (GH-1992) (#1993) If pass a server_hostname= that fails IDNA decoding to SSLContext.wrap_socket or SSLContext.wrap_bio, then the SSLContext object had a spurious Py_DECREF called on it, eventually leading to segfaults. (cherry picked from commit 65ece7ca2366308fa91a39a8dfa255e6bdce3cca) --- Modules/_ssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 9f79d17f6d3f4a..3b2d3add2821bf 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -570,6 +570,7 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->ssl = NULL; self->Socket = NULL; self->ctx = sslctx; + Py_INCREF(sslctx); self->shutdown_seen_zero = 0; self->handshake_done = 0; self->owner = NULL; @@ -584,8 +585,6 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, self->server_hostname = hostname; } - Py_INCREF(sslctx); - /* Make sure the SSL error state is initialized */ (void) ERR_get_state(); ERR_clear_error(); From a0b9088881b8fcfda864070335b249071508ee0c Mon Sep 17 00:00:00 2001 From: Denis Osipov Date: Thu, 8 Jun 2017 17:16:48 +0500 Subject: [PATCH 254/340] [3.5] bpo-30584: Fix test_os fails on non-English Windows (GH-1980) (#2000) * Fix bpo-30584 * Adding a comment mentionning the bpo and explaining what is the identifier * Add Denis Osipov to Misc/ACKS (cherry picked from commit 897bba75632dfce87c355e3cd4700468357715a7) --- Lib/test/test_os.py | 4 +++- Misc/ACKS | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 10383cfc1f0e93..5865783a43e9f2 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -448,7 +448,9 @@ def test_access_denied(self): # force CreateFile to fail with ERROR_ACCESS_DENIED. DETACHED_PROCESS = 8 subprocess.check_call( - ['icacls.exe', fname, '/deny', 'Users:(S)'], + # bpo-30584: Use security identifier *S-1-5-32-545 instead + # of localized "Users" to not depend on the locale. + ['icacls.exe', fname, '/deny', '*S-1-5-32-545:(S)'], creationflags=DETACHED_PROCESS ) result = os.stat(fname) diff --git a/Misc/ACKS b/Misc/ACKS index 53f6879535b84d..1ed9e5bc98abf5 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1101,6 +1101,7 @@ William Orr Michele Orrù Tomáš Orsava Oleg Oshmyan +Denis Osipov Denis S. Otkidach Peter Otten Michael Otteneder From df04c088493bdbc2defea5e225a94e9bdd8e759f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 8 Jun 2017 18:20:46 +0200 Subject: [PATCH 255/340] bpo-30418: Popen.communicate() always ignore EINVAL (#2002) (#2005) On Windows, subprocess.Popen.communicate() now also ignore EINVAL on stdin.write() if the child process is still running but closed the pipe. (cherry picked from commit d52aa31378ae43e044a300edfe8285954c167216) --- Lib/subprocess.py | 14 ++++++++------ Misc/NEWS | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 281ea8af92257e..614de40e5cae32 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -741,19 +741,21 @@ def _stdin_write(self, input): self.stdin.write(input) except BrokenPipeError: pass # communicate() must ignore broken pipe errors. - except OSError as e: - if e.errno == errno.EINVAL and self.poll() is not None: - # Issue #19612: On Windows, stdin.write() fails with EINVAL - # if the process already exited before the write + except OSError as exc: + if exc.errno == errno.EINVAL: + # bpo-19612, bpo-30418: On Windows, stdin.write() fails + # with EINVAL if the child process exited or if the child + # process is still running but closed the pipe. pass else: raise + try: self.stdin.close() except BrokenPipeError: pass # communicate() must ignore broken pipe errors. - except OSError as e: - if e.errno == errno.EINVAL and self.poll() is not None: + except OSError as exc: + if exc.errno == errno.EINVAL: pass else: raise diff --git a/Misc/NEWS b/Misc/NEWS index 997058b34a5592..78ec9f0ccae64a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-30418: On Windows, subprocess.Popen.communicate() now also ignore EINVAL + on stdin.write() if the child process is still running but closed the pipe. + - bpo-30378: Fix the problem that logging.handlers.SysLogHandler cannot handle IPv6 addresses. From 3fc2fa8cb909cb58325f56deb5cd500d278e4102 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 9 Jun 2017 07:33:24 -0700 Subject: [PATCH 256/340] bpo-24755: Document asyncio.wrap_future (GH-603) (GH-2020) (cherry picked from commit 824f6879121413e09439fffef54580413e44bf46) --- Doc/library/asyncio-task.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst index 558d17c0969793..804f1925b40929 100644 --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -540,6 +540,11 @@ Task functions .. deprecated:: 3.4.4 +.. function:: wrap_future(future, \*, loop=None) + + Wrap a :class:`concurrent.futures.Future` object in a :class:`Future` + object. + .. function:: gather(\*coros_or_futures, loop=None, return_exceptions=False) Return a future aggregating results from the given coroutine objects or From d913d1c31733eff5969835e46ae13e2d156dbb1c Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 9 Jun 2017 17:08:23 -0400 Subject: [PATCH 257/340] Fix waiter cancellation in asyncio.Lock (#1031) (#2038) Avoid a deadlock when the waiter who is about to take the lock is cancelled Issue #27585 --- Lib/asyncio/locks.py | 17 ++++++++++++----- Lib/test/test_asyncio/test_locks.py | 22 ++++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/Lib/asyncio/locks.py b/Lib/asyncio/locks.py index deefc938ecfb01..92661830a06228 100644 --- a/Lib/asyncio/locks.py +++ b/Lib/asyncio/locks.py @@ -176,6 +176,10 @@ def acquire(self): yield from fut self._locked = True return True + except futures.CancelledError: + if not self._locked: + self._wake_up_first() + raise finally: self._waiters.remove(fut) @@ -192,14 +196,17 @@ def release(self): """ if self._locked: self._locked = False - # Wake up the first waiter who isn't cancelled. - for fut in self._waiters: - if not fut.done(): - fut.set_result(True) - break + self._wake_up_first() else: raise RuntimeError('Lock is not acquired.') + def _wake_up_first(self): + """Wake up the first waiter who isn't cancelled.""" + for fut in self._waiters: + if not fut.done(): + fut.set_result(True) + break + class Event: """Asynchronous equivalent to threading.Event. diff --git a/Lib/test/test_asyncio/test_locks.py b/Lib/test/test_asyncio/test_locks.py index 152948c8138975..c85e8b1a32f73a 100644 --- a/Lib/test/test_asyncio/test_locks.py +++ b/Lib/test/test_asyncio/test_locks.py @@ -176,6 +176,28 @@ def lockit(name, blocker): self.assertTrue(tb.cancelled()) self.assertTrue(tc.done()) + def test_finished_waiter_cancelled(self): + lock = asyncio.Lock(loop=self.loop) + + ta = asyncio.Task(lock.acquire(), loop=self.loop) + test_utils.run_briefly(self.loop) + self.assertTrue(lock.locked()) + + tb = asyncio.Task(lock.acquire(), loop=self.loop) + test_utils.run_briefly(self.loop) + self.assertEqual(len(lock._waiters), 1) + + # Create a second waiter, wake up the first, and cancel it. + # Without the fix, the second was not woken up. + tc = asyncio.Task(lock.acquire(), loop=self.loop) + lock.release() + tb.cancel() + test_utils.run_briefly(self.loop) + + self.assertTrue(lock.locked()) + self.assertTrue(ta.done()) + self.assertTrue(tb.cancelled()) + def test_release_not_acquired(self): lock = asyncio.Lock(loop=self.loop) diff --git a/Misc/NEWS b/Misc/NEWS index 78ec9f0ccae64a..af50b0f96b568b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-27585: Fix waiter cancellation in asyncio.Lock. + Patch by Mathieu Sornay. + - bpo-30418: On Windows, subprocess.Popen.communicate() now also ignore EINVAL on stdin.write() if the child process is still running but closed the pipe. From a0338045dbaa6c9f922113c6e9efad6bdbc4cdcb Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 9 Jun 2017 14:35:31 -0700 Subject: [PATCH 258/340] [3.5] Clarify what --enable-optimizations does (GH-1847) (GH-2040) (cherry picked from commit b4e5fee6f5bcc50500ea6261a22021db58955b55) --- configure | 20 ++++---------------- configure.ac | 4 ++-- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/configure b/configure index 2091da7fb1bd51..5640c2dc12afab 100755 --- a/configure +++ b/configure @@ -781,7 +781,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -893,7 +892,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1146,15 +1144,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1292,7 +1281,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1445,7 +1434,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1486,8 +1474,8 @@ Optional Features: Build (MacOSX|Darwin) framework --enable-shared disable/enable building shared python library --enable-profiling enable C-level code profiling - --enable-optimizations Enable expensive optimizations (PGO, maybe LTO, - etc). Disabled by default. + --enable-optimizations Enable expensive, stable optimizations (PGO, etc). + Disabled by default. --enable-loadable-sqlite-extensions support loadable extensions in _sqlite module --enable-ipv6 Enable ipv6 (with ipv4) support @@ -17838,7 +17826,7 @@ mv config.c Modules if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then echo "" >&6 echo "" >&6 - echo "If you want a release build with all optimizations active (LTO, PGO, etc)," + echo "If you want a release build with all stable optimizations active (PGO, etc)," echo "please run ./configure --enable-optimizations" >&6 echo "" >&6 echo "" >&6 diff --git a/configure.ac b/configure.ac index e1731dbc222078..c9b755f0f40bd2 100644 --- a/configure.ac +++ b/configure.ac @@ -1226,7 +1226,7 @@ AC_SUBST(DEF_MAKE_ALL_RULE) AC_SUBST(DEF_MAKE_RULE) Py_OPT='false' AC_MSG_CHECKING(for --enable-optimizations) -AC_ARG_ENABLE(optimizations, AS_HELP_STRING([--enable-optimizations], [Enable expensive optimizations (PGO, maybe LTO, etc). Disabled by default.]), +AC_ARG_ENABLE(optimizations, AS_HELP_STRING([--enable-optimizations], [Enable expensive, stable optimizations (PGO, etc). Disabled by default.]), [ if test "$enableval" != no then @@ -5389,7 +5389,7 @@ mv config.c Modules if test "$Py_OPT" = 'false' -a "$Py_DEBUG" != 'true'; then echo "" >&AS_MESSAGE_FD echo "" >&AS_MESSAGE_FD - echo "If you want a release build with all optimizations active (LTO, PGO, etc)," + echo "If you want a release build with all stable optimizations active (PGO, etc)," echo "please run ./configure --enable-optimizations" >&AS_MESSAGE_FD echo "" >&AS_MESSAGE_FD echo "" >&AS_MESSAGE_FD From ff9511bbadba27457cd0eb084e9b4305ab9dfcf5 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 9 Jun 2017 18:27:45 -0400 Subject: [PATCH 259/340] Closing transport during handshake process leaks socket (#480) (#2045) --- Lib/asyncio/sslproto.py | 7 +++++-- Lib/test/test_asyncio/test_sslproto.py | 15 +++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index aa5e03423766c4..31803ac3b0dc8f 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -550,8 +550,11 @@ def _get_extra_info(self, name, default=None): def _start_shutdown(self): if self._in_shutdown: return - self._in_shutdown = True - self._write_appdata(b'') + if self._in_handshake: + self._abort() + else: + self._in_shutdown = True + self._write_appdata(b'') def _write_appdata(self, data): self._write_backlog.append((data, 0)) diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index f1771c5561afea..bcd236ea2632ed 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -42,6 +42,7 @@ def mock_handshake(callback): sslpipe.do_handshake.side_effect = mock_handshake with mock.patch('asyncio.sslproto._SSLPipe', return_value=sslpipe): ssl_proto.connection_made(transport) + return transport def test_cancel_handshake(self): # Python issue #23197: cancelling a handshake must not raise an @@ -95,6 +96,20 @@ def test_connection_lost(self): test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionAbortedError) + def test_close_during_handshake(self): + # bpo-29743 Closing transport during handshake process leaks socket + waiter = asyncio.Future(loop=self.loop) + ssl_proto = self.ssl_protocol(waiter) + + def do_handshake(callback): + return [] + + transport = self.connection_made(ssl_proto) + test_utils.run_briefly(self.loop) + + ssl_proto._app_transport.close() + self.assertTrue(transport.abort.called) + def test_get_extra_info_on_closed_connection(self): waiter = asyncio.Future(loop=self.loop) ssl_proto = self.ssl_protocol(waiter) diff --git a/Misc/NEWS b/Misc/NEWS index af50b0f96b568b..05331939f6efe4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-29743: Closing transport during handshake process leaks open socket. + Patch by Nikolay Kim + - bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. From 7f1cd726c6e2d20368fe4d6a9762556c6d3604c2 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Fri, 9 Jun 2017 19:14:24 -0400 Subject: [PATCH 260/340] Break circular references when closing SSLTransport objects (#981) (#2048) --- Lib/asyncio/sslproto.py | 10 ++++++---- Misc/NEWS | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 31803ac3b0dc8f..61d478ebda6c78 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -685,12 +685,14 @@ def _fatal_error(self, exc, message='Fatal error on transport'): self._transport._force_close(exc) def _finalize(self): + self._sslpipe = None + if self._transport is not None: self._transport.close() def _abort(self): - if self._transport is not None: - try: + try: + if self._transport is not None: self._transport.abort() - finally: - self._finalize() + finally: + self._finalize() diff --git a/Misc/NEWS b/Misc/NEWS index 05331939f6efe4..5edf13b98cdb94 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-29870: Fix ssl sockets leaks when connection is aborted in asyncio/ssl + implementation. Patch by Michaël Sghaïer. + - bpo-29743: Closing transport during handshake process leaks open socket. Patch by Nikolay Kim From a2cdbdf3bb26b3b28bd04af0b6520a5f8333ea03 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 9 Jun 2017 17:02:18 -0700 Subject: [PATCH 261/340] [3.5] Make codecov config on master the only config used (GH-2041) (GH-2053) This will allow for centralized management of the Codecov config to prevent skew as well as easier management going forward. Closes python/core-workflowGH-81. (cherry picked from commit 11ffb4543bc000dea527bcc0417e2f8bda13790f) --- .github/codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/codecov.yml b/.github/codecov.yml index fcf9df6a7a698e..dc21321d0baaf0 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -1,4 +1,5 @@ codecov: + strict_yaml_branch: master notify: require_ci_to_pass: true comment: off From cabdba24b5cee036bd4963d2dcf5bf667e6d63c9 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 9 Jun 2017 18:33:50 -0700 Subject: [PATCH 262/340] [3.5] bpo-30335: Add deprecation alias entry for assertNotRegexpMatches (GH-1536) (GH-2056) Document that assertNotRegexpMatches is a deprecated alias for assertNotRegex. (cherry picked from commit 74921ed8941fce14c2a53dc7280f43eb01fe4ed8) --- Doc/library/unittest.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst index 76008c4a8fac50..2790762dc68ea8 100644 --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -1170,6 +1170,9 @@ Test cases :meth:`.assertRegex`. .. versionadded:: 3.2 :meth:`.assertNotRegex`. + .. versionadded:: 3.5 + The name ``assertNotRegexpMatches`` is a deprecated alias + for :meth:`.assertNotRegex`. .. method:: assertCountEqual(first, second, msg=None) @@ -1435,9 +1438,9 @@ For historical reasons, some of the :class:`TestCase` methods had one or more aliases that are now deprecated. The following table lists the correct names along with their deprecated aliases: - ============================== ====================== ====================== + ============================== ====================== ======================= Method Name Deprecated alias Deprecated alias - ============================== ====================== ====================== + ============================== ====================== ======================= :meth:`.assertEqual` failUnlessEqual assertEquals :meth:`.assertNotEqual` failIfEqual assertNotEquals :meth:`.assertTrue` failUnless assert\_ @@ -1446,8 +1449,9 @@ along with their deprecated aliases: :meth:`.assertAlmostEqual` failUnlessAlmostEqual assertAlmostEquals :meth:`.assertNotAlmostEqual` failIfAlmostEqual assertNotAlmostEquals :meth:`.assertRegex` assertRegexpMatches + :meth:`.assertNotRegex` assertNotRegexpMatches :meth:`.assertRaisesRegex` assertRaisesRegexp - ============================== ====================== ====================== + ============================== ====================== ======================= .. deprecated:: 3.1 the fail* aliases listed in the second column. @@ -1455,8 +1459,9 @@ along with their deprecated aliases: the assert* aliases listed in the third column. .. deprecated:: 3.2 ``assertRegexpMatches`` and ``assertRaisesRegexp`` have been renamed to - :meth:`.assertRegex` and :meth:`.assertRaisesRegex` - + :meth:`.assertRegex` and :meth:`.assertRaisesRegex`. + .. deprecated:: 3.5 + the ``assertNotRegexpMatches`` name in favor of :meth:`.assertNotRegex`. .. _testsuite-objects: From 91581d4225e91e581f44d60d0b87c80778c36d1d Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Fri, 9 Jun 2017 22:26:48 -0500 Subject: [PATCH 263/340] [3.5] bpo-30417: Disable `cpu` resource on AppVeyor (GH-1951) (cherry picked from commit 42e3acda86829def9adc354fbee77597b849bf9e) --- .github/appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 5d11a0788b48ef..55d0661f0bcf8a 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -8,7 +8,7 @@ branches: build_script: - cmd: PCbuild\build.bat -e test_script: -- cmd: PCbuild\rt.bat -q -uall -rwW --timeout=1200 -j0 +- cmd: PCbuild\rt.bat -q -uall -u-cpu -rwW --timeout=1200 -j0 # Only trigger AppVeyor if actual code or its configuration changes only_commits: From 1f73023b908b1d13ca31d162ba613e0186218be5 Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sat, 10 Jun 2017 00:15:41 -0400 Subject: [PATCH 264/340] [3.5] Fix TypeError is asyncio/proactor_events (GH-993) (#2060) (cherry picked from commit 34792d25ab7329241ea24595286d65d54c266274) --- Lib/asyncio/proactor_events.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py index fef3205877f994..13a885cd559538 100644 --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -231,8 +231,9 @@ class _ProactorBaseWritePipeTransport(_ProactorBasePipeTransport, def write(self, data): if not isinstance(data, (bytes, bytearray, memoryview)): - raise TypeError('data argument must be byte-ish (%r)', - type(data)) + msg = ("data argument must be a bytes-like object, not '%s'" % + type(data).__name__) + raise TypeError(msg) if self._eof_written: raise RuntimeError('write_eof() already called') From 1395c58ef7b98f087d1d5d50962fe7a8c032f34d Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sat, 10 Jun 2017 10:01:17 -0400 Subject: [PATCH 265/340] [3.5] bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers (GH-409) (#2063) * bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers (#409) (cherry picked from commit a608d2d5a7f1aabe9bcbfc220135c5e126189390) * [3.5] bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers (GH-409) * asyncio SSL contexts leak sockets after calling close with certain servers * cleanup _shutdown_timeout_handle on _fatal_error. (cherry picked from commit a608d2d5a7f1aabe9bcbfc220135c5e126189390) --- Lib/asyncio/sslproto.py | 24 +++++++++++++++++- Lib/test/test_asyncio/test_sslproto.py | 34 ++++++++++++++++++++++++++ Misc/NEWS | 4 +++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 61d478ebda6c78..4606f0bf2d86db 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -7,6 +7,7 @@ from . import base_events from . import compat +from . import futures from . import protocols from . import transports from .log import logger @@ -411,7 +412,7 @@ class SSLProtocol(protocols.Protocol): def __init__(self, loop, app_protocol, sslcontext, waiter, server_side=False, server_hostname=None, - call_connection_made=True): + call_connection_made=True, shutdown_timeout=5.0): if ssl is None: raise RuntimeError('stdlib ssl module not available') @@ -442,6 +443,8 @@ def __init__(self, loop, app_protocol, sslcontext, waiter, self._session_established = False self._in_handshake = False self._in_shutdown = False + self._shutdown_timeout = shutdown_timeout + self._shutdown_timeout_handle = None # transport, ex: SelectorSocketTransport self._transport = None self._call_connection_made = call_connection_made @@ -556,6 +559,15 @@ def _start_shutdown(self): self._in_shutdown = True self._write_appdata(b'') + if self._shutdown_timeout is not None: + self._shutdown_timeout_handle = self._loop.call_later( + self._shutdown_timeout, self._on_shutdown_timeout) + + def _on_shutdown_timeout(self): + if self._transport is not None: + self._fatal_error( + futures.TimeoutError(), 'Can not complete shitdown operation') + def _write_appdata(self, data): self._write_backlog.append((data, 0)) self._write_buffer_size += len(data) @@ -683,12 +695,22 @@ def _fatal_error(self, exc, message='Fatal error on transport'): }) if self._transport: self._transport._force_close(exc) + self._transport = None + + if self._shutdown_timeout_handle is not None: + self._shutdown_timeout_handle.cancel() + self._shutdown_timeout_handle = None def _finalize(self): self._sslpipe = None if self._transport is not None: self._transport.close() + self._transport = None + + if self._shutdown_timeout_handle is not None: + self._shutdown_timeout_handle.cancel() + self._shutdown_timeout_handle = None def _abort(self): try: diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index bcd236ea2632ed..6bcaa9edb4306d 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -96,6 +96,40 @@ def test_connection_lost(self): test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionAbortedError) + def test_close_abort(self): + # From issue #bpo-29406 + # abort connection if server does not complete shutdown procedure + ssl_proto = self.ssl_protocol() + transport = self.connection_made(ssl_proto) + ssl_proto._on_handshake_complete(None) + ssl_proto._start_shutdown() + self.assertIsNotNone(ssl_proto._shutdown_timeout_handle) + + exc_handler = mock.Mock() + self.loop.set_exception_handler(exc_handler) + ssl_proto._shutdown_timeout_handle._run() + + exc_handler.assert_called_with( + self.loop, {'message': 'Can not complete shitdown operation', + 'exception': mock.ANY, + 'transport': transport, + 'protocol': ssl_proto} + ) + self.assertIsNone(ssl_proto._shutdown_timeout_handle) + + def test_close(self): + # From issue #bpo-29406 + # abort connection if server does not complete shutdown procedure + ssl_proto = self.ssl_protocol() + transport = self.connection_made(ssl_proto) + ssl_proto._on_handshake_complete(None) + ssl_proto._start_shutdown() + self.assertIsNotNone(ssl_proto._shutdown_timeout_handle) + + ssl_proto._finalize() + self.assertIsNone(ssl_proto._transport) + self.assertIsNone(ssl_proto._shutdown_timeout_handle) + def test_close_during_handshake(self): # bpo-29743 Closing transport during handshake process leaks socket waiter = asyncio.Future(loop=self.loop) diff --git a/Misc/NEWS b/Misc/NEWS index 5edf13b98cdb94..3abdc12ec5b6fa 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -62,6 +62,10 @@ Library - bpo-29743: Closing transport during handshake process leaks open socket. Patch by Nikolay Kim +- bpo-29406: asyncio SSL contexts leak sockets after calling close with + certain servers. + Patch by Nikolay Kim + - bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. From 656f232131e7a49800662119c7f9b8078729e697 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 10 Jun 2017 07:26:08 -0700 Subject: [PATCH 266/340] bpo-25409: Clarify fnmatch and fnmatchcase documentation (GH-1535) (GH-2066) Mention that fnmatchcase does not call normcase, and fnmatch does. (cherry picked from commit e5f6e86c48c7b2eb9e1d6a0e72867b4d8b4720f3) --- Doc/library/fnmatch.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/fnmatch.rst b/Doc/library/fnmatch.rst index 9fc9c7c4d51893..670b17681be161 100644 --- a/Doc/library/fnmatch.rst +++ b/Doc/library/fnmatch.rst @@ -43,9 +43,8 @@ patterns. .. function:: fnmatch(filename, pattern) Test whether the *filename* string matches the *pattern* string, returning - :const:`True` or :const:`False`. If the operating system is case-insensitive, - then both parameters will be normalized to all lower- or upper-case before - the comparison is performed. :func:`fnmatchcase` can be used to perform a + :const:`True` or :const:`False`. Both parameters are case-normalized + using :func:`os.path.normcase`. :func:`fnmatchcase` can be used to perform a case-sensitive comparison, regardless of whether that's standard for the operating system. @@ -63,7 +62,8 @@ patterns. .. function:: fnmatchcase(filename, pattern) Test whether *filename* matches *pattern*, returning :const:`True` or - :const:`False`; the comparison is case-sensitive. + :const:`False`; the comparison is case-sensitive and does not apply + :func:`os.path.normcase`. .. function:: filter(names, pattern) From afa6a389606402779c5048a7211edbf2678cecff Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sat, 10 Jun 2017 15:40:08 -0500 Subject: [PATCH 267/340] [3.5] bpo-27425: Be more explicit in .gitattributes (GH-840) (GH-2084) Also updates checked-in line endings on some files. --- .gitattributes | 45 +- Lib/venv/scripts/nt/Activate.ps1 | 102 +- Lib/venv/scripts/nt/activate.bat | 64 +- Lib/venv/scripts/nt/deactivate.bat | 42 +- Modules/_decimal/tests/runall.bat | 222 ++--- PC/bdist_wininst/build.bat | 44 +- PCbuild/build.bat | 312 +++--- PCbuild/build_env.bat | 2 +- PCbuild/build_pgo.bat | 12 +- PCbuild/clean.bat | 10 +- PCbuild/env.bat | 32 +- PCbuild/get_externals.bat | 208 ++-- PCbuild/idle.bat | 30 +- PCbuild/pcbuild.sln | 1430 ++++++++++++++-------------- PCbuild/prepare_ssl.bat | 24 +- PCbuild/readme.txt | 600 ++++++------ PCbuild/rt.bat | 120 +-- Tools/buildbot/build-amd64.bat | 10 +- Tools/buildbot/build.bat | 34 +- Tools/buildbot/buildmsi.bat | 16 +- Tools/buildbot/clean-amd64.bat | 10 +- Tools/buildbot/clean.bat | 32 +- Tools/buildbot/external-amd64.bat | 6 +- Tools/buildbot/external.bat | 6 +- Tools/buildbot/test-amd64.bat | 12 +- Tools/buildbot/test.bat | 38 +- Tools/msi/build.bat | 158 +-- Tools/msi/buildrelease.bat | 492 +++++----- Tools/msi/get_externals.bat | 54 +- Tools/msi/testrelease.bat | 234 ++--- Tools/msi/uploadrelease.bat | 152 +-- Tools/nuget/build.bat | 110 +-- Tools/unicode/genwincodecs.bat | 14 +- 33 files changed, 2355 insertions(+), 2322 deletions(-) diff --git a/.gitattributes b/.gitattributes index 82694d81f276b2..5eead66489830d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,8 +1,41 @@ +# Binary data types +*.aif binary +*.aifc binary +*.aiff binary +*.au binary +*.bmp binary +*.exe binary +*.icns binary +*.gif binary +*.ico binary +*.jpg binary *.pck binary -Lib/test/cjkencodings/* binary -Lib/test/decimaltestdata/*.decTest binary +*.png binary +*.psd binary +*.tar binary +*.wav binary +*.whl binary +*.zip binary + +# Specific binary files Lib/test/sndhdrdata/sndhdr.* binary -Lib/test/test_email/data/msg_26.txt binary -Lib/test/xmltestdata/* binary -Lib/venv/scripts/nt/* binary -Lib/test/coding20731.py binary + +# Text files that should not be subject to eol conversion +Lib/test/cjkencodings/* -text +Lib/test/decimaltestdata/*.decTest -text +Lib/test/test_email/data/*.txt -text +Lib/test/xmltestdata/* -text +Lib/test/coding20731.py -text + +# Special files in third party code +Modules/zlib/zlib.map -text + +# CRLF files +*.bat text eol=crlf +*.ps1 text eol=crlf +*.sln text eol=crlf +*.vcxproj* text eol=crlf +*.props text eol=crlf +*.proj text eol=crlf +PCbuild/readme.txt text eol=crlf +PC/readme.txt text eol=crlf diff --git a/Lib/venv/scripts/nt/Activate.ps1 b/Lib/venv/scripts/nt/Activate.ps1 index 85646c89a81cb3..bf60869e552e97 100644 --- a/Lib/venv/scripts/nt/Activate.ps1 +++ b/Lib/venv/scripts/nt/Activate.ps1 @@ -1,51 +1,51 @@ -function global:deactivate ([switch]$NonDestructive) { - # Revert to original values - if (Test-Path function:_OLD_VIRTUAL_PROMPT) { - copy-item function:_OLD_VIRTUAL_PROMPT function:prompt - remove-item function:_OLD_VIRTUAL_PROMPT - } - - if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { - copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME - remove-item env:_OLD_VIRTUAL_PYTHONHOME - } - - if (Test-Path env:_OLD_VIRTUAL_PATH) { - copy-item env:_OLD_VIRTUAL_PATH env:PATH - remove-item env:_OLD_VIRTUAL_PATH - } - - if (Test-Path env:VIRTUAL_ENV) { - remove-item env:VIRTUAL_ENV - } - - if (!$NonDestructive) { - # Self destruct! - remove-item function:deactivate - } -} - -deactivate -nondestructive - -$env:VIRTUAL_ENV="__VENV_DIR__" - -if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { - # Set the prompt to include the env name - # Make sure _OLD_VIRTUAL_PROMPT is global - function global:_OLD_VIRTUAL_PROMPT {""} - copy-item function:prompt function:_OLD_VIRTUAL_PROMPT - function global:prompt { - Write-Host -NoNewline -ForegroundColor Green '__VENV_PROMPT__' - _OLD_VIRTUAL_PROMPT - } -} - -# Clear PYTHONHOME -if (Test-Path env:PYTHONHOME) { - copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME - remove-item env:PYTHONHOME -} - -# Add the venv to the PATH -copy-item env:PATH env:_OLD_VIRTUAL_PATH -$env:PATH = "$env:VIRTUAL_ENV\__VENV_BIN_NAME__;$env:PATH" +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + if (Test-Path function:_OLD_VIRTUAL_PROMPT) { + copy-item function:_OLD_VIRTUAL_PROMPT function:prompt + remove-item function:_OLD_VIRTUAL_PROMPT + } + + if (Test-Path env:_OLD_VIRTUAL_PYTHONHOME) { + copy-item env:_OLD_VIRTUAL_PYTHONHOME env:PYTHONHOME + remove-item env:_OLD_VIRTUAL_PYTHONHOME + } + + if (Test-Path env:_OLD_VIRTUAL_PATH) { + copy-item env:_OLD_VIRTUAL_PATH env:PATH + remove-item env:_OLD_VIRTUAL_PATH + } + + if (Test-Path env:VIRTUAL_ENV) { + remove-item env:VIRTUAL_ENV + } + + if (!$NonDestructive) { + # Self destruct! + remove-item function:deactivate + } +} + +deactivate -nondestructive + +$env:VIRTUAL_ENV="__VENV_DIR__" + +if (! $env:VIRTUAL_ENV_DISABLE_PROMPT) { + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT {""} + copy-item function:prompt function:_OLD_VIRTUAL_PROMPT + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green '__VENV_PROMPT__' + _OLD_VIRTUAL_PROMPT + } +} + +# Clear PYTHONHOME +if (Test-Path env:PYTHONHOME) { + copy-item env:PYTHONHOME env:_OLD_VIRTUAL_PYTHONHOME + remove-item env:PYTHONHOME +} + +# Add the venv to the PATH +copy-item env:PATH env:_OLD_VIRTUAL_PATH +$env:PATH = "$env:VIRTUAL_ENV\__VENV_BIN_NAME__;$env:PATH" diff --git a/Lib/venv/scripts/nt/activate.bat b/Lib/venv/scripts/nt/activate.bat index 9eab147f314d3b..d76ca1359627ee 100644 --- a/Lib/venv/scripts/nt/activate.bat +++ b/Lib/venv/scripts/nt/activate.bat @@ -1,32 +1,32 @@ -@echo off -set "VIRTUAL_ENV=__VENV_DIR__" - -if not defined PROMPT ( - set "PROMPT=$P$G" -) - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) - -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" -) - -set "_OLD_VIRTUAL_PROMPT=%PROMPT%" -set "PROMPT=__VENV_PROMPT__%PROMPT%" - -if defined PYTHONHOME ( - set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" - set PYTHONHOME= -) - -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) else ( - set "_OLD_VIRTUAL_PATH=%PATH%" -) - -set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%" - -:END +@echo off +set "VIRTUAL_ENV=__VENV_DIR__" + +if not defined PROMPT ( + set "PROMPT=$P$G" +) + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" +) + +set "_OLD_VIRTUAL_PROMPT=%PROMPT%" +set "PROMPT=__VENV_PROMPT__%PROMPT%" + +if defined PYTHONHOME ( + set "_OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME%" + set PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) else ( + set "_OLD_VIRTUAL_PATH=%PATH%" +) + +set "PATH=%VIRTUAL_ENV%\__VENV_BIN_NAME__;%PATH%" + +:END diff --git a/Lib/venv/scripts/nt/deactivate.bat b/Lib/venv/scripts/nt/deactivate.bat index 313c0791173682..1205c618686fbb 100644 --- a/Lib/venv/scripts/nt/deactivate.bat +++ b/Lib/venv/scripts/nt/deactivate.bat @@ -1,21 +1,21 @@ -@echo off - -if defined _OLD_VIRTUAL_PROMPT ( - set "PROMPT=%_OLD_VIRTUAL_PROMPT%" -) -set _OLD_VIRTUAL_PROMPT= - -if defined _OLD_VIRTUAL_PYTHONHOME ( - set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" - set _OLD_VIRTUAL_PYTHONHOME= -) - -if defined _OLD_VIRTUAL_PATH ( - set "PATH=%_OLD_VIRTUAL_PATH%" -) - -set _OLD_VIRTUAL_PATH= - -set VIRTUAL_ENV= - -:END +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= + +:END diff --git a/Modules/_decimal/tests/runall.bat b/Modules/_decimal/tests/runall.bat index 568f92f6ddf392..5bc872a63f83aa 100755 --- a/Modules/_decimal/tests/runall.bat +++ b/Modules/_decimal/tests/runall.bat @@ -1,111 +1,111 @@ -@ECHO OFF - -rem Test all machine configurations, pydebug, refleaks, release build. - -cd ..\..\..\ - - -echo. -echo # ====================================================================== -echo # Building Python -echo # ====================================================================== -echo. - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 -msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 - -call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 -msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 -echo. -echo. - -echo. -echo # ====================================================================== -echo # test_decimal: platform=x64 -echo # ====================================================================== -echo. - -cd PCbuild\amd64 - -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -python.exe -m test -uall test_decimal -echo. -echo. - -cd .. - -echo. -echo # ====================================================================== -echo # test_decimal: platform=x86 -echo # ====================================================================== -echo. - -echo # ==================== refleak tests ======================= -echo. -python_d.exe -m test -uall -R 2:2 test_decimal -echo. -echo. - -echo # ==================== regular tests ======================= -echo. -python.exe -m test -uall test_decimal -echo. -echo. - -cd amd64 - -echo. -echo # ====================================================================== -echo # deccheck: platform=x64 -echo # ====================================================================== -echo. - -echo # ==================== debug build ======================= -echo. -python_d.exe ..\..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -echo # =================== release build ====================== -echo. -python.exe ..\..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -cd .. - -echo. -echo # ====================================================================== -echo # deccheck: platform=x86 -echo # ====================================================================== -echo. -echo. - -echo # ==================== debug build ======================= -echo. -python_d.exe ..\Modules\_decimal\tests\deccheck.py -echo. -echo. - -echo # =================== release build ====================== -echo. -python.exe ..\Modules\_decimal\tests\deccheck.py -echo. -echo. - - -cd ..\Modules\_decimal\tests - - - +@ECHO OFF + +rem Test all machine configurations, pydebug, refleaks, release build. + +cd ..\..\..\ + + +echo. +echo # ====================================================================== +echo # Building Python +echo # ====================================================================== +echo. + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x64 +msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Release /p:PlatformTarget=x64 +msbuild /noconsolelogger /target:clean PCbuild\pcbuild.sln /p:Configuration=Debug /p:PlatformTarget=x64 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=x64 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=x64 + +call "%VS100COMNTOOLS%\..\..\VC\vcvarsall.bat" x86 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Release /p:Platform=Win32 +msbuild /noconsolelogger PCbuild\pcbuild.sln /p:Configuration=Debug /p:Platform=Win32 +echo. +echo. + +echo. +echo # ====================================================================== +echo # test_decimal: platform=x64 +echo # ====================================================================== +echo. + +cd PCbuild\amd64 + +echo # ==================== refleak tests ======================= +echo. +python_d.exe -m test -uall -R 2:2 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +python.exe -m test -uall test_decimal +echo. +echo. + +cd .. + +echo. +echo # ====================================================================== +echo # test_decimal: platform=x86 +echo # ====================================================================== +echo. + +echo # ==================== refleak tests ======================= +echo. +python_d.exe -m test -uall -R 2:2 test_decimal +echo. +echo. + +echo # ==================== regular tests ======================= +echo. +python.exe -m test -uall test_decimal +echo. +echo. + +cd amd64 + +echo. +echo # ====================================================================== +echo # deccheck: platform=x64 +echo # ====================================================================== +echo. + +echo # ==================== debug build ======================= +echo. +python_d.exe ..\..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +echo # =================== release build ====================== +echo. +python.exe ..\..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +cd .. + +echo. +echo # ====================================================================== +echo # deccheck: platform=x86 +echo # ====================================================================== +echo. +echo. + +echo # ==================== debug build ======================= +echo. +python_d.exe ..\Modules\_decimal\tests\deccheck.py +echo. +echo. + +echo # =================== release build ====================== +echo. +python.exe ..\Modules\_decimal\tests\deccheck.py +echo. +echo. + + +cd ..\Modules\_decimal\tests + + + diff --git a/PC/bdist_wininst/build.bat b/PC/bdist_wininst/build.bat index 25f565ce0a16d8..ee6856754faa8c 100644 --- a/PC/bdist_wininst/build.bat +++ b/PC/bdist_wininst/build.bat @@ -1,22 +1,22 @@ -@echo off -setlocal - -set D=%~dp0 -set PCBUILD=%~dp0..\..\PCBuild\ - - -echo Building Lib\distutils\command\wininst-xx.0.exe - -call "%PCBUILD%env.bat" x86 -if errorlevel 1 goto :eof - -msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 -if errorlevel 1 goto :eof - - -echo Building Lib\distutils\command\wininst-xx.0-amd64.exe - -call "%PCBUILD%env.bat" x86_amd64 -if errorlevel 1 goto :eof - -msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 +@echo off +setlocal + +set D=%~dp0 +set PCBUILD=%~dp0..\..\PCBuild\ + + +echo Building Lib\distutils\command\wininst-xx.0.exe + +call "%PCBUILD%env.bat" x86 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 +if errorlevel 1 goto :eof + + +echo Building Lib\distutils\command\wininst-xx.0-amd64.exe + +call "%PCBUILD%env.bat" x86_amd64 +if errorlevel 1 goto :eof + +msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 1dbe888972f4c5..8936fd75b7cace 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -1,156 +1,156 @@ -@echo off -goto Run -:Usage -echo.%~nx0 [flags and arguments] [quoted MSBuild options] -echo. -echo.Build CPython from the command line. Requires the appropriate -echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt). -echo.Also requires Subversion (svn.exe) to be on PATH if the '-e' flag is -echo.given. -echo. -echo.After the flags recognized by this script, up to 9 arguments to be passed -echo.directly to MSBuild may be passed. If the argument contains an '=', the -echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`) -echo. -echo.Available flags: -echo. -h Display this help message -echo. -V Display version information for the current build -echo. -r Target Rebuild instead of Build -echo. -d Set the configuration to Debug -echo. -e Build external libraries fetched by get_externals.bat -echo. Extension modules that depend on external libraries will not attempt -echo. to build if this flag is not present -echo. -m Enable parallel build (enabled by default) -echo. -M Disable parallel build -echo. -v Increased output messages -echo. -k Attempt to kill any running Pythons before building (usually done -echo. automatically by the pythoncore project) -echo. --pgo Build with Profile-Guided Optimization. This flag -echo. overrides -c and -d -echo. --test-marker Enable the test marker within the build. -echo. -echo.Available flags to avoid building certain modules. -echo.These flags have no effect if '-e' is not given: -echo. --no-ssl Do not attempt to build _ssl -echo. --no-tkinter Do not attempt to build Tkinter -echo. -echo.Available arguments: -echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate -echo. Set the configuration (default: Release) -echo. -p x64 ^| Win32 -echo. Set the platform (default: Win32) -echo. -t Build ^| Rebuild ^| Clean ^| CleanAll -echo. Set the target manually -echo. --pgo-job The job to use for PGO training; implies --pgo -echo. (default: "-m test --pgo") -exit /b 127 - -:Run -setlocal -set platf=Win32 -set vs_platf=x86 -set conf=Release -set target=Build -set dir=%~dp0 -set parallel=/m -set verbose=/nologo /v:m -set kill= -set do_pgo= -set pgo_job=-m test --pgo -set on_64_bit=true - -rem This may not be 100% accurate, but close enough. -if "%ProgramFiles(x86)%"=="" (set on_64_bit=false) - -:CheckOpts -if "%~1"=="-h" goto Usage -if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts -if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts -if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts -if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts -if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts -if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts -if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts -if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts -if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts -if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts -if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts -if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts -if "%~1"=="-V" shift & goto Version -rem These use the actual property names used by MSBuild. We could just let -rem them in through the environment, but we specify them on the command line -rem anyway for visibility so set defaults after this -if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts -if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts -if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts - -if "%IncludeExternals%"=="" set IncludeExternals=false -if "%IncludeSSL%"=="" set IncludeSSL=true -if "%IncludeTkinter%"=="" set IncludeTkinter=true - -if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" - -if "%platf%"=="x64" ( - if "%on_64_bit%"=="true" ( - rem This ought to always be correct these days... - set vs_platf=amd64 - ) else ( - if "%do_pgo%"=="true" ( - echo.ERROR: Cannot cross-compile with PGO - echo. 32bit operating system detected, if this is incorrect, - echo. make sure the ProgramFiles(x86^) environment variable is set - exit /b 1 - ) - set vs_platf=x86_amd64 - ) -) - -if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" -if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" -if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= - -rem Setup the environment -call "%dir%env.bat" %vs_platf% >nul - -if "%kill%"=="true" call :Kill - -if "%do_pgo%"=="true" ( - set conf=PGInstrument - call :Build - del /s "%dir%\*.pgc" - del /s "%dir%\..\Lib\*.pyc" - echo on - call "%dir%\..\python.bat" %pgo_job% - @echo off - call :Kill - set conf=PGUpdate -) -goto Build - -:Kill -echo on -msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ - /p:Configuration=%conf% /p:Platform=%platf%^ - /p:KillPython=true - -@echo off -goto :eof - -:Build -rem Call on MSBuild to do the work, echo the command. -rem Passing %1-9 is not the preferred option, but argument parsing in -rem batch is, shall we say, "lackluster" -echo on -msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ - /p:Configuration=%conf% /p:Platform=%platf%^ - /p:IncludeExternals=%IncludeExternals%^ - /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ - /p:UseTestMarker=%UseTestMarker% %GITProperty%^ - %1 %2 %3 %4 %5 %6 %7 %8 %9 - -@echo off -goto :eof - -:Version -rem Display the current build version information -msbuild "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +goto Run +:Usage +echo.%~nx0 [flags and arguments] [quoted MSBuild options] +echo. +echo.Build CPython from the command line. Requires the appropriate +echo.version(s) of Microsoft Visual Studio to be installed (see readme.txt). +echo.Also requires Subversion (svn.exe) to be on PATH if the '-e' flag is +echo.given. +echo. +echo.After the flags recognized by this script, up to 9 arguments to be passed +echo.directly to MSBuild may be passed. If the argument contains an '=', the +echo.entire argument must be quoted (e.g. `%~nx0 "/p:PlatformToolset=v100"`) +echo. +echo.Available flags: +echo. -h Display this help message +echo. -V Display version information for the current build +echo. -r Target Rebuild instead of Build +echo. -d Set the configuration to Debug +echo. -e Build external libraries fetched by get_externals.bat +echo. Extension modules that depend on external libraries will not attempt +echo. to build if this flag is not present +echo. -m Enable parallel build (enabled by default) +echo. -M Disable parallel build +echo. -v Increased output messages +echo. -k Attempt to kill any running Pythons before building (usually done +echo. automatically by the pythoncore project) +echo. --pgo Build with Profile-Guided Optimization. This flag +echo. overrides -c and -d +echo. --test-marker Enable the test marker within the build. +echo. +echo.Available flags to avoid building certain modules. +echo.These flags have no effect if '-e' is not given: +echo. --no-ssl Do not attempt to build _ssl +echo. --no-tkinter Do not attempt to build Tkinter +echo. +echo.Available arguments: +echo. -c Release ^| Debug ^| PGInstrument ^| PGUpdate +echo. Set the configuration (default: Release) +echo. -p x64 ^| Win32 +echo. Set the platform (default: Win32) +echo. -t Build ^| Rebuild ^| Clean ^| CleanAll +echo. Set the target manually +echo. --pgo-job The job to use for PGO training; implies --pgo +echo. (default: "-m test --pgo") +exit /b 127 + +:Run +setlocal +set platf=Win32 +set vs_platf=x86 +set conf=Release +set target=Build +set dir=%~dp0 +set parallel=/m +set verbose=/nologo /v:m +set kill= +set do_pgo= +set pgo_job=-m test --pgo +set on_64_bit=true + +rem This may not be 100% accurate, but close enough. +if "%ProgramFiles(x86)%"=="" (set on_64_bit=false) + +:CheckOpts +if "%~1"=="-h" goto Usage +if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts +if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts +if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts +if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts +if "%~1"=="-m" (set parallel=/m) & shift & goto CheckOpts +if "%~1"=="-M" (set parallel=) & shift & goto CheckOpts +if "%~1"=="-v" (set verbose=/v:n) & shift & goto CheckOpts +if "%~1"=="-k" (set kill=true) & shift & goto CheckOpts +if "%~1"=="--pgo" (set do_pgo=true) & shift & goto CheckOpts +if "%~1"=="--pgo-job" (set do_pgo=true) & (set pgo_job=%~2) & shift & shift & goto CheckOpts +if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts +if "%~1"=="-V" shift & goto Version +rem These use the actual property names used by MSBuild. We could just let +rem them in through the environment, but we specify them on the command line +rem anyway for visibility so set defaults after this +if "%~1"=="-e" (set IncludeExternals=true) & shift & goto CheckOpts +if "%~1"=="--no-ssl" (set IncludeSSL=false) & shift & goto CheckOpts +if "%~1"=="--no-tkinter" (set IncludeTkinter=false) & shift & goto CheckOpts + +if "%IncludeExternals%"=="" set IncludeExternals=false +if "%IncludeSSL%"=="" set IncludeSSL=true +if "%IncludeTkinter%"=="" set IncludeTkinter=true + +if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" + +if "%platf%"=="x64" ( + if "%on_64_bit%"=="true" ( + rem This ought to always be correct these days... + set vs_platf=amd64 + ) else ( + if "%do_pgo%"=="true" ( + echo.ERROR: Cannot cross-compile with PGO + echo. 32bit operating system detected, if this is incorrect, + echo. make sure the ProgramFiles(x86^) environment variable is set + exit /b 1 + ) + set vs_platf=x86_amd64 + ) +) + +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" +if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= + +rem Setup the environment +call "%dir%env.bat" %vs_platf% >nul + +if "%kill%"=="true" call :Kill + +if "%do_pgo%"=="true" ( + set conf=PGInstrument + call :Build + del /s "%dir%\*.pgc" + del /s "%dir%\..\Lib\*.pyc" + echo on + call "%dir%\..\python.bat" %pgo_job% + @echo off + call :Kill + set conf=PGUpdate +) +goto Build + +:Kill +echo on +msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:KillPython=true + +@echo off +goto :eof + +:Build +rem Call on MSBuild to do the work, echo the command. +rem Passing %1-9 is not the preferred option, but argument parsing in +rem batch is, shall we say, "lackluster" +echo on +msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ + /p:Configuration=%conf% /p:Platform=%platf%^ + /p:IncludeExternals=%IncludeExternals%^ + /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ + /p:UseTestMarker=%UseTestMarker% %GITProperty%^ + %1 %2 %3 %4 %5 %6 %7 %8 %9 + +@echo off +goto :eof + +:Version +rem Display the current build version information +msbuild "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/build_env.bat b/PCbuild/build_env.bat index 01024cff215d39..4c67ae3ac253c7 100644 --- a/PCbuild/build_env.bat +++ b/PCbuild/build_env.bat @@ -1 +1 @@ -@%comspec% /k env.bat %* +@%comspec% /k env.bat %* diff --git a/PCbuild/build_pgo.bat b/PCbuild/build_pgo.bat index 872c3822ecb219..f02a6e5ad7c8a1 100644 --- a/PCbuild/build_pgo.bat +++ b/PCbuild/build_pgo.bat @@ -1,6 +1,6 @@ -@echo off -echo.DeprecationWarning: -echo. This script is deprecated, use `build.bat --pgo` instead. -echo. - -call "%~dp0build.bat" --pgo %* +@echo off +echo.DeprecationWarning: +echo. This script is deprecated, use `build.bat --pgo` instead. +echo. + +call "%~dp0build.bat" --pgo %* diff --git a/PCbuild/clean.bat b/PCbuild/clean.bat index 78517d225f9f44..6144c715f64e43 100644 --- a/PCbuild/clean.bat +++ b/PCbuild/clean.bat @@ -1,5 +1,5 @@ -@echo off -rem A batch program to clean a particular configuration, -rem just for convenience. - -call %~dp0build.bat -t Clean %* +@echo off +rem A batch program to clean a particular configuration, +rem just for convenience. + +call %~dp0build.bat -t Clean %* diff --git a/PCbuild/env.bat b/PCbuild/env.bat index 2b2c0051ce912f..9d4c9d1c32f7a4 100644 --- a/PCbuild/env.bat +++ b/PCbuild/env.bat @@ -1,16 +1,16 @@ -@echo off -rem This script adds the latest available tools to the path for the current -rem command window. However, most builds of Python will ignore the version -rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of -rem tools should be the same version to avoid potential conflicts. -rem -rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or -rem 'v110', 'v120' or 'v140') to the build script. - -echo Build environments: x86, amd64, x86_amd64 -echo. -set VSTOOLS=%VS140COMNTOOLS% -if "%VSTOOLS%"=="" set VSTOOLS=%VS120COMNTOOLS% -if "%VSTOOLS%"=="" set VSTOOLS=%VS110COMNTOOLS% -if "%VSTOOLS%"=="" set VSTOOLS=%VS100COMNTOOLS% -call "%VSTOOLS%..\..\VC\vcvarsall.bat" %* +@echo off +rem This script adds the latest available tools to the path for the current +rem command window. However, most builds of Python will ignore the version +rem of the tools on PATH and use PlatformToolset instead. Ideally, both sets of +rem tools should be the same version to avoid potential conflicts. +rem +rem To build Python with an earlier toolset, pass "/p:PlatformToolset=v100" (or +rem 'v110', 'v120' or 'v140') to the build script. + +echo Build environments: x86, amd64, x86_amd64 +echo. +set VSTOOLS=%VS140COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS120COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS110COMNTOOLS% +if "%VSTOOLS%"=="" set VSTOOLS=%VS100COMNTOOLS% +call "%VSTOOLS%..\..\VC\vcvarsall.bat" %* diff --git a/PCbuild/get_externals.bat b/PCbuild/get_externals.bat index 9cd13065c7abb9..a2ccd7b03e0e73 100644 --- a/PCbuild/get_externals.bat +++ b/PCbuild/get_externals.bat @@ -1,104 +1,104 @@ -@echo off -setlocal -rem Simple script to fetch source for external libraries - -if not exist "%~dp0..\externals" mkdir "%~dp0..\externals" -pushd "%~dp0..\externals" - -if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ - -rem Optionally clean up first. Be warned that this can be very destructive! -if not "%1"=="" ( - for %%c in (-c --clean --clean-only) do ( - if "%1"=="%%c" goto clean - ) - goto usage -) -goto fetch - -:clean -echo.Cleaning up external libraries. -for /D %%d in ( - bzip2-* - db-* - nasm-* - openssl-* - tcl-* - tcltk* - tk-* - tix-* - sqlite-* - xz-* - ) do ( - echo.Removing %%d - rmdir /s /q %%d -) -if "%1"=="--clean-only" ( - goto end -) - -:fetch -rem Fetch current versions - -svn --version > nul 2>&1 -if ERRORLEVEL 9009 ( - echo.svn.exe must be on your PATH. - echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the - echo.command line tools option. - popd - exit /b 1 -) - -echo.Fetching external libraries... - -set libraries= -set libraries=%libraries% bzip2-1.0.6 -if NOT "%IncludeSSL%"=="false" set libraries=%libraries% nasm-2.11.06 -if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2k -set libraries=%libraries% sqlite-3.8.11.0 -if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.4.2 -if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.4.2 -if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tix-8.4.3.6 -set libraries=%libraries% xz-5.0.5 - -for %%e in (%libraries%) do ( - if exist %%e ( - echo.%%e already exists, skipping. - ) else ( - echo.Fetching %%e... - svn export -q %SVNROOT%%%e - ) -) - -goto end - -:usage -echo.invalid argument: %1 -echo.usage: %~n0 [[ -c ^| --clean ] ^| --clean-only ] -echo. -echo.Pull all sources necessary for compiling optional extension modules -echo.that rely on external libraries. Requires svn.exe to be on your PATH -echo.and pulls sources from %SVNROOT%. -echo. -echo.Use the -c or --clean option to clean up all external library sources -echo.before pulling in the current versions. -echo. -echo.Use the --clean-only option to do the same cleaning, without pulling in -echo.anything new. -echo. -echo.Only the first argument is checked, all others are ignored. -echo. -echo.**WARNING**: the cleaning options unconditionally remove any directory -echo.that is a child of -echo. %CD% -echo.and matches wildcard patterns beginning with bzip2-, db-, nasm-, openssl-, -echo.tcl-, tcltk, tk-, tix-, sqlite-, or xz-, and as such has the potential -echo.to be very destructive if you are not aware of what it is doing. Use with -echo.caution! -popd -exit /b -1 - - -:end -echo Finished. -popd +@echo off +setlocal +rem Simple script to fetch source for external libraries + +if not exist "%~dp0..\externals" mkdir "%~dp0..\externals" +pushd "%~dp0..\externals" + +if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ + +rem Optionally clean up first. Be warned that this can be very destructive! +if not "%1"=="" ( + for %%c in (-c --clean --clean-only) do ( + if "%1"=="%%c" goto clean + ) + goto usage +) +goto fetch + +:clean +echo.Cleaning up external libraries. +for /D %%d in ( + bzip2-* + db-* + nasm-* + openssl-* + tcl-* + tcltk* + tk-* + tix-* + sqlite-* + xz-* + ) do ( + echo.Removing %%d + rmdir /s /q %%d +) +if "%1"=="--clean-only" ( + goto end +) + +:fetch +rem Fetch current versions + +svn --version > nul 2>&1 +if ERRORLEVEL 9009 ( + echo.svn.exe must be on your PATH. + echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the + echo.command line tools option. + popd + exit /b 1 +) + +echo.Fetching external libraries... + +set libraries= +set libraries=%libraries% bzip2-1.0.6 +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% nasm-2.11.06 +if NOT "%IncludeSSL%"=="false" set libraries=%libraries% openssl-1.0.2k +set libraries=%libraries% sqlite-3.8.11.0 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tcl-core-8.6.4.2 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tk-8.6.4.2 +if NOT "%IncludeTkinter%"=="false" set libraries=%libraries% tix-8.4.3.6 +set libraries=%libraries% xz-5.0.5 + +for %%e in (%libraries%) do ( + if exist %%e ( + echo.%%e already exists, skipping. + ) else ( + echo.Fetching %%e... + svn export -q %SVNROOT%%%e + ) +) + +goto end + +:usage +echo.invalid argument: %1 +echo.usage: %~n0 [[ -c ^| --clean ] ^| --clean-only ] +echo. +echo.Pull all sources necessary for compiling optional extension modules +echo.that rely on external libraries. Requires svn.exe to be on your PATH +echo.and pulls sources from %SVNROOT%. +echo. +echo.Use the -c or --clean option to clean up all external library sources +echo.before pulling in the current versions. +echo. +echo.Use the --clean-only option to do the same cleaning, without pulling in +echo.anything new. +echo. +echo.Only the first argument is checked, all others are ignored. +echo. +echo.**WARNING**: the cleaning options unconditionally remove any directory +echo.that is a child of +echo. %CD% +echo.and matches wildcard patterns beginning with bzip2-, db-, nasm-, openssl-, +echo.tcl-, tcltk, tk-, tix-, sqlite-, or xz-, and as such has the potential +echo.to be very destructive if you are not aware of what it is doing. Use with +echo.caution! +popd +exit /b -1 + + +:end +echo Finished. +popd diff --git a/PCbuild/idle.bat b/PCbuild/idle.bat index bacaaa8414a267..1978b99f6ee19d 100644 --- a/PCbuild/idle.bat +++ b/PCbuild/idle.bat @@ -1,15 +1,15 @@ -@echo off -rem start idle -rem Usage: idle [-d] -rem -d Run Debug build (python_d.exe). Else release build. - -setlocal -set exe=win32\python -PATH %PATH%;..\externals\tcltk\bin - -if "%1"=="-d" (set exe=%exe%_d) & shift - -set cmd=%exe% ../Lib/idlelib/idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 - -echo on -%cmd% +@echo off +rem start idle +rem Usage: idle [-d] +rem -d Run Debug build (python_d.exe). Else release build. + +setlocal +set exe=win32\python +PATH %PATH%;..\externals\tcltk\bin + +if "%1"=="-d" (set exe=%exe%_d) & shift + +set cmd=%exe% ../Lib/idlelib/idle.py %1 %2 %3 %4 %5 %6 %7 %8 %9 + +echo on +%cmd% diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln index 42a4d2b9ee2ba4..b375228499a0fe 100644 --- a/PCbuild/pcbuild.sln +++ b/PCbuild/pcbuild.sln @@ -1,715 +1,715 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" - ProjectSection(SolutionItems) = preProject - ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c - readme.txt = readme.txt - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcxproj", "{0E9791DB-593A-465F-98BC-681011311618}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcxproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcxproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcxproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcxproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcxproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcxproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcxproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcxproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "..\PC\bdist_wininst\bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" - ProjectSection(ProjectDependencies) = postProject - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} = {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" - ProjectSection(ProjectDependencies) = postProject - {7B2727B5-5A3F-40EE-A866-43A13CD31446} = {7B2727B5-5A3F-40EE-A866-43A13CD31446} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_importlib", "_freeze_importlib.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcl", "tcl.vcxproj", "{B5FD6F1D-129E-4BFF-9340-03606FAC7283}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tix", "tix.vcxproj", "{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tk", "tk.vcxproj", "{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay", "libeay.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay", "ssleay.vcxproj", "{10615B24-73BF-4EFA-93AA-236916321317}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - PGInstrument|Win32 = PGInstrument|Win32 - PGInstrument|x64 = PGInstrument|x64 - PGUpdate|Win32 = PGUpdate|Win32 - PGUpdate|x64 = PGUpdate|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 - {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 - {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 - {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 - {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 - {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 - {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 - {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 - {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 - {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 - {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 - {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 - {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 - {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 - {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 - {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 - {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 - {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 - {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 - {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 - {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 - {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 - {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 - {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 - {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 - {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 - {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 - {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 - {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.Build.0 = Debug|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.ActiveCfg = Release|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 - {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 - {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.ActiveCfg = Debug|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.Build.0 = Debug|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.ActiveCfg = Debug|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.Build.0 = Debug|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.Build.0 = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.Build.0 = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.ActiveCfg = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 - {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.ActiveCfg = Debug|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.Build.0 = Debug|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.ActiveCfg = Debug|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.Build.0 = Debug|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.Build.0 = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.ActiveCfg = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.Build.0 = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.Build.0 = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.ActiveCfg = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.Build.0 = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.ActiveCfg = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.Build.0 = Release|Win32 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.ActiveCfg = Release|x64 - {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.Build.0 = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.ActiveCfg = Debug|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.Build.0 = Debug|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.ActiveCfg = Debug|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.Build.0 = Debug|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.Build.0 = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.ActiveCfg = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.Build.0 = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.Build.0 = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.ActiveCfg = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.Build.0 = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.ActiveCfg = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.Build.0 = Release|Win32 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.ActiveCfg = Release|x64 - {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.Build.0 = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.ActiveCfg = Debug|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.Build.0 = Debug|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.ActiveCfg = Debug|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.Build.0 = Debug|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.Build.0 = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.ActiveCfg = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.Build.0 = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.Build.0 = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.ActiveCfg = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.Build.0 = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.ActiveCfg = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.Build.0 = Release|Win32 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.ActiveCfg = Release|x64 - {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 - {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.ActiveCfg = Debug|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.Build.0 = Debug|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.ActiveCfg = Debug|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.Build.0 = Debug|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.ActiveCfg = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.Build.0 = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.ActiveCfg = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.Build.0 = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.ActiveCfg = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.Build.0 = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.ActiveCfg = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.Build.0 = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.ActiveCfg = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.Build.0 = Release|Win32 - {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.ActiveCfg = Release|x64 - {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.Build.0 = Release|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.ActiveCfg = Debug|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.Build.0 = Debug|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.ActiveCfg = Debug|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.Build.0 = Debug|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.Build.0 = PGInstrument|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 - {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25123.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{553EC33E-9816-4996-A660-5D6186A0B0B3}" + ProjectSection(SolutionItems) = preProject + ..\Modules\getbuildinfo.c = ..\Modules\getbuildinfo.c + readme.txt = readme.txt + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythonw", "pythonw.vcxproj", "{F4229CC3-873C-49AE-9729-DD308ED4CD4A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winsound", "winsound.vcxproj", "{28B5D777-DDF2-4B6B-B34F-31D938813856}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_decimal", "_decimal.vcxproj", "{0E9791DB-593A-465F-98BC-681011311617}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes", "_ctypes.vcxproj", "{0E9791DB-593A-465F-98BC-681011311618}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ctypes_test", "_ctypes_test.vcxproj", "{9EC7190A-249F-4180-A900-548FDCF3055F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_elementtree", "_elementtree.vcxproj", "{17E1E049-C309-4D79-843F-AE483C264AEA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_msi", "_msi.vcxproj", "{31FFC478-7B4A-43E8-9954-8D03E2187E9C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_socket", "_socket.vcxproj", "{86937F53-C189-40EF-8CE8-8759D8E7D480}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_sqlite3", "_sqlite3.vcxproj", "{13CECB97-4119-4316-9D42-8534019A5A44}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_ssl", "_ssl.vcxproj", "{C6E20F84-3247-4AD6-B051-B073268F73BA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testcapi", "_testcapi.vcxproj", "{6901D91C-6E48-4BB7-9FEC-700C8131DF1D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testimportmultiple", "_testimportmultiple.vcxproj", "{36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_tkinter", "_tkinter.vcxproj", "{4946ECAC-2E69-4BF8-A90A-F5136F5094DF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_bz2", "_bz2.vcxproj", "{73FCD2BD-F133-46B7-8EC1-144CD82A59D5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "select", "select.vcxproj", "{18CAE28C-B454-46C1-87A0-493D91D97F03}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_lzma", "_lzma.vcxproj", "{F9D71780-F393-11E0-BE50-0800200C9A66}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unicodedata", "unicodedata.vcxproj", "{ECC7CEAC-A5E5-458E-BB9E-2413CC847881}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyexpat", "pyexpat.vcxproj", "{D06B6426-4762-44CC-8BAD-D79052507F2F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bdist_wininst", "..\PC\bdist_wininst\bdist_wininst.vcxproj", "{EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_hashlib", "_hashlib.vcxproj", "{447F05A8-F581-4CAC-A466-5AC7936E207E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_multiprocessing", "_multiprocessing.vcxproj", "{9E48B300-37D1-11DD-8C41-005056C00008}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3dll", "python3dll.vcxproj", "{885D4898-D08D-4091-9C40-C700CFE3FC5A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxlimited", "xxlimited.vcxproj", "{F749B822-B489-4CA5-A3AD-CE078F5F338A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testbuffer", "_testbuffer.vcxproj", "{A2697BD3-28C1-4AEC-9106-8B748639FD16}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pylauncher", "pylauncher.vcxproj", "{7B2727B5-5A3F-40EE-A866-43A13CD31446}" + ProjectSection(ProjectDependencies) = postProject + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} = {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pywlauncher", "pywlauncher.vcxproj", "{1D4B18D3-7C12-4ECB-9179-8531FF876CE6}" + ProjectSection(ProjectDependencies) = postProject + {7B2727B5-5A3F-40EE-A866-43A13CD31446} = {7B2727B5-5A3F-40EE-A866-43A13CD31446} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_freeze_importlib", "_freeze_importlib.vcxproj", "{19C0C13F-47CA-4432-AFF3-799A296A4DDC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_overlapped", "_overlapped.vcxproj", "{EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testembed", "_testembed.vcxproj", "{6DAC66D9-E703-4624-BE03-49112AB5AA62}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_testmultiphase", "_testmultiphase.vcxproj", "{16BFE6F0-22EF-40B5-B831-7E937119EF10}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tcl", "tcl.vcxproj", "{B5FD6F1D-129E-4BFF-9340-03606FAC7283}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tix", "tix.vcxproj", "{C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tk", "tk.vcxproj", "{7E85ECCF-A72C-4DA4-9E52-884508E80BA1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay", "libeay.vcxproj", "{E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay", "ssleay.vcxproj", "{10615B24-73BF-4EFA-93AA-236916321317}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyshellext", "pyshellext.vcxproj", "{0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + PGInstrument|Win32 = PGInstrument|Win32 + PGInstrument|x64 = PGInstrument|x64 + PGUpdate|Win32 = PGUpdate|Win32 + PGUpdate|x64 = PGUpdate|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.ActiveCfg = Debug|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|Win32.Build.0 = Debug|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.ActiveCfg = Debug|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Debug|x64.Build.0 = Debug|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.ActiveCfg = Release|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|Win32.Build.0 = Release|Win32 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.ActiveCfg = Release|x64 + {B11D750F-CD1F-4A96-85CE-E69A5C5259F9}.Release|x64.Build.0 = Release|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|Win32.Build.0 = Debug|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.ActiveCfg = Debug|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Debug|x64.Build.0 = Debug|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.ActiveCfg = Release|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|Win32.Build.0 = Release|Win32 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.ActiveCfg = Release|x64 + {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}.Release|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.ActiveCfg = Debug|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|Win32.Build.0 = Debug|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.ActiveCfg = Debug|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Debug|x64.Build.0 = Debug|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGInstrument|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.PGUpdate|x64.Build.0 = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.ActiveCfg = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|Win32.Build.0 = Release|Win32 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.ActiveCfg = Release|x64 + {F4229CC3-873C-49AE-9729-DD308ED4CD4A}.Release|x64.Build.0 = Release|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.ActiveCfg = Debug|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|Win32.Build.0 = Debug|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.ActiveCfg = Debug|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Debug|x64.Build.0 = Debug|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.ActiveCfg = Release|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|Win32.Build.0 = Release|Win32 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.ActiveCfg = Release|x64 + {28B5D777-DDF2-4B6B-B34F-31D938813856}.Release|x64.Build.0 = Release|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|Win32.Build.0 = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.ActiveCfg = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Debug|x64.Build.0 = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311617}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.ActiveCfg = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Release|Win32.Build.0 = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.ActiveCfg = Release|x64 + {0E9791DB-593A-465F-98BC-681011311617}.Release|x64.Build.0 = Release|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|Win32.Build.0 = Debug|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.ActiveCfg = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Debug|x64.Build.0 = Debug|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311618}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.ActiveCfg = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Release|Win32.Build.0 = Release|Win32 + {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.ActiveCfg = Release|x64 + {0E9791DB-593A-465F-98BC-681011311618}.Release|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.ActiveCfg = Debug|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|Win32.Build.0 = Debug|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.ActiveCfg = Debug|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Debug|x64.Build.0 = Debug|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGInstrument|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.PGUpdate|x64.Build.0 = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.ActiveCfg = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|Win32.Build.0 = Release|Win32 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.ActiveCfg = Release|x64 + {9EC7190A-249F-4180-A900-548FDCF3055F}.Release|x64.Build.0 = Release|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.ActiveCfg = Debug|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|Win32.Build.0 = Debug|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.ActiveCfg = Debug|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Debug|x64.Build.0 = Debug|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.ActiveCfg = Release|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|Win32.Build.0 = Release|Win32 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.ActiveCfg = Release|x64 + {17E1E049-C309-4D79-843F-AE483C264AEA}.Release|x64.Build.0 = Release|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.ActiveCfg = Debug|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|Win32.Build.0 = Debug|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.ActiveCfg = Debug|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Debug|x64.Build.0 = Debug|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.ActiveCfg = Release|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|Win32.Build.0 = Release|Win32 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.ActiveCfg = Release|x64 + {31FFC478-7B4A-43E8-9954-8D03E2187E9C}.Release|x64.Build.0 = Release|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.ActiveCfg = Debug|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|Win32.Build.0 = Debug|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.ActiveCfg = Debug|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Debug|x64.Build.0 = Debug|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.ActiveCfg = Release|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|Win32.Build.0 = Release|Win32 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.ActiveCfg = Release|x64 + {86937F53-C189-40EF-8CE8-8759D8E7D480}.Release|x64.Build.0 = Release|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.ActiveCfg = Debug|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|Win32.Build.0 = Debug|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.ActiveCfg = Debug|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Debug|x64.Build.0 = Debug|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.ActiveCfg = Release|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|Win32.Build.0 = Release|Win32 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.ActiveCfg = Release|x64 + {13CECB97-4119-4316-9D42-8534019A5A44}.Release|x64.Build.0 = Release|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.ActiveCfg = Debug|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|Win32.Build.0 = Debug|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.ActiveCfg = Debug|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Debug|x64.Build.0 = Debug|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.ActiveCfg = Release|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|Win32.Build.0 = Release|Win32 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.ActiveCfg = Release|x64 + {C6E20F84-3247-4AD6-B051-B073268F73BA}.Release|x64.Build.0 = Release|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.ActiveCfg = Debug|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|Win32.Build.0 = Debug|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.ActiveCfg = Debug|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Debug|x64.Build.0 = Debug|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.ActiveCfg = Release|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|Win32.Build.0 = Release|Win32 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.ActiveCfg = Release|x64 + {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}.Release|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.ActiveCfg = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|Win32.Build.0 = Debug|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.ActiveCfg = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Debug|x64.Build.0 = Debug|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGInstrument|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.PGUpdate|x64.Build.0 = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.ActiveCfg = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|Win32.Build.0 = Release|Win32 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.ActiveCfg = Release|x64 + {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}.Release|x64.Build.0 = Release|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.ActiveCfg = Debug|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|Win32.Build.0 = Debug|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.ActiveCfg = Debug|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Debug|x64.Build.0 = Debug|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.ActiveCfg = Release|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|Win32.Build.0 = Release|Win32 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.ActiveCfg = Release|x64 + {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}.Release|x64.Build.0 = Release|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.ActiveCfg = Debug|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|Win32.Build.0 = Debug|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.ActiveCfg = Debug|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Debug|x64.Build.0 = Debug|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.ActiveCfg = Release|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|Win32.Build.0 = Release|Win32 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.ActiveCfg = Release|x64 + {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}.Release|x64.Build.0 = Release|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.ActiveCfg = Debug|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|Win32.Build.0 = Debug|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.ActiveCfg = Debug|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Debug|x64.Build.0 = Debug|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.ActiveCfg = Release|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|Win32.Build.0 = Release|Win32 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.ActiveCfg = Release|x64 + {18CAE28C-B454-46C1-87A0-493D91D97F03}.Release|x64.Build.0 = Release|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.ActiveCfg = Debug|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|Win32.Build.0 = Debug|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.ActiveCfg = Debug|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Debug|x64.Build.0 = Debug|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.ActiveCfg = Release|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|Win32.Build.0 = Release|Win32 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.ActiveCfg = Release|x64 + {F9D71780-F393-11E0-BE50-0800200C9A66}.Release|x64.Build.0 = Release|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.ActiveCfg = Debug|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|Win32.Build.0 = Debug|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.ActiveCfg = Debug|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Debug|x64.Build.0 = Debug|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.ActiveCfg = Release|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|Win32.Build.0 = Release|Win32 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.ActiveCfg = Release|x64 + {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}.Release|x64.Build.0 = Release|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.ActiveCfg = Debug|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|Win32.Build.0 = Debug|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.ActiveCfg = Debug|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Debug|x64.Build.0 = Debug|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.ActiveCfg = Release|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|Win32.Build.0 = Release|Win32 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.ActiveCfg = Release|x64 + {D06B6426-4762-44CC-8BAD-D79052507F2F}.Release|x64.Build.0 = Release|x64 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Debug|x64.ActiveCfg = Release|x64 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGInstrument|x64.ActiveCfg = Release|x64 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.PGUpdate|x64.ActiveCfg = Release|x64 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|Win32.ActiveCfg = Release|Win32 + {EB1C19C1-1F18-421E-9735-CAEE69DC6A3C}.Release|x64.ActiveCfg = Release|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.ActiveCfg = Debug|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|Win32.Build.0 = Debug|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.ActiveCfg = Debug|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Debug|x64.Build.0 = Debug|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.ActiveCfg = Release|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|Win32.Build.0 = Release|Win32 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.ActiveCfg = Release|x64 + {447F05A8-F581-4CAC-A466-5AC7936E207E}.Release|x64.Build.0 = Release|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|Win32.Build.0 = Debug|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.ActiveCfg = Debug|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Debug|x64.Build.0 = Debug|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.ActiveCfg = Release|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|Win32.Build.0 = Release|Win32 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.ActiveCfg = Release|x64 + {A1A295E5-463C-437F-81CA-1F32367685DA}.Release|x64.Build.0 = Release|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.ActiveCfg = Debug|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|Win32.Build.0 = Debug|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.ActiveCfg = Debug|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Debug|x64.Build.0 = Debug|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.ActiveCfg = Release|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|Win32.Build.0 = Release|Win32 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.ActiveCfg = Release|x64 + {9E48B300-37D1-11DD-8C41-005056C00008}.Release|x64.Build.0 = Release|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Debug|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGInstrument|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.ActiveCfg = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|Win32.Build.0 = Debug|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.ActiveCfg = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.PGUpdate|x64.Build.0 = Debug|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.ActiveCfg = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|Win32.Build.0 = Release|Win32 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.ActiveCfg = Release|x64 + {885D4898-D08D-4091-9C40-C700CFE3FC5A}.Release|x64.Build.0 = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|Win32.ActiveCfg = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Debug|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.PGUpdate|x64.Build.0 = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.ActiveCfg = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|Win32.Build.0 = Release|Win32 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.ActiveCfg = Release|x64 + {F749B822-B489-4CA5-A3AD-CE078F5F338A}.Release|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.ActiveCfg = Debug|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|Win32.Build.0 = Debug|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.ActiveCfg = Debug|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Debug|x64.Build.0 = Debug|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGInstrument|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.PGUpdate|x64.Build.0 = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.ActiveCfg = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|Win32.Build.0 = Release|Win32 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.ActiveCfg = Release|x64 + {A2697BD3-28C1-4AEC-9106-8B748639FD16}.Release|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.ActiveCfg = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|Win32.Build.0 = Debug|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.ActiveCfg = Debug|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Debug|x64.Build.0 = Debug|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGInstrument|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.PGUpdate|x64.Build.0 = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.ActiveCfg = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|Win32.Build.0 = Release|Win32 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.ActiveCfg = Release|x64 + {7B2727B5-5A3F-40EE-A866-43A13CD31446}.Release|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|Win32.Build.0 = Debug|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.ActiveCfg = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Debug|x64.Build.0 = Debug|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGInstrument|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.PGUpdate|x64.Build.0 = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.ActiveCfg = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|Win32.Build.0 = Release|Win32 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.ActiveCfg = Release|x64 + {1D4B18D3-7C12-4ECB-9179-8531FF876CE6}.Release|x64.Build.0 = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|Win32.ActiveCfg = Debug|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Debug|x64.ActiveCfg = Debug|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGInstrument|x64.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.PGUpdate|x64.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.ActiveCfg = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|Win32.Build.0 = Release|Win32 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.ActiveCfg = Release|x64 + {19C0C13F-47CA-4432-AFF3-799A296A4DDC}.Release|x64.Build.0 = Release|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|Win32.Build.0 = Debug|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.ActiveCfg = Debug|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Debug|x64.Build.0 = Debug|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.ActiveCfg = Release|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|Win32.Build.0 = Release|Win32 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.ActiveCfg = Release|x64 + {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}.Release|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.ActiveCfg = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|Win32.Build.0 = Debug|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.ActiveCfg = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Debug|x64.Build.0 = Debug|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGInstrument|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.PGUpdate|x64.Build.0 = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.ActiveCfg = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|Win32.Build.0 = Release|Win32 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.ActiveCfg = Release|x64 + {6DAC66D9-E703-4624-BE03-49112AB5AA62}.Release|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.ActiveCfg = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|Win32.Build.0 = Debug|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.ActiveCfg = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Debug|x64.Build.0 = Debug|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGInstrument|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.PGUpdate|x64.Build.0 = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.ActiveCfg = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|Win32.Build.0 = Release|Win32 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.ActiveCfg = Release|x64 + {16BFE6F0-22EF-40B5-B831-7E937119EF10}.Release|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.ActiveCfg = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|Win32.Build.0 = Debug|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.ActiveCfg = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Debug|x64.Build.0 = Debug|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGInstrument|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.PGUpdate|x64.Build.0 = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.ActiveCfg = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|Win32.Build.0 = Release|Win32 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.ActiveCfg = Release|x64 + {B5FD6F1D-129E-4BFF-9340-03606FAC7283}.Release|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.ActiveCfg = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|Win32.Build.0 = Debug|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.ActiveCfg = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Debug|x64.Build.0 = Debug|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGInstrument|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.PGUpdate|x64.Build.0 = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.ActiveCfg = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|Win32.Build.0 = Release|Win32 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.ActiveCfg = Release|x64 + {C5A3E7FB-9695-4B2E-960B-1D9F43F1E555}.Release|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.ActiveCfg = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|Win32.Build.0 = Debug|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.ActiveCfg = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Debug|x64.Build.0 = Debug|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGInstrument|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.PGUpdate|x64.Build.0 = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.ActiveCfg = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|Win32.Build.0 = Release|Win32 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.ActiveCfg = Release|x64 + {7E85ECCF-A72C-4DA4-9E52-884508E80BA1}.Release|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.ActiveCfg = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|Win32.Build.0 = Debug|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.ActiveCfg = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Debug|x64.Build.0 = Debug|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGInstrument|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.PGUpdate|x64.Build.0 = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.ActiveCfg = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|Win32.Build.0 = Release|Win32 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.ActiveCfg = Release|x64 + {E5B04CC0-EB4C-42AB-B4DC-18EF95F864B0}.Release|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.ActiveCfg = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|Win32.Build.0 = Debug|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.ActiveCfg = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Debug|x64.Build.0 = Debug|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGInstrument|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.PGUpdate|x64.Build.0 = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.ActiveCfg = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|Win32.Build.0 = Release|Win32 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.ActiveCfg = Release|x64 + {10615B24-73BF-4EFA-93AA-236916321317}.Release|x64.Build.0 = Release|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.ActiveCfg = Debug|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|Win32.Build.0 = Debug|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.ActiveCfg = Debug|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Debug|x64.Build.0 = Debug|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.ActiveCfg = PGInstrument|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|Win32.Build.0 = PGInstrument|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.ActiveCfg = PGInstrument|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGInstrument|x64.Build.0 = PGInstrument|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.ActiveCfg = PGUpdate|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|Win32.Build.0 = PGUpdate|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.ActiveCfg = PGUpdate|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.PGUpdate|x64.Build.0 = PGUpdate|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.ActiveCfg = Release|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|Win32.Build.0 = Release|Win32 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.ActiveCfg = Release|x64 + {0F6EE4A4-C75F-4578-B4B3-2D64F4B9B782}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/PCbuild/prepare_ssl.bat b/PCbuild/prepare_ssl.bat index 1be73e6c365c67..83b58668476bae 100644 --- a/PCbuild/prepare_ssl.bat +++ b/PCbuild/prepare_ssl.bat @@ -1,12 +1,12 @@ -@echo off -if not defined HOST_PYTHON ( - if "%1" EQU "Debug" ( - shift - set HOST_PYTHON=python_d.exe - if not exist python35_d.dll exit 1 - ) ELSE ( - set HOST_PYTHON=python.exe - if not exist python35.dll exit 1 - ) -) -%HOST_PYTHON% "%~dp0prepare_ssl.py" %1 +@echo off +if not defined HOST_PYTHON ( + if "%1" EQU "Debug" ( + shift + set HOST_PYTHON=python_d.exe + if not exist python35_d.dll exit 1 + ) ELSE ( + set HOST_PYTHON=python.exe + if not exist python35.dll exit 1 + ) +) +%HOST_PYTHON% "%~dp0prepare_ssl.py" %1 diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 68579256f28b84..5f4ee64eff9dde 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -1,300 +1,300 @@ -Quick Start Guide ------------------ - -1. Install Microsoft Visual Studio 2015, any edition. -2. Install Subversion, and make sure 'svn.exe' is on your PATH. -3. Run "build.bat -e" to build Python in 32-bit Release configuration. -4. (Optional, but recommended) Run the test suite with "rt.bat -q". - - -Building Python using Microsoft Visual C++ ------------------------------------------- - -This directory is used to build CPython for Microsoft Windows NT version -6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 -bit platforms. Using this directory requires an installation of -Microsoft Visual C++ 2015 (MSVC 14.0) of any edition. The specific -requirements are as follows: - -Visual Studio Express 2015 for Desktop -Visual Studio Professional 2015 - Either edition is sufficient for building all configurations except - for Profile Guided Optimization. - The Python build solution pcbuild.sln makes use of Solution Folders, - which this edition does not support. Any time pcbuild.sln is opened - or reloaded by Visual Studio, a warning about Solution Folders will - be displayed, which can be safely dismissed with no impact on your - ability to build Python. - Required for building 64-bit Debug and Release configuration builds -Visual Studio Premium 2015 - Required for building Release configuration builds that make use of - Profile Guided Optimization (PGO), on either platform. - -All you need to do to build is open the solution "pcbuild.sln" in Visual -Studio, select the desired combination of configuration and platform, -then build with "Build Solution". You can also build from the command -line using the "build.bat" script in this directory; see below for -details. The solution is configured to build the projects in the correct -order. - -The solution currently supports two platforms. The Win32 platform is -used to build standard x86-compatible 32-bit binaries, output into the -win32 sub-directory. The x64 platform is used for building 64-bit AMD64 -(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. -The Itanium (IA-64) platform is no longer supported. - -Four configuration options are supported by the solution: -Debug - Used to build Python with extra debugging capabilities, equivalent - to using ./configure --with-pydebug on UNIX. All binaries built - using this configuration have "_d" added to their name: - python35_d.dll, python_d.exe, parser_d.pyd, and so on. Both the - build and rt (run test) batch files in this directory accept a -d - option for debug builds. If you are building Python to help with - development of CPython, you will most likely use this configuration. -PGInstrument, PGUpdate - Used to build Python in Release configuration using PGO, which - requires Premium Edition of Visual Studio. See the "Profile - Guided Optimization" section below for more information. Build - output from each of these configurations lands in its own - sub-directory of this directory. The official Python releases may - be built using these configurations. -Release - Used to build Python as it is meant to be used in production - settings, though without PGO. - - -Building Python using the build.bat script ----------------------------------------------- - -In this directory you can find build.bat, a script designed to make -building Python on Windows simpler. This script will use the env.bat -script to detect one of Visual Studio 2015, 2013, 2012, or 2010, any of -which may be used to build Python, though only Visual Studio 2015 is -officially supported. - -By default, build.bat will build Python in Release configuration for -the 32-bit Win32 platform. It accepts several arguments to change -this behavior, try `build.bat -h` to learn more. - - -C Runtime ---------- - -Visual Studio 2015 uses version 14 of the C runtime (MSVCRT14). The -executables no longer use the "Side by Side" assemblies used in previous -versions of the compiler. This simplifies distribution of applications. - -The run time libraries are available under the VC/Redist folder of your -Visual Studio distribution. For more info, see the Readme in the -VC/Redist folder. - - -Sub-Projects ------------- - -The CPython project is split up into several smaller sub-projects which -are managed by the pcbuild.sln solution file. Each sub-project is -represented by a .vcxproj and a .vcxproj.filters file starting with the -name of the sub-project. These sub-projects fall into a few general -categories: - -The following sub-projects represent the bare minimum required to build -a functioning CPython interpreter. If nothing else builds but these, -you'll have a very limited but usable python.exe: -pythoncore - .dll and .lib -python - .exe - -These sub-projects provide extra executables that are useful for running -CPython in different ways: -pythonw - pythonw.exe, a variant of python.exe that doesn't open a Command - Prompt window -pylauncher - py.exe, the Python Launcher for Windows, see - http://docs.python.org/3/using/windows.html#launcher -pywlauncher - pyw.exe, a variant of py.exe that doesn't open a Command Prompt - window -_testembed - _testembed.exe, a small program that embeds Python for testing - purposes, used by test_capi.py - -These are miscellaneous sub-projects that don't really fit the other -categories: -_freeze_importlib - _freeze_importlib.exe, used to regenerate Python\importlib.h after - changes have been made to Lib\importlib\_bootstrap.py -python3dll - python3.dll, the PEP 384 Stable ABI dll -xxlimited - builds an example module that makes use of the PEP 384 Stable ABI, - see Modules\xxlimited.c - -The following sub-projects are for individual modules of the standard -library which are implemented in C; each one builds a DLL (renamed to -.pyd) of the same name as the project: -_ctypes -_ctypes_test -_decimal -_elementtree -_hashlib -_msi -_multiprocessing -_overlapped -_socket -_testcapi -_testbuffer -_testimportmultiple -pyexpat -select -unicodedata -winsound - -The following Python-controlled sub-projects wrap external projects. -Note that these external libraries are not necessary for a working -interpreter, but they do implement several major features. See the -"Getting External Sources" section below for additional information -about getting the source for building these libraries. The sub-projects -are: -_bz2 - Python wrapper for version 1.0.6 of the libbzip2 compression library - Homepage: - http://www.bzip.org/ -_lzma - Python wrapper for the liblzma compression library, using pre-built - binaries of XZ Utils version 5.0.5 - Homepage: - http://tukaani.org/xz/ -_ssl - Python wrapper for version 1.0.2k of the OpenSSL secure sockets - library, which is built by ssl.vcxproj - Homepage: - http://www.openssl.org/ - - Building OpenSSL requires nasm.exe (the Netwide Assembler), version - 2.10 or newer from - http://www.nasm.us/ - to be somewhere on your PATH. More recent versions of OpenSSL may - need a later version of NASM. If OpenSSL's self tests don't pass, - you should first try to update NASM and do a full rebuild of - OpenSSL. If you use the PCbuild\get_externals.bat method - for getting sources, it also downloads a version of NASM which the - libeay/ssleay sub-projects use. - - The libeay/ssleay sub-projects expect your OpenSSL sources to have - already been configured and be ready to build. If you get your sources - from svn.python.org as suggested in the "Getting External Sources" - section below, the OpenSSL source will already be ready to go. If - you want to build a different version, you will need to run - - PCbuild\prepare_ssl.py path\to\openssl-source-dir - - That script will prepare your OpenSSL sources in the same way that - those available on svn.python.org have been prepared. Note that - Perl must be installed and available on your PATH to configure - OpenSSL. ActivePerl is recommended and is available from - http://www.activestate.com/activeperl/ - - The libeay and ssleay sub-projects will build the modules of OpenSSL - required by _ssl and _hashlib and may need to be manually updated when - upgrading to a newer version of OpenSSL or when adding new - functionality to _ssl or _hashlib. They will not clean up their output - with the normal Clean target; CleanAll should be used instead. -_sqlite3 - Wraps SQLite 3.8.11.0, which is itself built by sqlite3.vcxproj - Homepage: - http://www.sqlite.org/ -_tkinter - Wraps version 8.6.4 of the Tk windowing system. - Homepage: - http://www.tcl.tk/ - - Tkinter's dependencies are built by the tcl.vcxproj and tk.vcxproj - projects. The tix.vcxproj project also builds the Tix extended - widget set for use with Tkinter. - - Those three projects install their respective components in a - directory alongside the source directories called "tcltk" on - Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs - into the current output directory, which should ensure that Tkinter - is able to load Tcl/Tk without having to change your PATH. - - The tcl, tk, and tix sub-projects do not clean their builds with - the normal Clean target; if you need to rebuild, you should use the - CleanAll target or manually delete their builds. - - -Getting External Sources ------------------------- - -The last category of sub-projects listed above wrap external projects -Python doesn't control, and as such a little more work is required in -order to download the relevant source files for each project before they -can be built. However, a simple script is provided to make this as -painless as possible, called "get_externals.bat" and located in this -directory. This script extracts all the external sub-projects from - http://svn.python.org/projects/external -via Subversion (so you'll need svn.exe on your PATH) and places them -in ..\externals (relative to this directory). - -It is also possible to download sources from each project's homepage, -though you may have to change folder names or pass the names to MSBuild -as the values of certain properties in order for the build solution to -find them. This is an advanced topic and not necessarily fully -supported. - -The get_externals.bat script is called automatically by build.bat when -you pass the '-e' option to it. - - -Profile Guided Optimization ---------------------------- - -The solution has two configurations for PGO. The PGInstrument -configuration must be built first. The PGInstrument binaries are linked -against a profiling library and contain extra debug information. The -PGUpdate configuration takes the profiling data and generates optimized -binaries. - -The build_pgo.bat script automates the creation of optimized binaries. -It creates the PGI files, runs the unit test suite or PyBench with the -PGI python, and finally creates the optimized files. - -See - http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.140).aspx -for more on this topic. - - -Static library --------------- - -The solution has no configuration for static libraries. However it is -easy to build a static library instead of a DLL. You simply have to set -the "Configuration Type" to "Static Library (.lib)" and alter the -preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may -also have to change the "Runtime Library" from "Multi-threaded DLL -(/MD)" to "Multi-threaded (/MT)". - - -Visual Studio properties ------------------------- - -The PCbuild solution makes use of Visual Studio property files (*.props) -to simplify each project. The properties can be viewed in the Property -Manager (View -> Other Windows -> Property Manager) but should be -carefully modified by hand. - -The property files used are: - * python (versions, directories and build names) - * pyproject (base settings for all projects) - * openssl (used by libeay and ssleay projects) - * tcltk (used by _tkinter, tcl, tk and tix projects) - -The pyproject property file defines all of the build settings for each -project, with some projects overriding certain specific values. The GUI -doesn't always reflect the correct settings and may confuse the user -with false information, especially for settings that automatically adapt -for diffirent configurations. +Quick Start Guide +----------------- + +1. Install Microsoft Visual Studio 2015, any edition. +2. Install Subversion, and make sure 'svn.exe' is on your PATH. +3. Run "build.bat -e" to build Python in 32-bit Release configuration. +4. (Optional, but recommended) Run the test suite with "rt.bat -q". + + +Building Python using Microsoft Visual C++ +------------------------------------------ + +This directory is used to build CPython for Microsoft Windows NT version +6.0 or higher (Windows Vista, Windows Server 2008, or later) on 32 and 64 +bit platforms. Using this directory requires an installation of +Microsoft Visual C++ 2015 (MSVC 14.0) of any edition. The specific +requirements are as follows: + +Visual Studio Express 2015 for Desktop +Visual Studio Professional 2015 + Either edition is sufficient for building all configurations except + for Profile Guided Optimization. + The Python build solution pcbuild.sln makes use of Solution Folders, + which this edition does not support. Any time pcbuild.sln is opened + or reloaded by Visual Studio, a warning about Solution Folders will + be displayed, which can be safely dismissed with no impact on your + ability to build Python. + Required for building 64-bit Debug and Release configuration builds +Visual Studio Premium 2015 + Required for building Release configuration builds that make use of + Profile Guided Optimization (PGO), on either platform. + +All you need to do to build is open the solution "pcbuild.sln" in Visual +Studio, select the desired combination of configuration and platform, +then build with "Build Solution". You can also build from the command +line using the "build.bat" script in this directory; see below for +details. The solution is configured to build the projects in the correct +order. + +The solution currently supports two platforms. The Win32 platform is +used to build standard x86-compatible 32-bit binaries, output into the +win32 sub-directory. The x64 platform is used for building 64-bit AMD64 +(aka x86_64 or EM64T) binaries, output into the amd64 sub-directory. +The Itanium (IA-64) platform is no longer supported. + +Four configuration options are supported by the solution: +Debug + Used to build Python with extra debugging capabilities, equivalent + to using ./configure --with-pydebug on UNIX. All binaries built + using this configuration have "_d" added to their name: + python35_d.dll, python_d.exe, parser_d.pyd, and so on. Both the + build and rt (run test) batch files in this directory accept a -d + option for debug builds. If you are building Python to help with + development of CPython, you will most likely use this configuration. +PGInstrument, PGUpdate + Used to build Python in Release configuration using PGO, which + requires Premium Edition of Visual Studio. See the "Profile + Guided Optimization" section below for more information. Build + output from each of these configurations lands in its own + sub-directory of this directory. The official Python releases may + be built using these configurations. +Release + Used to build Python as it is meant to be used in production + settings, though without PGO. + + +Building Python using the build.bat script +---------------------------------------------- + +In this directory you can find build.bat, a script designed to make +building Python on Windows simpler. This script will use the env.bat +script to detect one of Visual Studio 2015, 2013, 2012, or 2010, any of +which may be used to build Python, though only Visual Studio 2015 is +officially supported. + +By default, build.bat will build Python in Release configuration for +the 32-bit Win32 platform. It accepts several arguments to change +this behavior, try `build.bat -h` to learn more. + + +C Runtime +--------- + +Visual Studio 2015 uses version 14 of the C runtime (MSVCRT14). The +executables no longer use the "Side by Side" assemblies used in previous +versions of the compiler. This simplifies distribution of applications. + +The run time libraries are available under the VC/Redist folder of your +Visual Studio distribution. For more info, see the Readme in the +VC/Redist folder. + + +Sub-Projects +------------ + +The CPython project is split up into several smaller sub-projects which +are managed by the pcbuild.sln solution file. Each sub-project is +represented by a .vcxproj and a .vcxproj.filters file starting with the +name of the sub-project. These sub-projects fall into a few general +categories: + +The following sub-projects represent the bare minimum required to build +a functioning CPython interpreter. If nothing else builds but these, +you'll have a very limited but usable python.exe: +pythoncore + .dll and .lib +python + .exe + +These sub-projects provide extra executables that are useful for running +CPython in different ways: +pythonw + pythonw.exe, a variant of python.exe that doesn't open a Command + Prompt window +pylauncher + py.exe, the Python Launcher for Windows, see + http://docs.python.org/3/using/windows.html#launcher +pywlauncher + pyw.exe, a variant of py.exe that doesn't open a Command Prompt + window +_testembed + _testembed.exe, a small program that embeds Python for testing + purposes, used by test_capi.py + +These are miscellaneous sub-projects that don't really fit the other +categories: +_freeze_importlib + _freeze_importlib.exe, used to regenerate Python\importlib.h after + changes have been made to Lib\importlib\_bootstrap.py +python3dll + python3.dll, the PEP 384 Stable ABI dll +xxlimited + builds an example module that makes use of the PEP 384 Stable ABI, + see Modules\xxlimited.c + +The following sub-projects are for individual modules of the standard +library which are implemented in C; each one builds a DLL (renamed to +.pyd) of the same name as the project: +_ctypes +_ctypes_test +_decimal +_elementtree +_hashlib +_msi +_multiprocessing +_overlapped +_socket +_testcapi +_testbuffer +_testimportmultiple +pyexpat +select +unicodedata +winsound + +The following Python-controlled sub-projects wrap external projects. +Note that these external libraries are not necessary for a working +interpreter, but they do implement several major features. See the +"Getting External Sources" section below for additional information +about getting the source for building these libraries. The sub-projects +are: +_bz2 + Python wrapper for version 1.0.6 of the libbzip2 compression library + Homepage: + http://www.bzip.org/ +_lzma + Python wrapper for the liblzma compression library, using pre-built + binaries of XZ Utils version 5.0.5 + Homepage: + http://tukaani.org/xz/ +_ssl + Python wrapper for version 1.0.2k of the OpenSSL secure sockets + library, which is built by ssl.vcxproj + Homepage: + http://www.openssl.org/ + + Building OpenSSL requires nasm.exe (the Netwide Assembler), version + 2.10 or newer from + http://www.nasm.us/ + to be somewhere on your PATH. More recent versions of OpenSSL may + need a later version of NASM. If OpenSSL's self tests don't pass, + you should first try to update NASM and do a full rebuild of + OpenSSL. If you use the PCbuild\get_externals.bat method + for getting sources, it also downloads a version of NASM which the + libeay/ssleay sub-projects use. + + The libeay/ssleay sub-projects expect your OpenSSL sources to have + already been configured and be ready to build. If you get your sources + from svn.python.org as suggested in the "Getting External Sources" + section below, the OpenSSL source will already be ready to go. If + you want to build a different version, you will need to run + + PCbuild\prepare_ssl.py path\to\openssl-source-dir + + That script will prepare your OpenSSL sources in the same way that + those available on svn.python.org have been prepared. Note that + Perl must be installed and available on your PATH to configure + OpenSSL. ActivePerl is recommended and is available from + http://www.activestate.com/activeperl/ + + The libeay and ssleay sub-projects will build the modules of OpenSSL + required by _ssl and _hashlib and may need to be manually updated when + upgrading to a newer version of OpenSSL or when adding new + functionality to _ssl or _hashlib. They will not clean up their output + with the normal Clean target; CleanAll should be used instead. +_sqlite3 + Wraps SQLite 3.8.11.0, which is itself built by sqlite3.vcxproj + Homepage: + http://www.sqlite.org/ +_tkinter + Wraps version 8.6.4 of the Tk windowing system. + Homepage: + http://www.tcl.tk/ + + Tkinter's dependencies are built by the tcl.vcxproj and tk.vcxproj + projects. The tix.vcxproj project also builds the Tix extended + widget set for use with Tkinter. + + Those three projects install their respective components in a + directory alongside the source directories called "tcltk" on + Win32 and "tcltk64" on x64. They also copy the Tcl and Tk DLLs + into the current output directory, which should ensure that Tkinter + is able to load Tcl/Tk without having to change your PATH. + + The tcl, tk, and tix sub-projects do not clean their builds with + the normal Clean target; if you need to rebuild, you should use the + CleanAll target or manually delete their builds. + + +Getting External Sources +------------------------ + +The last category of sub-projects listed above wrap external projects +Python doesn't control, and as such a little more work is required in +order to download the relevant source files for each project before they +can be built. However, a simple script is provided to make this as +painless as possible, called "get_externals.bat" and located in this +directory. This script extracts all the external sub-projects from + http://svn.python.org/projects/external +via Subversion (so you'll need svn.exe on your PATH) and places them +in ..\externals (relative to this directory). + +It is also possible to download sources from each project's homepage, +though you may have to change folder names or pass the names to MSBuild +as the values of certain properties in order for the build solution to +find them. This is an advanced topic and not necessarily fully +supported. + +The get_externals.bat script is called automatically by build.bat when +you pass the '-e' option to it. + + +Profile Guided Optimization +--------------------------- + +The solution has two configurations for PGO. The PGInstrument +configuration must be built first. The PGInstrument binaries are linked +against a profiling library and contain extra debug information. The +PGUpdate configuration takes the profiling data and generates optimized +binaries. + +The build_pgo.bat script automates the creation of optimized binaries. +It creates the PGI files, runs the unit test suite or PyBench with the +PGI python, and finally creates the optimized files. + +See + http://msdn.microsoft.com/en-us/library/e7k32f4k(VS.140).aspx +for more on this topic. + + +Static library +-------------- + +The solution has no configuration for static libraries. However it is +easy to build a static library instead of a DLL. You simply have to set +the "Configuration Type" to "Static Library (.lib)" and alter the +preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may +also have to change the "Runtime Library" from "Multi-threaded DLL +(/MD)" to "Multi-threaded (/MT)". + + +Visual Studio properties +------------------------ + +The PCbuild solution makes use of Visual Studio property files (*.props) +to simplify each project. The properties can be viewed in the Property +Manager (View -> Other Windows -> Property Manager) but should be +carefully modified by hand. + +The property files used are: + * python (versions, directories and build names) + * pyproject (base settings for all projects) + * openssl (used by libeay and ssleay projects) + * tcltk (used by _tkinter, tcl, tk and tix projects) + +The pyproject property file defines all of the build settings for each +project, with some projects overriding certain specific values. The GUI +doesn't always reflect the correct settings and may confuse the user +with false information, especially for settings that automatically adapt +for diffirent configurations. diff --git a/PCbuild/rt.bat b/PCbuild/rt.bat index 20568549b1599d..b49285dcbae127 100644 --- a/PCbuild/rt.bat +++ b/PCbuild/rt.bat @@ -1,60 +1,60 @@ -@echo off -rem Run Tests. Run the regression test suite. -rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args -rem -d Run Debug build (python_d.exe). Else release build. -rem -O Run python.exe or python_d.exe (see -d) with -O. -rem -q "quick" -- normally the tests are run twice, the first time -rem after deleting all the .pyc files reachable from Lib/. -rem -q runs the tests just once, and without deleting .pyc files. -rem -x64 Run the 64-bit build of python (or python_d if -d was specified) -rem from the 'amd64' dir instead of the 32-bit build in this dir. -rem All leading instances of these switches are shifted off, and -rem whatever remains (up to 9 arguments) is passed to regrtest.py. -rem For example, -rem rt -O -d -x test_thread -rem runs -rem python_d -O ../lib/test/regrtest.py -x test_thread -rem twice, and -rem rt -q -g test_binascii -rem runs -rem python_d ../lib/test/regrtest.py -g test_binascii -rem to generate the expected-output file for binascii quickly. -rem -rem Confusing: if you want to pass a comma-separated list, like -rem -u network,largefile -rem then you have to quote it on the rt line, like -rem rt -u "network,largefile" - -setlocal - -set pcbuild=%~dp0 -set prefix=%pcbuild%win32\ -set suffix= -set qmode= -set dashO= -set regrtestargs= - -:CheckOpts -if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts -if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts -if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts -if "%1"=="-x64" (set prefix=%pcbuild%amd64\) & shift & goto CheckOpts -if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts - -set exe=%prefix%python%suffix%.exe -set cmd="%exe%" %dashO% -Wd -E -bb "%pcbuild%..\lib\test\regrtest.py" %regrtestargs% -if defined qmode goto Qmode - -echo Deleting .pyc files ... -"%exe%" "%pcbuild%rmpyc.py" - -echo on -%cmd% -@echo off - -echo About to run again without deleting .pyc first: -pause - -:Qmode -echo on -%cmd% +@echo off +rem Run Tests. Run the regression test suite. +rem Usage: rt [-d] [-O] [-q] [-x64] regrtest_args +rem -d Run Debug build (python_d.exe). Else release build. +rem -O Run python.exe or python_d.exe (see -d) with -O. +rem -q "quick" -- normally the tests are run twice, the first time +rem after deleting all the .pyc files reachable from Lib/. +rem -q runs the tests just once, and without deleting .pyc files. +rem -x64 Run the 64-bit build of python (or python_d if -d was specified) +rem from the 'amd64' dir instead of the 32-bit build in this dir. +rem All leading instances of these switches are shifted off, and +rem whatever remains (up to 9 arguments) is passed to regrtest.py. +rem For example, +rem rt -O -d -x test_thread +rem runs +rem python_d -O ../lib/test/regrtest.py -x test_thread +rem twice, and +rem rt -q -g test_binascii +rem runs +rem python_d ../lib/test/regrtest.py -g test_binascii +rem to generate the expected-output file for binascii quickly. +rem +rem Confusing: if you want to pass a comma-separated list, like +rem -u network,largefile +rem then you have to quote it on the rt line, like +rem rt -u "network,largefile" + +setlocal + +set pcbuild=%~dp0 +set prefix=%pcbuild%win32\ +set suffix= +set qmode= +set dashO= +set regrtestargs= + +:CheckOpts +if "%1"=="-O" (set dashO=-O) & shift & goto CheckOpts +if "%1"=="-q" (set qmode=yes) & shift & goto CheckOpts +if "%1"=="-d" (set suffix=_d) & shift & goto CheckOpts +if "%1"=="-x64" (set prefix=%pcbuild%amd64\) & shift & goto CheckOpts +if NOT "%1"=="" (set regrtestargs=%regrtestargs% %1) & shift & goto CheckOpts + +set exe=%prefix%python%suffix%.exe +set cmd="%exe%" %dashO% -Wd -E -bb "%pcbuild%..\lib\test\regrtest.py" %regrtestargs% +if defined qmode goto Qmode + +echo Deleting .pyc files ... +"%exe%" "%pcbuild%rmpyc.py" + +echo on +%cmd% +@echo off + +echo About to run again without deleting .pyc first: +pause + +:Qmode +echo on +%cmd% diff --git a/Tools/buildbot/build-amd64.bat b/Tools/buildbot/build-amd64.bat index f77407bcf7031c..ab4231ebfd98e3 100644 --- a/Tools/buildbot/build-amd64.bat +++ b/Tools/buildbot/build-amd64.bat @@ -1,5 +1,5 @@ -@rem Formerly used by the buildbot "compile" step. -@echo This script is no longer used and may be removed in the future. -@echo To get the same effect as this script, use -@echo PCbuild\build.bat -d -e -k -p x64 -call "%~dp0build.bat" -p x64 %* +@rem Formerly used by the buildbot "compile" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use +@echo PCbuild\build.bat -d -e -k -p x64 +call "%~dp0build.bat" -p x64 %* diff --git a/Tools/buildbot/build.bat b/Tools/buildbot/build.bat index 5e840cc7eaca84..9af511a81dbd8e 100644 --- a/Tools/buildbot/build.bat +++ b/Tools/buildbot/build.bat @@ -1,17 +1,17 @@ -@rem Used by the buildbot "compile" step. - -@rem Clean up -call "%~dp0clean.bat" %* - -@rem If you need the buildbots to start fresh (such as when upgrading to -@rem a new version of an external library, especially Tcl/Tk): -@rem 1) uncomment the following line: - -@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only - -@rem 2) commit and push -@rem 3) wait for all Windows bots to start a build with that changeset -@rem 4) re-comment, commit and push again - -@rem Do the build -call "%~dp0..\..\PCbuild\build.bat" -e -d -k -v %* +@rem Used by the buildbot "compile" step. + +@rem Clean up +call "%~dp0clean.bat" %* + +@rem If you need the buildbots to start fresh (such as when upgrading to +@rem a new version of an external library, especially Tcl/Tk): +@rem 1) uncomment the following line: + +@rem call "%~dp0..\..\PCbuild\get_externals.bat" --clean-only + +@rem 2) commit and push +@rem 3) wait for all Windows bots to start a build with that changeset +@rem 4) re-comment, commit and push again + +@rem Do the build +call "%~dp0..\..\PCbuild\build.bat" -e -d -k -v %* diff --git a/Tools/buildbot/buildmsi.bat b/Tools/buildbot/buildmsi.bat index e3c2dbd73d00df..6804d794799509 100644 --- a/Tools/buildbot/buildmsi.bat +++ b/Tools/buildbot/buildmsi.bat @@ -1,9 +1,9 @@ -@rem Used by the buildbot "buildmsi" step. -setlocal - -pushd - -@rem build both snapshot MSIs -call "%~dp0..\msi\build.bat" -x86 -x64 - +@rem Used by the buildbot "buildmsi" step. +setlocal + +pushd + +@rem build both snapshot MSIs +call "%~dp0..\msi\build.bat" -x86 -x64 + popd \ No newline at end of file diff --git a/Tools/buildbot/clean-amd64.bat b/Tools/buildbot/clean-amd64.bat index b53c7c1038d391..a0d4b07482bf99 100644 --- a/Tools/buildbot/clean-amd64.bat +++ b/Tools/buildbot/clean-amd64.bat @@ -1,5 +1,5 @@ -@rem Formerly used by the buildbot "clean" step. -@echo This script is no longer used and may be removed in the future. -@echo To get the same effect as this script, use `clean.bat` from this -@echo directory and pass `-p x64` as two arguments. -call "%~dp0clean.bat" -p x64 %* +@rem Formerly used by the buildbot "clean" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use `clean.bat` from this +@echo directory and pass `-p x64` as two arguments. +call "%~dp0clean.bat" -p x64 %* diff --git a/Tools/buildbot/clean.bat b/Tools/buildbot/clean.bat index 0fc68fd727192d..c2efd5b29b5848 100644 --- a/Tools/buildbot/clean.bat +++ b/Tools/buildbot/clean.bat @@ -1,16 +1,16 @@ -@echo off -rem Used by the buildbot "clean" step. - -setlocal -set root=%~dp0..\.. -set pcbuild=%root%\PCbuild - -echo Deleting build -call "%pcbuild%\build.bat" -t Clean -k %* -call "%pcbuild%\build.bat" -t Clean -k -d %* - -echo Deleting .pyc/.pyo files ... -del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" - -echo Deleting test leftovers ... -rmdir /s /q "%root%\build" +@echo off +rem Used by the buildbot "clean" step. + +setlocal +set root=%~dp0..\.. +set pcbuild=%root%\PCbuild + +echo Deleting build +call "%pcbuild%\build.bat" -t Clean -k %* +call "%pcbuild%\build.bat" -t Clean -k -d %* + +echo Deleting .pyc/.pyo files ... +del /s "%root%\Lib\*.pyc" "%root%\Lib\*.pyo" + +echo Deleting test leftovers ... +rmdir /s /q "%root%\build" diff --git a/Tools/buildbot/external-amd64.bat b/Tools/buildbot/external-amd64.bat index bfaef055f54b98..1a67b0f21dd007 100644 --- a/Tools/buildbot/external-amd64.bat +++ b/Tools/buildbot/external-amd64.bat @@ -1,3 +1,3 @@ -@echo This script is no longer used and may be removed in the future. -@echo Please use PCbuild\get_externals.bat instead. -@"%~dp0..\..\PCbuild\get_externals.bat" %* +@echo This script is no longer used and may be removed in the future. +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/external.bat b/Tools/buildbot/external.bat index bfaef055f54b98..1a67b0f21dd007 100644 --- a/Tools/buildbot/external.bat +++ b/Tools/buildbot/external.bat @@ -1,3 +1,3 @@ -@echo This script is no longer used and may be removed in the future. -@echo Please use PCbuild\get_externals.bat instead. -@"%~dp0..\..\PCbuild\get_externals.bat" %* +@echo This script is no longer used and may be removed in the future. +@echo Please use PCbuild\get_externals.bat instead. +@"%~dp0..\..\PCbuild\get_externals.bat" %* diff --git a/Tools/buildbot/test-amd64.bat b/Tools/buildbot/test-amd64.bat index e48329c0b30f3c..f994d2dccb8589 100644 --- a/Tools/buildbot/test-amd64.bat +++ b/Tools/buildbot/test-amd64.bat @@ -1,6 +1,6 @@ -@rem Formerly used by the buildbot "test" step. -@echo This script is no longer used and may be removed in the future. -@echo To get the same effect as this script, use -@echo PCbuild\rt.bat -q -d -x64 -uall -rwW -@echo or use `test.bat` in this directory and pass `-x64` as an argument. -call "%~dp0test.bat" -x64 %* +@rem Formerly used by the buildbot "test" step. +@echo This script is no longer used and may be removed in the future. +@echo To get the same effect as this script, use +@echo PCbuild\rt.bat -q -d -x64 -uall -rwW +@echo or use `test.bat` in this directory and pass `-x64` as an argument. +call "%~dp0test.bat" -x64 %* diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index ff7d167e6a7b25..a2c47839deadab 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,19 +1,19 @@ -@echo off -rem Used by the buildbot "test" step. -setlocal - -set here=%~dp0 -set rt_opts=-q -d -set regrtest_args= - -:CheckOpts -if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts -if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts -if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts -if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts - -echo on -call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=3600 %regrtest_args% +@echo off +rem Used by the buildbot "test" step. +setlocal + +set here=%~dp0 +set rt_opts=-q -d +set regrtest_args= + +:CheckOpts +if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts +if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts +if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts +if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts + +echo on +call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=3600 %regrtest_args% diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 69f00c0bb43f84..59e0261c6d5236 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -1,79 +1,79 @@ -@echo off -setlocal -set D=%~dp0 -set PCBUILD=%D%..\..\PCBuild\ - -set BUILDX86= -set BUILDX64= -set BUILDDOC= -set BUILDTEST=--test-marker -set BUILDPACK= -set REBUILD= - -:CheckOpts -if "%~1" EQU "-h" goto Help -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 "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts -if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts - -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) - -call "%D%get_externals.bat" - -call "%PCBUILD%env.bat" x86 - -if defined BUILDX86 ( - call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof - call "%PCBUILD%build.bat" -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof -) -if defined BUILDX64 ( - call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof - call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% - if errorlevel 1 goto :eof -) - -if defined BUILDDOC ( - call "%PCBUILD%..\Doc\make.bat" htmlhelp - if errorlevel 1 goto :eof -) - -rem Build the launcher MSI separately -msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 - -set BUILD_CMD="%D%bundle\snapshot.wixproj" -if defined BUILDTEST ( - set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true -) -if defined BUILDPACK ( - set BUILD_CMD=%BUILD_CMD% /p:Pack=true -) -if defined REBUILD ( - set BUILD_CMD=%BUILD_CMD% /t:Rebuild -) - -if defined BUILDX86 ( - msbuild %BUILD_CMD% - if errorlevel 1 goto :eof -) -if defined BUILDX64 ( - msbuild /p:Platform=x64 %BUILD_CMD% - if errorlevel 1 goto :eof -) - -exit /B 0 - -:Help -echo build.bat [-x86] [-x64] [--doc] [-h] [--no-test-marker] [--pack] [-r] -echo. -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo --doc Build CHM documentation -echo --no-test-marker Build without test markers -echo --pack Embed core MSIs into installer -echo -r Rebuild rather than incremental build +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set BUILDDOC= +set BUILDTEST=--test-marker +set BUILDPACK= +set REBUILD= + +:CheckOpts +if "%~1" EQU "-h" goto Help +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 "--no-test-marker" (set BUILDTEST=) && shift && goto CheckOpts +if "%~1" EQU "--pack" (set BUILDPACK=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +call "%D%get_externals.bat" + +call "%PCBUILD%env.bat" x86 + +if defined BUILDX86 ( + call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + call "%PCBUILD%build.bat" -p x64 -d -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof + call "%PCBUILD%build.bat" -p x64 -e %REBUILD% %BUILDTEST% + if errorlevel 1 goto :eof +) + +if defined BUILDDOC ( + call "%PCBUILD%..\Doc\make.bat" htmlhelp + if errorlevel 1 goto :eof +) + +rem Build the launcher MSI separately +msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 + +set BUILD_CMD="%D%bundle\snapshot.wixproj" +if defined BUILDTEST ( + set BUILD_CMD=%BUILD_CMD% /p:UseTestMarker=true +) +if defined BUILDPACK ( + set BUILD_CMD=%BUILD_CMD% /p:Pack=true +) +if defined REBUILD ( + set BUILD_CMD=%BUILD_CMD% /t:Rebuild +) + +if defined BUILDX86 ( + msbuild %BUILD_CMD% + if errorlevel 1 goto :eof +) +if defined BUILDX64 ( + msbuild /p:Platform=x64 %BUILD_CMD% + if errorlevel 1 goto :eof +) + +exit /B 0 + +:Help +echo build.bat [-x86] [-x64] [--doc] [-h] [--no-test-marker] [--pack] [-r] +echo. +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo --doc Build CHM documentation +echo --no-test-marker Build without test markers +echo --pack Embed core MSIs into installer +echo -r Rebuild rather than incremental build diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index 706febf2534f71..c316cd7f24d303 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -1,246 +1,246 @@ -@setlocal -@echo off - -rem This script is intended for building official releases of Python. -rem To use it to build alternative releases, you should clone this file -rem and modify the following three URIs. - -rem These two will ensure that your release can be installed -rem alongside an official Python release, by modifying the GUIDs used -rem for all components. -rem -rem The following substitutions will be applied to the release URI: -rem Variable Description Example -rem {arch} architecture amd64, win32 -set RELEASE_URI=http://www.python.org/{arch} - -rem This is the URL that will be used to download installation files. -rem The files available from the default URL *will* conflict with your -rem installer. Trust me, you don't want them, even if it seems like a -rem good idea. -rem -rem The following substitutions will be applied to the download URL: -rem Variable Description Example -rem {version} version number 3.5.0 -rem {arch} architecture amd64, win32 -rem {releasename} release name a1, b2, rc3 (or blank for final) -rem {msi} MSI filename core.msi -set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} - -set D=%~dp0 -set PCBUILD=%D%..\..\PCBuild\ -set EXTERNALS=%D%..\..\externals\windows-installer\ - -set BUILDX86= -set BUILDX64= -set TARGET=Rebuild -set TESTTARGETDIR= -set PGO= -set BUILDNUGET=1 -set BUILDZIP=1 - - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts -if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts -if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts -if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts -if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts - -if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 - -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) - -if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" -if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 - -call "%D%get_externals.bat" - -:builddoc -if "%SKIPBUILD%" EQU "1" goto skipdoc -if "%SKIPDOC%" EQU "1" goto skipdoc - -if not defined PYTHON where py -q || echo Cannot find py on path and PYTHON is not set. && exit /B 1 -if not defined SPHINXBUILD where sphinx-build -q || echo Cannot find sphinx-build on path and SPHINXBUILD is not set. && exit /B 1 - -call "%D%..\..\doc\make.bat" htmlhelp -if errorlevel 1 goto :eof -:skipdoc - -where dlltool /q && goto skipdlltoolsearch -set _DLLTOOL_PATH= -where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" -if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 -for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf -set _DLLTOOL_PATH= -:skipdlltoolsearch - -if defined BUILDX86 ( - call :build x86 - if errorlevel 1 exit /B -) - -if defined BUILDX64 ( - call :build x64 "%PGO%" - if errorlevel 1 exit /B -) - -if defined TESTTARGETDIR ( - call "%D%testrelease.bat" -t "%TESTTARGETDIR%" -) - -exit /B 0 - -:build -@setlocal -@echo off - -if "%1" EQU "x86" ( - call "%PCBUILD%env.bat" x86 - set BUILD=%PCBUILD%win32\ - set BUILD_PLAT=Win32 - set OUTDIR_PLAT=win32 - set OBJDIR_PLAT=x86 -) else if "%~2" NEQ "" ( - call "%PCBUILD%env.bat" amd64 - set PGO=%~2 - set BUILD=%PCBUILD%amd64-pgo\ - set BUILD_PLAT=x64 - set OUTDIR_PLAT=amd64 - set OBJDIR_PLAT=x64 -) else ( - call "%PCBUILD%env.bat" amd64 - set BUILD=%PCBUILD%amd64\ - set BUILD_PLAT=x64 - set OUTDIR_PLAT=amd64 - set OBJDIR_PLAT=x64 -) - -if exist "%BUILD%en-us" ( - echo Deleting %BUILD%en-us - rmdir /q/s "%BUILD%en-us" - if errorlevel 1 exit /B -) - -if exist "%D%obj\Release_%OBJDIR_PLAT%" ( - echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" - rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" - if errorlevel 1 exit /B -) - -if not "%CERTNAME%" EQU "" ( - set CERTOPTS="/p:SigningCertificate=%CERTNAME%" -) else ( - set CERTOPTS= -) - -if not "%SKIPBUILD%" EQU "1" ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS% - @if errorlevel 1 exit /B - @rem build.bat turns echo back on, so we disable it again - @echo off - - if "%PGO%" EQU "" ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %CERTOPTS% - ) else ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGInstrument -t %TARGET% %CERTOPTS% - @if errorlevel 1 exit /B - - @del "%BUILD%*.pgc" - if "%PGO%" EQU "default" ( - "%BUILD%python.exe" -m test -q --pgo - ) else if "%PGO%" EQU "default2" ( - "%BUILD%python.exe" -m test -r -q --pgo - "%BUILD%python.exe" -m test -r -q --pgo - ) else if "%PGO%" EQU "default10" ( - for /L %%i in (0, 1, 9) do "%BUILD%python.exe" -m test -q -r --pgo - ) else if "%PGO%" EQU "pybench" ( - "%BUILD%python.exe" "%PCBUILD%..\Tools\pybench\pybench.py" - ) else ( - "%BUILD%python.exe" %PGO% - ) - - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t Build %CERTOPTS% - ) - @if errorlevel 1 exit /B - @echo off -) - -set BUILDOPTS=/p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% -if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD% -msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% -msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true -if errorlevel 1 exit /B -msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false -if errorlevel 1 exit /B - -if defined BUILDZIP ( - msbuild "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B -) - -if defined BUILDNUGET ( - msbuild "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" - if errorlevel 1 exit /B -) - -if not "%OUTDIR%" EQU "" ( - mkdir "%OUTDIR%\%OUTDIR_PLAT%" - mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries" - mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols" - robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb" - robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" - robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" -) - -exit /B 0 - -:Help -echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND] -echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] -echo [--download DOWNLOAD URL] [--test TARGETDIR] -echo [-h] -echo. -echo --out (-o) Specify an additional output directory for installers -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo --build (-b) Incrementally build Python rather than rebuilding -echo --skip-build (-B) Do not build Python (just do the installers) -echo --skip-doc (-D) Do not build documentation -echo --skip-nuget Do not build Nuget packages -echo --skip-zip Do not build embeddable package -echo --pgo Build x64 installers using PGO -echo --download Specify the full download URL for MSIs -echo --test Specify the test directory to run the installer tests -echo -h Display this help information -echo. -echo If no architecture is specified, all architectures will be built. -echo If --test is not specified, the installer tests are not run. -echo. -echo For the --pgo option, any Python command line can be used as well as the -echo following shortcuts: -echo Shortcut Description -echo default Test suite with --pgo -echo default2 2x test suite with --pgo and randomized test order -echo default10 10x test suite with --pgo and randomized test order -echo pybench pybench script -echo. -echo The following substitutions will be applied to the download URL: -echo Variable Description Example -echo {version} version number 3.5.0 -echo {arch} architecture amd64, win32 -echo {releasename} release name a1, b2, rc3 (or blank for final) -echo {msi} MSI filename core.msi +@setlocal +@echo off + +rem This script is intended for building official releases of Python. +rem To use it to build alternative releases, you should clone this file +rem and modify the following three URIs. + +rem These two will ensure that your release can be installed +rem alongside an official Python release, by modifying the GUIDs used +rem for all components. +rem +rem The following substitutions will be applied to the release URI: +rem Variable Description Example +rem {arch} architecture amd64, win32 +set RELEASE_URI=http://www.python.org/{arch} + +rem This is the URL that will be used to download installation files. +rem The files available from the default URL *will* conflict with your +rem installer. Trust me, you don't want them, even if it seems like a +rem good idea. +rem +rem The following substitutions will be applied to the download URL: +rem Variable Description Example +rem {version} version number 3.5.0 +rem {arch} architecture amd64, win32 +rem {releasename} release name a1, b2, rc3 (or blank for final) +rem {msi} MSI filename core.msi +set DOWNLOAD_URL=https://www.python.org/ftp/python/{version}/{arch}{releasename}/{msi} + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ +set EXTERNALS=%D%..\..\externals\windows-installer\ + +set BUILDX86= +set BUILDX64= +set TARGET=Rebuild +set TESTTARGETDIR= +set PGO= +set BUILDNUGET=1 +set BUILDZIP=1 + + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-c" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--certificate" (set CERTNAME=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-o" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--out" (set OUTDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-D" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "--skip-doc" (set SKIPDOC=1) && shift && goto CheckOpts +if "%1" EQU "-B" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--skip-build" (set SKIPBUILD=1) && shift && goto CheckOpts +if "%1" EQU "--download" (set DOWNLOAD_URL=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--test" (set TESTTARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-b" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts +if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts +if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts + +if "%1" NEQ "" echo Invalid option: "%1" && exit /B 1 + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP%\git.loc" & del "%TEMP%\git.loc" +if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 + +call "%D%get_externals.bat" + +:builddoc +if "%SKIPBUILD%" EQU "1" goto skipdoc +if "%SKIPDOC%" EQU "1" goto skipdoc + +if not defined PYTHON where py -q || echo Cannot find py on path and PYTHON is not set. && exit /B 1 +if not defined SPHINXBUILD where sphinx-build -q || echo Cannot find sphinx-build on path and SPHINXBUILD is not set. && exit /B 1 + +call "%D%..\..\doc\make.bat" htmlhelp +if errorlevel 1 goto :eof +:skipdoc + +where dlltool /q && goto skipdlltoolsearch +set _DLLTOOL_PATH= +where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" +if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 +for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf +set _DLLTOOL_PATH= +:skipdlltoolsearch + +if defined BUILDX86 ( + call :build x86 + if errorlevel 1 exit /B +) + +if defined BUILDX64 ( + call :build x64 "%PGO%" + if errorlevel 1 exit /B +) + +if defined TESTTARGETDIR ( + call "%D%testrelease.bat" -t "%TESTTARGETDIR%" +) + +exit /B 0 + +:build +@setlocal +@echo off + +if "%1" EQU "x86" ( + call "%PCBUILD%env.bat" x86 + set BUILD=%PCBUILD%win32\ + set BUILD_PLAT=Win32 + set OUTDIR_PLAT=win32 + set OBJDIR_PLAT=x86 +) else if "%~2" NEQ "" ( + call "%PCBUILD%env.bat" amd64 + set PGO=%~2 + set BUILD=%PCBUILD%amd64-pgo\ + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 +) else ( + call "%PCBUILD%env.bat" amd64 + set BUILD=%PCBUILD%amd64\ + set BUILD_PLAT=x64 + set OUTDIR_PLAT=amd64 + set OBJDIR_PLAT=x64 +) + +if exist "%BUILD%en-us" ( + echo Deleting %BUILD%en-us + rmdir /q/s "%BUILD%en-us" + if errorlevel 1 exit /B +) + +if exist "%D%obj\Release_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" + if errorlevel 1 exit /B +) + +if not "%CERTNAME%" EQU "" ( + set CERTOPTS="/p:SigningCertificate=%CERTNAME%" +) else ( + set CERTOPTS= +) + +if not "%SKIPBUILD%" EQU "1" ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS% + @if errorlevel 1 exit /B + @rem build.bat turns echo back on, so we disable it again + @echo off + + if "%PGO%" EQU "" ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %CERTOPTS% + ) else ( + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGInstrument -t %TARGET% %CERTOPTS% + @if errorlevel 1 exit /B + + @del "%BUILD%*.pgc" + if "%PGO%" EQU "default" ( + "%BUILD%python.exe" -m test -q --pgo + ) else if "%PGO%" EQU "default2" ( + "%BUILD%python.exe" -m test -r -q --pgo + "%BUILD%python.exe" -m test -r -q --pgo + ) else if "%PGO%" EQU "default10" ( + for /L %%i in (0, 1, 9) do "%BUILD%python.exe" -m test -q -r --pgo + ) else if "%PGO%" EQU "pybench" ( + "%BUILD%python.exe" "%PCBUILD%..\Tools\pybench\pybench.py" + ) else ( + "%BUILD%python.exe" %PGO% + ) + + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t Build %CERTOPTS% + ) + @if errorlevel 1 exit /B + @echo off +) + +set BUILDOPTS=/p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% +if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD% +msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% +msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true +if errorlevel 1 exit /B +msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false +if errorlevel 1 exit /B + +if defined BUILDZIP ( + msbuild "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B +) + +if defined BUILDNUGET ( + msbuild "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" + if errorlevel 1 exit /B +) + +if not "%OUTDIR%" EQU "" ( + mkdir "%OUTDIR%\%OUTDIR_PLAT%" + mkdir "%OUTDIR%\%OUTDIR_PLAT%\binaries" + mkdir "%OUTDIR%\%OUTDIR_PLAT%\symbols" + robocopy "%BUILD%en-us" "%OUTDIR%\%OUTDIR_PLAT%" /XF "*.wixpdb" + robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\binaries" *.exe *.dll *.pyd /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" + robocopy "%BUILD%\" "%OUTDIR%\%OUTDIR_PLAT%\symbols" *.pdb /XF "_test*" /XF "*_d.*" /XF "_freeze*" /XF "tcl*" /XF "tk*" /XF "*_test.*" +) + +exit /B 0 + +:Help +echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND] +echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] +echo [--download DOWNLOAD URL] [--test TARGETDIR] +echo [-h] +echo. +echo --out (-o) Specify an additional output directory for installers +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo --build (-b) Incrementally build Python rather than rebuilding +echo --skip-build (-B) Do not build Python (just do the installers) +echo --skip-doc (-D) Do not build documentation +echo --skip-nuget Do not build Nuget packages +echo --skip-zip Do not build embeddable package +echo --pgo Build x64 installers using PGO +echo --download Specify the full download URL for MSIs +echo --test Specify the test directory to run the installer tests +echo -h Display this help information +echo. +echo If no architecture is specified, all architectures will be built. +echo If --test is not specified, the installer tests are not run. +echo. +echo For the --pgo option, any Python command line can be used as well as the +echo following shortcuts: +echo Shortcut Description +echo default Test suite with --pgo +echo default2 2x test suite with --pgo and randomized test order +echo default10 10x test suite with --pgo and randomized test order +echo pybench pybench script +echo. +echo The following substitutions will be applied to the download URL: +echo Variable Description Example +echo {version} version number 3.5.0 +echo {arch} architecture amd64, win32 +echo {releasename} release name a1, b2, rc3 (or blank for final) +echo {msi} MSI filename core.msi diff --git a/Tools/msi/get_externals.bat b/Tools/msi/get_externals.bat index 4ead75e757233e..e1d74de6ac78f5 100644 --- a/Tools/msi/get_externals.bat +++ b/Tools/msi/get_externals.bat @@ -1,27 +1,27 @@ -@echo off -setlocal -rem Simple script to fetch source for external tools - -where /Q svn -if ERRORLEVEL 1 ( - echo.svn.exe must be on your PATH to get external tools. - echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the - echo.command line tools option. - popd - exit /b 1 -) - -if not exist "%~dp0..\..\externals" mkdir "%~dp0..\..\externals" -pushd "%~dp0..\..\externals" - -if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ - -if not exist "windows-installer\.svn" ( - echo.Checking out installer dependencies to %CD%\windows-installer - svn co %SVNROOT%windows-installer -) else ( - echo.Updating installer dependencies in %CD%\windows-installer - svn up windows-installer -) - -popd +@echo off +setlocal +rem Simple script to fetch source for external tools + +where /Q svn +if ERRORLEVEL 1 ( + echo.svn.exe must be on your PATH to get external tools. + echo.Try TortoiseSVN (http://tortoisesvn.net/^) and be sure to check the + echo.command line tools option. + popd + exit /b 1 +) + +if not exist "%~dp0..\..\externals" mkdir "%~dp0..\..\externals" +pushd "%~dp0..\..\externals" + +if "%SVNROOT%"=="" set SVNROOT=http://svn.python.org/projects/external/ + +if not exist "windows-installer\.svn" ( + echo.Checking out installer dependencies to %CD%\windows-installer + svn co %SVNROOT%windows-installer +) else ( + echo.Updating installer dependencies in %CD%\windows-installer + svn up windows-installer +) + +popd diff --git a/Tools/msi/testrelease.bat b/Tools/msi/testrelease.bat index a989575ed6f032..96fdf5eb86e480 100644 --- a/Tools/msi/testrelease.bat +++ b/Tools/msi/testrelease.bat @@ -1,117 +1,117 @@ -@setlocal enableextensions -@echo off - -set D=%~dp0 -set PCBUILD=%D%..\..\PCBuild\ - -set TARGETDIR=%TEMP% -set TESTX86= -set TESTX64= -set TESTALLUSER= -set TESTPERUSER= - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts -if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts -if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts -if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts -if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts -if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts - -if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) -if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) - - -if defined TESTX86 ( - for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( - if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" - if errorlevel 1 exit /B - if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" - if errorlevel 1 exit /B - ) -) - -if defined TESTX64 ( - for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( - if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" - if errorlevel 1 exit /B - if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" - if errorlevel 1 exit /B - ) -) - -exit /B 0 - -:test -@setlocal -@echo on - -@if not exist "%~1" exit /B 1 - -@set EXE=%~1 -@if not "%EXE:embed=%"=="%EXE%" exit /B 0 - -@set EXITCODE=0 -@echo Installing %1 into %2 -"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 - -@if not errorlevel 1 ( - @echo Printing version - "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 -) - -@if not errorlevel 1 ( - @echo Capturing Start Menu - @dir /s/b "%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" > "%~2\startmenu.txt" 2>&1 - @dir /s/b "%APPDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" >> "%~2\startmenu.txt" 2>&1 - - @echo Capturing registry - @for /F "usebackq" %%f in (`reg query HKCR /s /f python /k`) do @( - echo %%f >> "%~2\hkcr.txt" - reg query "%%f" /s >> "%~2\hkcr.txt" 2>&1 - ) - @reg query HKCU\Software\Python /s > "%~2\hkcu.txt" 2>&1 - @reg query HKLM\Software\Python /reg:32 /s > "%~2\hklm.txt" 2>&1 - @reg query HKLM\Software\Python /reg:64 /s >> "%~2\hklm.txt" 2>&1 - cmd /k exit 0 -) - -@if not errorlevel 1 ( - @echo Installing package - "%~2\Python\python.exe" -m pip install "azure<0.10" > "%~2\pip.txt" 2>&1 - @if not errorlevel 1 ( - "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 - ) -) -@if not errorlevel 1 ( - @echo Testing Tcl/tk - @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 - "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 - @set TCL_LIBRARY= -) - -@set EXITCODE=%ERRORLEVEL% - -@echo Result was %EXITCODE% -@echo Removing %1 -"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" - -@echo off -exit /B %EXITCODE% - -:Help -echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] -echo. -echo --target (-t) Specify the target directory for installs and logs -echo -x86 Run tests for x86 installers -echo -x64 Run tests for x64 installers -echo --alluser (-a) Run tests for all-user installs (requires Administrator) -echo --peruser (-p) Run tests for per-user installs -echo -h Display this help information -echo. -echo If no test architecture is specified, all architectures will be tested. -echo If no install type is selected, all install types will be tested. -echo. +@setlocal enableextensions +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set TARGETDIR=%TEMP% +set TESTX86= +set TESTX64= +set TESTALLUSER= +set TESTPERUSER= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-x86" (set TESTX86=1) && shift && goto CheckOpts +if "%1" EQU "-x64" (set TESTX64=1) && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGETDIR=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-a" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "--alluser" (set TESTALLUSER=1) && shift && goto CheckOpts +if "%1" EQU "-p" (set TESTPERUSER=1) && shift && goto CheckOpts +if "%1" EQU "--peruser" (set TESTPERUSER=1) && shift && goto CheckOpts + +if not defined TESTX86 if not defined TESTX64 (set TESTX86=1) && (set TESTX64=1) +if not defined TESTALLUSER if not defined TESTPERUSER (set TESTALLUSER=1) && (set TESTPERUSER=1) + + +if defined TESTX86 ( + for %%f in ("%PCBUILD%win32\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +if defined TESTX64 ( + for %%f in ("%PCBUILD%amd64\en-us\*.exe") do ( + if defined TESTALLUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-alluser" "InstallAllUsers=1 CompileAll=1" + if errorlevel 1 exit /B + if defined TESTPERUSER call :test "%%~ff" "%TARGETDIR%\%%~nf-peruser" "InstallAllUsers=0 CompileAll=0" + if errorlevel 1 exit /B + ) +) + +exit /B 0 + +:test +@setlocal +@echo on + +@if not exist "%~1" exit /B 1 + +@set EXE=%~1 +@if not "%EXE:embed=%"=="%EXE%" exit /B 0 + +@set EXITCODE=0 +@echo Installing %1 into %2 +"%~1" /passive /log "%~2\install\log.txt" TargetDir="%~2\Python" Include_debug=1 Include_symbols=1 %~3 + +@if not errorlevel 1 ( + @echo Printing version + "%~2\Python\python.exe" -c "import sys; print(sys.version)" > "%~2\version.txt" 2>&1 +) + +@if not errorlevel 1 ( + @echo Capturing Start Menu + @dir /s/b "%PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" > "%~2\startmenu.txt" 2>&1 + @dir /s/b "%APPDATA%\Microsoft\Windows\Start Menu\Programs" | findstr /ic:"python" >> "%~2\startmenu.txt" 2>&1 + + @echo Capturing registry + @for /F "usebackq" %%f in (`reg query HKCR /s /f python /k`) do @( + echo %%f >> "%~2\hkcr.txt" + reg query "%%f" /s >> "%~2\hkcr.txt" 2>&1 + ) + @reg query HKCU\Software\Python /s > "%~2\hkcu.txt" 2>&1 + @reg query HKLM\Software\Python /reg:32 /s > "%~2\hklm.txt" 2>&1 + @reg query HKLM\Software\Python /reg:64 /s >> "%~2\hklm.txt" 2>&1 + cmd /k exit 0 +) + +@if not errorlevel 1 ( + @echo Installing package + "%~2\Python\python.exe" -m pip install "azure<0.10" > "%~2\pip.txt" 2>&1 + @if not errorlevel 1 ( + "%~2\Python\python.exe" -m pip uninstall -y azure python-dateutil six >> "%~2\pip.txt" 2>&1 + ) +) +@if not errorlevel 1 ( + @echo Testing Tcl/tk + @set TCL_LIBRARY=%~2\Python\tcl\tcl8.6 + "%~2\Python\python.exe" -m test -uall -v test_ttk_guionly test_tk test_idle > "%~2\tcltk.txt" 2>&1 + @set TCL_LIBRARY= +) + +@set EXITCODE=%ERRORLEVEL% + +@echo Result was %EXITCODE% +@echo Removing %1 +"%~1" /passive /uninstall /log "%~2\uninstall\log.txt" + +@echo off +exit /B %EXITCODE% + +:Help +echo testrelease.bat [--target TARGET] [-x86] [-x64] [--alluser] [--peruser] [-h] +echo. +echo --target (-t) Specify the target directory for installs and logs +echo -x86 Run tests for x86 installers +echo -x64 Run tests for x64 installers +echo --alluser (-a) Run tests for all-user installs (requires Administrator) +echo --peruser (-p) Run tests for per-user installs +echo -h Display this help information +echo. +echo If no test architecture is specified, all architectures will be tested. +echo If no install type is selected, all install types will be tested. +echo. diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat index 670836be8c1c8b..0873d55589f0db 100644 --- a/Tools/msi/uploadrelease.bat +++ b/Tools/msi/uploadrelease.bat @@ -1,76 +1,76 @@ -@setlocal -@echo off - -set D=%~dp0 -set PCBUILD=%D%..\..\PCBuild\ - -set HOST= -set USER= -set TARGET= -set DRYRUN=false -set NOGPG= -set PURGE_OPTION=/p:Purge=true -set NOTEST= - -:CheckOpts -if "%1" EQU "-h" goto Help -if "%1" EQU "-o" (set HOST=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--host" (set HOST=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-u" (set USER=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts -if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts -if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts -if "%1" EQU "--skip-purge" (set PURGE_OPTION=) && shift && godo CheckOpts -if "%1" EQU "--skip-test" (set NOTEST=true) && shift && godo CheckOpts -if "%1" EQU "-T" (set NOTEST=true) && shift && godo CheckOpts -if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 - -if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK where /R "%ProgramFiles(x86)%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" -if not defined PLINK echo Cannot locate plink.exe & exit /B 1 -echo Found plink.exe at %PLINK% - -if not defined PSCP where pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles(x86)%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" -if not defined PSCP echo Cannot locate pscp.exe & exit /B 1 -echo Found pscp.exe at %PSCP% - -if defined NOGPG ( - set GPG= - echo Skipping GPG signature generation because of --skip-gpg -) else ( - if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" - if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" - if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause - echo Found gpg2.exe at %GPG% -) - -call "%PCBUILD%env.bat" > nul 2> nul -pushd "%D%" -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% -if not defined NOTEST ( - msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 - msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 -) -msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 -msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false -popd -exit /B 0 - -:Help -echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] -echo. -echo --host (-o) Specify the upload host (required) -echo --user (-u) Specify the user on the host (required) -echo --target (-t) Specify the target directory on the host -echo --dry-run Display commands and filenames without executing them -echo --skip-gpg Does not generate GPG signatures before uploading -echo --skip-purge Does not perform CDN purge after uploading -echo --skip-test (-T) Does not perform post-upload tests -echo -h Display this help information -echo. +@setlocal +@echo off + +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set HOST= +set USER= +set TARGET= +set DRYRUN=false +set NOGPG= +set PURGE_OPTION=/p:Purge=true +set NOTEST= + +:CheckOpts +if "%1" EQU "-h" goto Help +if "%1" EQU "-o" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--host" (set HOST=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-u" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--user" (set USER=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "-t" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--target" (set TARGET=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--dry-run" (set DRYRUN=true) && shift && goto CheckOpts +if "%1" EQU "--skip-gpg" (set NOGPG=true) && shift && goto CheckOpts +if "%1" EQU "--skip-purge" (set PURGE_OPTION=) && shift && godo CheckOpts +if "%1" EQU "--skip-test" (set NOTEST=true) && shift && godo CheckOpts +if "%1" EQU "-T" (set NOTEST=true) && shift && godo CheckOpts +if "%1" NEQ "" echo Unexpected argument "%1" & exit /B 1 + +if not defined PLINK where plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%\PuTTY" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK where /R "%ProgramFiles(x86)%" plink > "%TEMP%\plink.loc" 2> nul && set /P PLINK= < "%TEMP%\plink.loc" & del "%TEMP%\plink.loc" +if not defined PLINK echo Cannot locate plink.exe & exit /B 1 +echo Found plink.exe at %PLINK% + +if not defined PSCP where pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%\PuTTY" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP where /R "%ProgramFiles(x86)%" pscp > "%TEMP%\pscp.loc" 2> nul && set /P pscp= < "%TEMP%\pscp.loc" & del "%TEMP%\pscp.loc" +if not defined PSCP echo Cannot locate pscp.exe & exit /B 1 +echo Found pscp.exe at %PSCP% + +if defined NOGPG ( + set GPG= + echo Skipping GPG signature generation because of --skip-gpg +) else ( + if not defined GPG where gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" + if not defined GPG where /R "%PCBUILD%..\externals\windows-installer" gpg2 > "%TEMP%\gpg.loc" 2> nul && set /P GPG= < "%TEMP%\gpg.loc" & del "%TEMP%\gpg.loc" + if not defined GPG echo Cannot locate gpg2.exe. Signatures will not be uploaded & pause + echo Found gpg2.exe at %GPG% +) + +call "%PCBUILD%env.bat" > nul 2> nul +pushd "%D%" +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% +msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% +if not defined NOTEST ( + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 + msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 +) +msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 +msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false +popd +exit /B 0 + +:Help +echo uploadrelease.bat --host HOST --user USERNAME [--target TARGET] [--dry-run] [-h] +echo. +echo --host (-o) Specify the upload host (required) +echo --user (-u) Specify the user on the host (required) +echo --target (-t) Specify the target directory on the host +echo --dry-run Display commands and filenames without executing them +echo --skip-gpg Does not generate GPG signatures before uploading +echo --skip-purge Does not perform CDN purge after uploading +echo --skip-test (-T) Does not perform post-upload tests +echo -h Display this help information +echo. diff --git a/Tools/nuget/build.bat b/Tools/nuget/build.bat index 120b38cb38ce61..5068c17244456e 100644 --- a/Tools/nuget/build.bat +++ b/Tools/nuget/build.bat @@ -1,55 +1,55 @@ -@echo off -setlocal -set D=%~dp0 -set PCBUILD=%D%..\..\PCBuild\ - -set BUILDX86= -set BUILDX64= -set REBUILD= -set OUTPUT= -set PACKAGES= - -:CheckOpts -if "%~1" EQU "-h" goto Help -if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts -if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts -if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts -if "%~1" EQU "-o" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts -if "%~1" EQU "--out" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts -if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckOpts - -if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) - -call "%D%..\msi\get_externals.bat" -call "%PCBUILD%env.bat" x86 - -if defined PACKAGES set PACKAGES="/p:Packages=%PACKAGES%" - -if defined BUILDX86 ( - if defined REBUILD ( call "%PCBUILD%build.bat" -e -r - ) else if not exist "%PCBUILD%win32\python.exe" call "%PCBUILD%build.bat" -e - if errorlevel 1 goto :eof - - msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% - if errorlevel 1 goto :eof -) - -if defined BUILDX64 ( - if defined REBUILD ( call "%PCBUILD%build.bat" -p x64 -e -r - ) else if not exist "%PCBUILD%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e - if errorlevel 1 goto :eof - - msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% - if errorlevel 1 goto :eof -) - -exit /B 0 - -:Help -echo build.bat [-x86] [-x64] [--out DIR] [-r] [-h] -echo. -echo -x86 Build x86 installers -echo -x64 Build x64 installers -echo -r Rebuild rather than incremental build -echo --out [DIR] Override output directory -echo -h Show usage +@echo off +setlocal +set D=%~dp0 +set PCBUILD=%D%..\..\PCBuild\ + +set BUILDX86= +set BUILDX64= +set REBUILD= +set OUTPUT= +set PACKAGES= + +:CheckOpts +if "%~1" EQU "-h" goto Help +if "%~1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts +if "%~1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts +if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts +if "%~1" EQU "-o" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts +if "%~1" EQU "--out" (set OUTPUT="/p:OutputPath=%~2") && shift && shift && goto CheckOpts +if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckOpts + +if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) + +call "%D%..\msi\get_externals.bat" +call "%PCBUILD%env.bat" x86 + +if defined PACKAGES set PACKAGES="/p:Packages=%PACKAGES%" + +if defined BUILDX86 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -e -r + ) else if not exist "%PCBUILD%win32\python.exe" call "%PCBUILD%build.bat" -e + if errorlevel 1 goto :eof + + msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% + if errorlevel 1 goto :eof +) + +if defined BUILDX64 ( + if defined REBUILD ( call "%PCBUILD%build.bat" -p x64 -e -r + ) else if not exist "%PCBUILD%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e + if errorlevel 1 goto :eof + + msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% + if errorlevel 1 goto :eof +) + +exit /B 0 + +:Help +echo build.bat [-x86] [-x64] [--out DIR] [-r] [-h] +echo. +echo -x86 Build x86 installers +echo -x64 Build x64 installers +echo -r Rebuild rather than incremental build +echo --out [DIR] Override output directory +echo -h Show usage diff --git a/Tools/unicode/genwincodecs.bat b/Tools/unicode/genwincodecs.bat index ad45c6c4438014..43cab0d6f8e71a 100644 --- a/Tools/unicode/genwincodecs.bat +++ b/Tools/unicode/genwincodecs.bat @@ -1,7 +1,7 @@ -@rem Recreate some python charmap codecs from the Windows function -@rem MultiByteToWideChar. - -@cd /d %~dp0 -@mkdir build -@rem Arabic DOS code page -c:\python30\python genwincodec.py 720 > build/cp720.py +@rem Recreate some python charmap codecs from the Windows function +@rem MultiByteToWideChar. + +@cd /d %~dp0 +@mkdir build +@rem Arabic DOS code page +c:\python30\python genwincodec.py 720 > build/cp720.py From ea8b34868c3a765ac9a5eed7321af8f4548a9654 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sat, 10 Jun 2017 14:41:38 -0700 Subject: [PATCH 268/340] bpo-28556: Updates to typing module (GH-2076) (GH-2088) This PR contains two updates to typing module: - Support ContextManager on all versions (original PR by Jelle Zijlstra). - Add generic AsyncContextManager.. (cherry picked from commit 29fda8db16e0edab92841277fa223f844f5a92cc) --- Lib/test/test_typing.py | 39 ++++++++++++++++++++++++-- Lib/typing.py | 61 +++++++++++++++++++++++++++++++++++++++-- Misc/NEWS | 4 +++ 3 files changed, 99 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index b3cabda394497e..6d0b2659db22b7 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1552,6 +1552,12 @@ def __anext__(self) -> T_a: return data else: raise StopAsyncIteration + +class ACM: + async def __aenter__(self) -> int: + return 42 + async def __aexit__(self, etype, eval, tb): + return None """ if ASYNCIO: @@ -1562,12 +1568,13 @@ def __anext__(self) -> T_a: else: # fake names for the sake of static analysis asyncio = None - AwaitableWrapper = AsyncIteratorWrapper = object + AwaitableWrapper = AsyncIteratorWrapper = ACM = object PY36 = sys.version_info[:2] >= (3, 6) PY36_TESTS = """ from test import ann_module, ann_module2, ann_module3 +from typing import AsyncContextManager class A: y: float @@ -1604,6 +1611,16 @@ def __str__(self): return f'{self.x} -> {self.y}' def __add__(self, other): return 0 + +async def g_with(am: AsyncContextManager[int]): + x: int + async with am as x: + return x + +try: + g_with(ACM()).send(None) +except StopIteration as e: + assert e.args[0] == 42 """ if PY36: @@ -2156,8 +2173,6 @@ class B: ... class OtherABCTests(BaseTestCase): - @skipUnless(hasattr(typing, 'ContextManager'), - 'requires typing.ContextManager') def test_contextmanager(self): @contextlib.contextmanager def manager(): @@ -2167,6 +2182,24 @@ def manager(): self.assertIsInstance(cm, typing.ContextManager) self.assertNotIsInstance(42, typing.ContextManager) + @skipUnless(ASYNCIO, 'Python 3.5 required') + def test_async_contextmanager(self): + class NotACM: + pass + self.assertIsInstance(ACM(), typing.AsyncContextManager) + self.assertNotIsInstance(NotACM(), typing.AsyncContextManager) + @contextlib.contextmanager + def manager(): + yield 42 + + cm = manager() + self.assertNotIsInstance(cm, typing.AsyncContextManager) + self.assertEqual(typing.AsyncContextManager[int].__args__, (int,)) + with self.assertRaises(TypeError): + isinstance(42, typing.AsyncContextManager[int]) + with self.assertRaises(TypeError): + typing.AsyncContextManager[int, str] + class TypeTests(BaseTestCase): diff --git a/Lib/typing.py b/Lib/typing.py index 645bc6f8ae0edd..c487afcb5b42f8 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -10,6 +10,8 @@ import collections.abc as collections_abc except ImportError: import collections as collections_abc # Fallback for PY3.2. +if sys.version_info[:2] >= (3, 6): + import _collections_abc # Needed for private function _check_methods # noqa try: from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType except ImportError: @@ -37,6 +39,7 @@ # for 'Generic' and ABCs below. 'ByteString', 'Container', + 'ContextManager', 'Hashable', 'ItemsView', 'Iterable', @@ -57,8 +60,8 @@ # AsyncIterable, # Coroutine, # Collection, - # ContextManager, # AsyncGenerator, + # AsyncContextManager # Structural checks, a.k.a. protocols. 'Reversible', @@ -1949,7 +1952,61 @@ class ValuesView(MappingView[VT_co], extra=collections_abc.ValuesView): if hasattr(contextlib, 'AbstractContextManager'): class ContextManager(Generic[T_co], extra=contextlib.AbstractContextManager): __slots__ = () - __all__.append('ContextManager') +else: + class ContextManager(Generic[T_co]): + __slots__ = () + + def __enter__(self): + return self + + @abc.abstractmethod + def __exit__(self, exc_type, exc_value, traceback): + return None + + @classmethod + def __subclasshook__(cls, C): + if cls is ContextManager: + # In Python 3.6+, it is possible to set a method to None to + # explicitly indicate that the class does not implement an ABC + # (https://bugs.python.org/issue25958), but we do not support + # that pattern here because this fallback class is only used + # in Python 3.5 and earlier. + if (any("__enter__" in B.__dict__ for B in C.__mro__) and + any("__exit__" in B.__dict__ for B in C.__mro__)): + return True + return NotImplemented + + +if hasattr(contextlib, 'AbstractAsyncContextManager'): + class AsyncContextManager(Generic[T_co], + extra=contextlib.AbstractAsyncContextManager): + __slots__ = () + + __all__.append('AsyncContextManager') +elif sys.version_info[:2] >= (3, 5): + exec(""" +class AsyncContextManager(Generic[T_co]): + __slots__ = () + + async def __aenter__(self): + return self + + @abc.abstractmethod + async def __aexit__(self, exc_type, exc_value, traceback): + return None + + @classmethod + def __subclasshook__(cls, C): + if cls is AsyncContextManager: + if sys.version_info[:2] >= (3, 6): + return _collections_abc._check_methods(C, "__aenter__", "__aexit__") + if (any("__aenter__" in B.__dict__ for B in C.__mro__) and + any("__aexit__" in B.__dict__ for B in C.__mro__)): + return True + return NotImplemented + +__all__.append('AsyncContextManager') +""") class Dict(dict, MutableMapping[KT, VT], extra=dict): diff --git a/Misc/NEWS b/Misc/NEWS index 3abdc12ec5b6fa..33b7b9ae9df8cf 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,10 @@ Extension Modules Library ------- +- bpo-28556: Updates to typing module: Add generic AsyncContextManager, add + support for ContextManager on all versions. Original PRs by Jelle Zijlstra + and Ivan Levkivskyi + - bpo-29870: Fix ssl sockets leaks when connection is aborted in asyncio/ssl implementation. Patch by Michaël Sghaïer. From d24c8287e226ac9983caf6bb826a7b53142ee31f Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sun, 11 Jun 2017 14:11:47 +0000 Subject: [PATCH 269/340] bpo-30508: Don't log exceptions if Task/Future "cancel()" method was called. (#2110) --- Lib/asyncio/futures.py | 1 + Lib/asyncio/tasks.py | 1 + Lib/test/test_asyncio/test_futures.py | 8 ++++++++ Lib/test/test_asyncio/test_tasks.py | 19 +++++++++++++++++++ Misc/NEWS | 3 +++ 5 files changed, 32 insertions(+) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py index 9ca8d8458bcf62..60b0d3133494c4 100644 --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -240,6 +240,7 @@ def cancel(self): change the future's state to cancelled, schedule the callbacks and return True. """ + self._log_traceback = False if self._state != _PENDING: return False self._state = _CANCELLED diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index 89d0989c614a56..6c43e6830a10f4 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -208,6 +208,7 @@ def cancel(self): terminates with a CancelledError exception (even if cancel() was not called). """ + self._log_traceback = False if self.done(): return False if self._fut_waiter is not None: diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py index c306b77e653264..195a006fe67e0b 100644 --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -314,6 +314,14 @@ def test_tb_logger_abandoned(self, m_log): del fut self.assertFalse(m_log.error.called) + @mock.patch('asyncio.base_events.logger') + def test_tb_logger_not_called_after_cancel(self, m_log): + fut = asyncio.Future(loop=self.loop) + fut.set_exception(Exception()) + fut.cancel() + del fut + self.assertFalse(m_log.error.called) + @mock.patch('asyncio.base_events.logger') def test_tb_logger_result_unretrieved(self, m_log): fut = asyncio.Future(loop=self.loop) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index b3d0653e82e573..c419015a088b63 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -1828,6 +1828,25 @@ def kill_me(loop): }) mock_handler.reset_mock() + @mock.patch('asyncio.base_events.logger') + def test_tb_logger_not_called_after_cancel(self, m_log): + loop = asyncio.new_event_loop() + self.set_event_loop(loop) + + @asyncio.coroutine + def coro(): + raise TypeError + + @asyncio.coroutine + def runner(): + task = loop.create_task(coro()) + yield from asyncio.sleep(0.05, loop=loop) + task.cancel() + task = None + + loop.run_until_complete(runner()) + self.assertFalse(m_log.error.called) + @mock.patch('asyncio.coroutines.logger') def test_coroutine_never_yielded(self, m_log): with set_coroutine_debug(True): diff --git a/Misc/NEWS b/Misc/NEWS index 33b7b9ae9df8cf..e8f94451f8c5e8 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-30508: Don't log exceptions if Task/Future "cancel()" method was + called. + - bpo-28556: Updates to typing module: Add generic AsyncContextManager, add support for ContextManager on all versions. Original PRs by Jelle Zijlstra and Ivan Levkivskyi From 4e9dfe214dff000c5b5ad0d8bd8a393feed1d3cf Mon Sep 17 00:00:00 2001 From: Yury Selivanov Date: Sun, 11 Jun 2017 16:46:53 +0200 Subject: [PATCH 270/340] Revert "[3.5] bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers (GH-409) (#2063)" (#2113) This reverts commit 1395c58ef7b98f087d1d5d50962fe7a8c032f34d. --- Lib/asyncio/sslproto.py | 24 +----------------- Lib/test/test_asyncio/test_sslproto.py | 34 -------------------------- Misc/NEWS | 4 --- 3 files changed, 1 insertion(+), 61 deletions(-) diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py index 4606f0bf2d86db..61d478ebda6c78 100644 --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -7,7 +7,6 @@ from . import base_events from . import compat -from . import futures from . import protocols from . import transports from .log import logger @@ -412,7 +411,7 @@ class SSLProtocol(protocols.Protocol): def __init__(self, loop, app_protocol, sslcontext, waiter, server_side=False, server_hostname=None, - call_connection_made=True, shutdown_timeout=5.0): + call_connection_made=True): if ssl is None: raise RuntimeError('stdlib ssl module not available') @@ -443,8 +442,6 @@ def __init__(self, loop, app_protocol, sslcontext, waiter, self._session_established = False self._in_handshake = False self._in_shutdown = False - self._shutdown_timeout = shutdown_timeout - self._shutdown_timeout_handle = None # transport, ex: SelectorSocketTransport self._transport = None self._call_connection_made = call_connection_made @@ -559,15 +556,6 @@ def _start_shutdown(self): self._in_shutdown = True self._write_appdata(b'') - if self._shutdown_timeout is not None: - self._shutdown_timeout_handle = self._loop.call_later( - self._shutdown_timeout, self._on_shutdown_timeout) - - def _on_shutdown_timeout(self): - if self._transport is not None: - self._fatal_error( - futures.TimeoutError(), 'Can not complete shitdown operation') - def _write_appdata(self, data): self._write_backlog.append((data, 0)) self._write_buffer_size += len(data) @@ -695,22 +683,12 @@ def _fatal_error(self, exc, message='Fatal error on transport'): }) if self._transport: self._transport._force_close(exc) - self._transport = None - - if self._shutdown_timeout_handle is not None: - self._shutdown_timeout_handle.cancel() - self._shutdown_timeout_handle = None def _finalize(self): self._sslpipe = None if self._transport is not None: self._transport.close() - self._transport = None - - if self._shutdown_timeout_handle is not None: - self._shutdown_timeout_handle.cancel() - self._shutdown_timeout_handle = None def _abort(self): try: diff --git a/Lib/test/test_asyncio/test_sslproto.py b/Lib/test/test_asyncio/test_sslproto.py index 6bcaa9edb4306d..bcd236ea2632ed 100644 --- a/Lib/test/test_asyncio/test_sslproto.py +++ b/Lib/test/test_asyncio/test_sslproto.py @@ -96,40 +96,6 @@ def test_connection_lost(self): test_utils.run_briefly(self.loop) self.assertIsInstance(waiter.exception(), ConnectionAbortedError) - def test_close_abort(self): - # From issue #bpo-29406 - # abort connection if server does not complete shutdown procedure - ssl_proto = self.ssl_protocol() - transport = self.connection_made(ssl_proto) - ssl_proto._on_handshake_complete(None) - ssl_proto._start_shutdown() - self.assertIsNotNone(ssl_proto._shutdown_timeout_handle) - - exc_handler = mock.Mock() - self.loop.set_exception_handler(exc_handler) - ssl_proto._shutdown_timeout_handle._run() - - exc_handler.assert_called_with( - self.loop, {'message': 'Can not complete shitdown operation', - 'exception': mock.ANY, - 'transport': transport, - 'protocol': ssl_proto} - ) - self.assertIsNone(ssl_proto._shutdown_timeout_handle) - - def test_close(self): - # From issue #bpo-29406 - # abort connection if server does not complete shutdown procedure - ssl_proto = self.ssl_protocol() - transport = self.connection_made(ssl_proto) - ssl_proto._on_handshake_complete(None) - ssl_proto._start_shutdown() - self.assertIsNotNone(ssl_proto._shutdown_timeout_handle) - - ssl_proto._finalize() - self.assertIsNone(ssl_proto._transport) - self.assertIsNone(ssl_proto._shutdown_timeout_handle) - def test_close_during_handshake(self): # bpo-29743 Closing transport during handshake process leaks socket waiter = asyncio.Future(loop=self.loop) diff --git a/Misc/NEWS b/Misc/NEWS index e8f94451f8c5e8..255f1467a8e359 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -69,10 +69,6 @@ Library - bpo-29743: Closing transport during handshake process leaks open socket. Patch by Nikolay Kim -- bpo-29406: asyncio SSL contexts leak sockets after calling close with - certain servers. - Patch by Nikolay Kim - - bpo-27585: Fix waiter cancellation in asyncio.Lock. Patch by Mathieu Sornay. From 80bdbf6f494f4ba673606d516a4ec7ed9ed66315 Mon Sep 17 00:00:00 2001 From: Zachary Ware Date: Sun, 11 Jun 2017 11:32:45 -0500 Subject: [PATCH 271/340] [3.5] Use Travis to make sure all generated files are up to date (GH-2080) (GH-2093) (cherry picked from commit 0afbabe245) Also fixes some line endings missed in GH-840 backport. --- .travis.yml | 9 + Doc/make.bat | 260 ++++++++++++------------- Lib/ctypes/macholib/fetch_macholib.bat | 2 +- Lib/idlelib/idle.bat | 8 +- 4 files changed, 144 insertions(+), 135 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3de0b666e7d8b2..65d555df749d4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -70,6 +70,7 @@ matrix: # Travis provides only 2 cores, so don't overdo the parallelism and waste memory. before_script: - | + set -e if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(\.rst$)|(^Doc)|(^Misc)' then echo "Only docs were updated, stopping build process." @@ -77,6 +78,14 @@ before_script: fi ./configure --with-pydebug make -j4 + make -j4 regen-all clinic + changes=`git status --porcelain` + if ! test -z "$changes" + then + echo "Generated files not up to date" + echo "$changes" + exit 1 + fi script: # `-r -w` implicitly provided through `make buildbottest`. diff --git a/Doc/make.bat b/Doc/make.bat index 740f148affa6cf..c7bc416996dd71 100644 --- a/Doc/make.bat +++ b/Doc/make.bat @@ -1,130 +1,130 @@ -@echo off -setlocal - -pushd %~dp0 - -set this=%~n0 - -if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build -if "%PYTHON%" EQU "" set PYTHON=py - -if "%1" NEQ "htmlhelp" goto :skiphhcsearch -if exist "%HTMLHELP%" goto :skiphhcsearch - -rem Search for HHC in likely places -set HTMLHELP= -where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch -where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" -if not exist "%HTMLHELP%" ( - echo. - echo.The HTML Help Workshop was not found. Set the HTMLHELP variable - echo.to the path to hhc.exe or download and install it from - echo.http://msdn.microsoft.com/en-us/library/ms669985 - exit /B 1 -) -:skiphhcsearch - -if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v - -if "%BUILDDIR%" EQU "" set BUILDDIR=build - -rem Targets that don't require sphinx-build -if "%1" EQU "" goto help -if "%1" EQU "help" goto help -if "%1" EQU "check" goto check -if "%1" EQU "serve" goto serve -if "%1" == "clean" ( - rmdir /q /s %BUILDDIR% - goto end -) - -%SPHINXBUILD% 2> nul -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - popd - exit /B 1 -) - -rem Targets that do require sphinx-build and have their own label -if "%1" EQU "htmlview" goto htmlview - -rem Everything else -goto build - -:help -echo.usage: %this% BUILDER [filename ...] -echo. -echo.Call %this% with the desired Sphinx builder as the first argument, e.g. -echo.``%this% html`` or ``%this% doctest``. Interesting targets that are -echo.always available include: -echo. -echo. Provided by Sphinx: -echo. html, htmlhelp, latex, text -echo. suspicious, linkcheck, changes, doctest -echo. Provided by this script: -echo. clean, check, serve, htmlview -echo. -echo.All arguments past the first one are passed through to sphinx-build as -echo.filenames to build or are ignored. See README.txt in this directory or -echo.the documentation for your version of Sphinx for more exhaustive lists -echo.of available targets and descriptions of each. -echo. -echo.This script assumes that the SPHINXBUILD environment variable contains -echo.a legitimate command for calling sphinx-build, or that sphinx-build is -echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can -echo.be passed by setting the SPHINXOPTS environment variable. -goto end - -:build -if NOT "%PAPER%" == "" ( - set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% -) -cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* - -if "%1" EQU "htmlhelp" ( - cmd /C "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp - rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 - if not errorlevel 2 cmd /C exit /b 0 -) - -echo. -if errorlevel 1 ( - echo.Build failed (exit code %ERRORLEVEL%^), check for error messages - echo.above. Any output will be found in %BUILDDIR%\%1 -) else ( - echo.Build succeeded. All output should be in %BUILDDIR%\%1 -) -goto end - -:htmlview -if NOT "%2" EQU "" ( - echo.Can't specify filenames to build with htmlview target, ignoring. -) -cmd /C %this% html - -if EXIST %BUILDDIR%\html\index.html ( - echo.Opening %BUILDDIR%\html\index.html in the default web browser... - start %BUILDDIR%\html\index.html -) - -goto end - -:check -cmd /C %PYTHON% tools\rstlint.py -i tools -goto end - -:serve -cmd /C %PYTHON% ..\Tools\scripts\serve.py %BUILDDIR%\html -goto end - -:end -popd +@echo off +setlocal + +pushd %~dp0 + +set this=%~n0 + +if "%SPHINXBUILD%" EQU "" set SPHINXBUILD=sphinx-build +if "%PYTHON%" EQU "" set PYTHON=py + +if "%1" NEQ "htmlhelp" goto :skiphhcsearch +if exist "%HTMLHELP%" goto :skiphhcsearch + +rem Search for HHC in likely places +set HTMLHELP= +where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch +where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc" +if not exist "%HTMLHELP%" ( + echo. + echo.The HTML Help Workshop was not found. Set the HTMLHELP variable + echo.to the path to hhc.exe or download and install it from + echo.http://msdn.microsoft.com/en-us/library/ms669985 + exit /B 1 +) +:skiphhcsearch + +if "%DISTVERSION%" EQU "" for /f "usebackq" %%v in (`%PYTHON% tools/extensions/patchlevel.py`) do set DISTVERSION=%%v + +if "%BUILDDIR%" EQU "" set BUILDDIR=build + +rem Targets that don't require sphinx-build +if "%1" EQU "" goto help +if "%1" EQU "help" goto help +if "%1" EQU "check" goto check +if "%1" EQU "serve" goto serve +if "%1" == "clean" ( + rmdir /q /s %BUILDDIR% + goto end +) + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + popd + exit /B 1 +) + +rem Targets that do require sphinx-build and have their own label +if "%1" EQU "htmlview" goto htmlview + +rem Everything else +goto build + +:help +echo.usage: %this% BUILDER [filename ...] +echo. +echo.Call %this% with the desired Sphinx builder as the first argument, e.g. +echo.``%this% html`` or ``%this% doctest``. Interesting targets that are +echo.always available include: +echo. +echo. Provided by Sphinx: +echo. html, htmlhelp, latex, text +echo. suspicious, linkcheck, changes, doctest +echo. Provided by this script: +echo. clean, check, serve, htmlview +echo. +echo.All arguments past the first one are passed through to sphinx-build as +echo.filenames to build or are ignored. See README.txt in this directory or +echo.the documentation for your version of Sphinx for more exhaustive lists +echo.of available targets and descriptions of each. +echo. +echo.This script assumes that the SPHINXBUILD environment variable contains +echo.a legitimate command for calling sphinx-build, or that sphinx-build is +echo.on your PATH if SPHINXBUILD is not set. Options for sphinx-build can +echo.be passed by setting the SPHINXOPTS environment variable. +goto end + +:build +if NOT "%PAPER%" == "" ( + set SPHINXOPTS=-D latex_elements.papersize=%PAPER% %SPHINXOPTS% +) +cmd /C %SPHINXBUILD% %SPHINXOPTS% -b%1 -dbuild\doctrees . %BUILDDIR%\%* + +if "%1" EQU "htmlhelp" ( + cmd /C "%HTMLHELP%" build\htmlhelp\python%DISTVERSION:.=%.hhp + rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2 + if not errorlevel 2 cmd /C exit /b 0 +) + +echo. +if errorlevel 1 ( + echo.Build failed (exit code %ERRORLEVEL%^), check for error messages + echo.above. Any output will be found in %BUILDDIR%\%1 +) else ( + echo.Build succeeded. All output should be in %BUILDDIR%\%1 +) +goto end + +:htmlview +if NOT "%2" EQU "" ( + echo.Can't specify filenames to build with htmlview target, ignoring. +) +cmd /C %this% html + +if EXIST %BUILDDIR%\html\index.html ( + echo.Opening %BUILDDIR%\html\index.html in the default web browser... + start %BUILDDIR%\html\index.html +) + +goto end + +:check +cmd /C %PYTHON% tools\rstlint.py -i tools +goto end + +:serve +cmd /C %PYTHON% ..\Tools\scripts\serve.py %BUILDDIR%\html +goto end + +:end +popd diff --git a/Lib/ctypes/macholib/fetch_macholib.bat b/Lib/ctypes/macholib/fetch_macholib.bat index f474d5cd0a26f7..f9e1c0dc96c318 100644 --- a/Lib/ctypes/macholib/fetch_macholib.bat +++ b/Lib/ctypes/macholib/fetch_macholib.bat @@ -1 +1 @@ -svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . +svn export --force http://svn.red-bean.com/bob/macholib/trunk/macholib/ . diff --git a/Lib/idlelib/idle.bat b/Lib/idlelib/idle.bat index 3d619a37eed366..e77b96e9b5149b 100755 --- a/Lib/idlelib/idle.bat +++ b/Lib/idlelib/idle.bat @@ -1,4 +1,4 @@ -@echo off -rem Start IDLE using the appropriate Python interpreter -set CURRDIR=%~dp0 -start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 +@echo off +rem Start IDLE using the appropriate Python interpreter +set CURRDIR=%~dp0 +start "IDLE" "%CURRDIR%..\..\pythonw.exe" "%CURRDIR%idle.pyw" %1 %2 %3 %4 %5 %6 %7 %8 %9 From 7563b0508172cedb5e6a95d05e9122f1a0bfcd86 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Sun, 11 Jun 2017 18:59:17 -0700 Subject: [PATCH 272/340] bpo-30621: Update Input Output Tutorial Example(GH-2074) (GH-2119) import json before using json module (cherry picked from commit 1dbce04d0e3e93b715eb0d8024da396361759d16) --- Doc/tutorial/inputoutput.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 5add11a8a49b8b..999034a9700b17 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -411,6 +411,7 @@ sent over a network connection to some distant machine. If you have an object ``x``, you can view its JSON string representation with a simple line of code:: + >>> import json >>> json.dumps([1, 'simple', 'list']) '[1, "simple", "list"]' From 7d8c1ebd86ce27b28736c5e97fef58ec60b8ef31 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 12 Jun 2017 09:02:33 +0300 Subject: [PATCH 273/340] [3.5] bpo-28994: Fixed errors handling in atexit._run_exitfuncs(). (GH-2034) (#2122) The traceback no longer displayed for SystemExit raised in a callback registered by atexit. (cherry picked from commit 3fd54d4a7e604067e2bc0f8cfd58bdbdc09fa7f4) --- Lib/test/test_atexit.py | 10 ++++++++++ Misc/NEWS | 3 +++ Modules/atexitmodule.c | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Lib/test/test_atexit.py b/Lib/test/test_atexit.py index c761076c4a0225..1d0b018aafaf93 100644 --- a/Lib/test/test_atexit.py +++ b/Lib/test/test_atexit.py @@ -23,6 +23,9 @@ def raise1(): def raise2(): raise SystemError +def exit(): + raise SystemExit + class GeneralTest(unittest.TestCase): @@ -76,6 +79,13 @@ def test_raise_unnormalized(self): self.assertRaises(ZeroDivisionError, atexit._run_exitfuncs) self.assertIn("ZeroDivisionError", self.stream.getvalue()) + def test_exit(self): + # be sure a SystemExit is handled properly + atexit.register(exit) + + self.assertRaises(SystemExit, atexit._run_exitfuncs) + self.assertEqual(self.stream.getvalue(), '') + def test_print_tracebacks(self): # Issue #18776: the tracebacks should be printed when errors occur. def f(): diff --git a/Misc/NEWS b/Misc/NEWS index 255f1467a8e359..c4c21e5662be9a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-28994: The traceback no longer displayed for SystemExit raised in + a callback registered by atexit. + - bpo-30508: Don't log exceptions if Task/Future "cancel()" method was called. diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c index 3cdf2d7e56348a..35ebf08ecd3c66 100644 --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -97,7 +97,7 @@ atexit_callfuncs(void) Py_XDECREF(exc_tb); } PyErr_Fetch(&exc_type, &exc_value, &exc_tb); - if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { + if (!PyErr_GivenExceptionMatches(exc_type, PyExc_SystemExit)) { PySys_WriteStderr("Error in atexit._run_exitfuncs:\n"); PyErr_NormalizeException(&exc_type, &exc_value, &exc_tb); PyErr_Display(exc_type, exc_value, exc_tb); From 37e04153d5e331162608b33639ecd3c9a5ae2432 Mon Sep 17 00:00:00 2001 From: Marco Buttu Date: Mon, 12 Jun 2017 21:43:52 +0200 Subject: [PATCH 274/340] bpo-30217: add the operators ~ and | to the index (GH-1502) (GH-2138) (cherry picked from commit dc980dfbcfce4695ccde056c3983160ba97b5a36) --- Doc/library/stdtypes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst index c4588f2438b8ea..3e279e6e5e8525 100644 --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -394,10 +394,12 @@ Bitwise Operations on Integer Types pair: bitwise; operations pair: shifting; operations pair: masking; operations + operator: | operator: ^ operator: & operator: << operator: >> + operator: ~ Bitwise operations only make sense for integers. Negative numbers are treated as their 2's complement value (this assumes that there are enough bits so that From 5a86154a931083e6a9f9bdf9cc8b3bc33abb673d Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 12 Jun 2017 22:40:43 -0700 Subject: [PATCH 275/340] bpo-6519: Improve Python Input Output Tutorial (GH-2143) (GH-2146) Move up the discussion about 'with' keyword, so it appears earlier in the document. (cherry picked from commit bd4e9e0ca96dabf33605d9b1fd1e0562ece8ae18) --- Doc/tutorial/inputoutput.rst | 50 +++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/Doc/tutorial/inputoutput.rst b/Doc/tutorial/inputoutput.rst index 999034a9700b17..32cb5782e87ed1 100644 --- a/Doc/tutorial/inputoutput.rst +++ b/Doc/tutorial/inputoutput.rst @@ -261,6 +261,35 @@ to file data is fine for text files, but will corrupt binary data like that in :file:`JPEG` or :file:`EXE` files. Be very careful to use binary mode when reading and writing such files. +It is good practice to use the :keyword:`with` keyword when dealing +with file objects. The advantage is that the file is properly closed +after its suite finishes, even if an exception is raised at some +point. Using :keyword:`with` is also much shorter than writing +equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: + + >>> with open('workfile') as f: + ... read_data = f.read() + >>> f.closed + True + +If you're not using the :keyword:`with` keyword, then you should call +``f.close()`` to close the file and immediately free up any system +resources used by it. If you don't explicitly close a file, Python's +garbage collector will eventually destroy the object and close the +open file for you, but the file may stay open for a while. Another +risk is that different Python implementations will do this clean-up at +different times. + +After a file object is closed, either by a :keyword:`with` statement +or by calling ``f.close()``, attempts to use the file object will +automatically fail. :: + + >>> f.close() + >>> f.read() + Traceback (most recent call last): + File "", line 1, in + ValueError: I/O operation on closed file + .. _tut-filemethods: @@ -353,27 +382,6 @@ to the very file end with ``seek(0, 2)``) and the only valid *offset* values are those returned from the ``f.tell()``, or zero. Any other *offset* value produces undefined behaviour. - -When you're done with a file, call ``f.close()`` to close it and free up any -system resources taken up by the open file. After calling ``f.close()``, -attempts to use the file object will automatically fail. :: - - >>> f.close() - >>> f.read() - Traceback (most recent call last): - File "", line 1, in - ValueError: I/O operation on closed file - -It is good practice to use the :keyword:`with` keyword when dealing with file -objects. This has the advantage that the file is properly closed after its -suite finishes, even if an exception is raised on the way. It is also much -shorter than writing equivalent :keyword:`try`\ -\ :keyword:`finally` blocks:: - - >>> with open('workfile', 'r') as f: - ... read_data = f.read() - >>> f.closed - True - File objects have some additional methods, such as :meth:`~file.isatty` and :meth:`~file.truncate` which are less frequently used; consult the Library Reference for a complete guide to file objects. From e0e0029623248e6ed786df91c3cdf9ff4f283d32 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 13 Jun 2017 10:21:54 +0200 Subject: [PATCH 276/340] [3.5] Mention how to disable signal fd wakeup (GH-2140) (#2150) (cherry picked from commit d79c1d4a9406384f10a37f26a7515ce79f9fdd78) --- Doc/library/signal.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/library/signal.rst b/Doc/library/signal.rst index 039b666475a247..46d71def08abd6 100644 --- a/Doc/library/signal.rst +++ b/Doc/library/signal.rst @@ -306,8 +306,10 @@ The :mod:`signal` module defines the following functions: a library to wakeup a poll or select call, allowing the signal to be fully processed. - The old wakeup fd is returned. *fd* must be non-blocking. It is up to the - library to remove any bytes before calling poll or select again. + The old wakeup fd is returned (or -1 if file descriptor wakeup was not + enabled). If *fd* is -1, file descriptor wakeup is disabled. + If not -1, *fd* must be non-blocking. It is up to the library to remove + any bytes from *fd* before calling poll or select again. Use for example ``struct.unpack('%uB' % len(data), data)`` to decode the signal numbers list. From d071a20f136547a490783fcfa969c6528025a6d2 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Tue, 13 Jun 2017 20:32:24 +1000 Subject: [PATCH 277/340] [3.5] bpo-29514: Check magic number for bugfix releases (#2158) Add a test to check the current MAGIC_NUMBER against the expected number for the release if the current release is at candidate or final level. On test failure, describe to the developer the procedure for changing the magic number. This ensures that pre-merge CI will automatically pick up on magic number changes in maintenance releases (and explain why those are problematic), rather than relying on all core developers to be aware of the implications of such changes. --- Lib/test/test_importlib/test_util.py | 44 ++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Lib/test/test_importlib/test_util.py b/Lib/test/test_importlib/test_util.py index 41ca3332d54d22..230cd291afd537 100644 --- a/Lib/test/test_importlib/test_util.py +++ b/Lib/test/test_importlib/test_util.py @@ -4,6 +4,7 @@ machinery = util.import_importlib('importlib.machinery') importlib_util = util.import_importlib('importlib.util') +import importlib.util import os import string import sys @@ -744,5 +745,48 @@ def test_source_from_cache_missing_optimization(self): ) = util.test_both(PEP3147Tests, util=importlib_util) +class MagicNumberTests(unittest.TestCase): + """ + Test release compatibility issues relating to importlib + """ + @unittest.skipUnless( + sys.version_info.releaselevel in ('final', 'release'), + 'only applies to candidate or final python release levels' + ) + def test_magic_number(self): + """ + Each python minor release should generally have a MAGIC_NUMBER + that does not change once the release reaches candidate status. + + Once a release reaches candidate status, the value of the constant + EXPECTED_MAGIC_NUMBER in this test should be changed. + This test will then check that the actual MAGIC_NUMBER matches + the expected value for the release. + + In exceptional cases, it may be required to change the MAGIC_NUMBER + for a maintenance release. In this case the change should be + discussed in python-dev. If a change is required, community + stakeholders such as OS package maintainers must be notified + in advance. Such exceptional releases will then require an + adjustment to this test case. + """ + EXPECTED_MAGIC_NUMBER = 3351 + actual = int.from_bytes(importlib.util.MAGIC_NUMBER[:2], 'little') + + msg = ( + "To avoid breaking backwards compatibility with cached bytecode " + "files that can't be automatically regenerated by the current " + "user, candidate and final releases require the current " + "importlib.util.MAGIC_NUMBER to match the expected " + "magic number in this test. Set the expected " + "magic number in this test to the current MAGIC_NUMBER to " + "continue with the release.\n\n" + "Changing the MAGIC_NUMBER for a maintenance release " + "requires discussion in python-dev and notification of " + "community stakeholders." + ) + self.assertEqual(EXPECTED_MAGIC_NUMBER, actual, msg) + + if __name__ == '__main__': unittest.main() From a0ecaab006849ade08fbcf8413fe1e92d9c8d71c Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Tue, 13 Jun 2017 17:54:10 +0200 Subject: [PATCH 278/340] [3.5] bpo-24484: Avoid race condition in multiprocessing cleanup (GH-2159) (#2167) * bpo-24484: Avoid race condition in multiprocessing cleanup The finalizer registry can be mutated while inspected by multiprocessing at process exit. * Use test.support.start_threads() * Add Misc/NEWS. (cherry picked from commit 1eb6c0074d17f4fd425cacfdda893d65f5f77f0a) --- Lib/multiprocessing/util.py | 34 ++++++++++------- Lib/test/_test_multiprocessing.py | 63 +++++++++++++++++++++++++++++++ Misc/NEWS | 2 + 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/Lib/multiprocessing/util.py b/Lib/multiprocessing/util.py index 0ce274ceca6057..b490caa7e64333 100644 --- a/Lib/multiprocessing/util.py +++ b/Lib/multiprocessing/util.py @@ -241,20 +241,28 @@ def _run_finalizers(minpriority=None): return if minpriority is None: - f = lambda p : p[0][0] is not None + f = lambda p : p[0] is not None else: - f = lambda p : p[0][0] is not None and p[0][0] >= minpriority - - items = [x for x in list(_finalizer_registry.items()) if f(x)] - items.sort(reverse=True) - - for key, finalizer in items: - sub_debug('calling %s', finalizer) - try: - finalizer() - except Exception: - import traceback - traceback.print_exc() + f = lambda p : p[0] is not None and p[0] >= minpriority + + # Careful: _finalizer_registry may be mutated while this function + # is running (either by a GC run or by another thread). + + # list(_finalizer_registry) should be atomic, while + # list(_finalizer_registry.items()) is not. + keys = [key for key in list(_finalizer_registry) if f(key)] + keys.sort(reverse=True) + + for key in keys: + finalizer = _finalizer_registry.get(key) + # key may have been removed from the registry + if finalizer is not None: + sub_debug('calling %s', finalizer) + try: + finalizer() + except Exception: + import traceback + traceback.print_exc() if minpriority is None: _finalizer_registry.clear() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index b24e7d6c32df1d..01459dc81d86df 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -2985,6 +2985,14 @@ class _TestFinalize(BaseTestCase): ALLOWED_TYPES = ('processes',) + def setUp(self): + self.registry_backup = util._finalizer_registry.copy() + util._finalizer_registry.clear() + + def tearDown(self): + self.assertFalse(util._finalizer_registry) + util._finalizer_registry.update(self.registry_backup) + @classmethod def _test_finalize(cls, conn): class Foo(object): @@ -3034,6 +3042,61 @@ def test_finalize(self): result = [obj for obj in iter(conn.recv, 'STOP')] self.assertEqual(result, ['a', 'b', 'd10', 'd03', 'd02', 'd01', 'e']) + def test_thread_safety(self): + # bpo-24484: _run_finalizers() should be thread-safe + def cb(): + pass + + class Foo(object): + def __init__(self): + self.ref = self # create reference cycle + # insert finalizer at random key + util.Finalize(self, cb, exitpriority=random.randint(1, 100)) + + finish = False + exc = None + + def run_finalizers(): + nonlocal exc + while not finish: + time.sleep(random.random() * 1e-1) + try: + # A GC run will eventually happen during this, + # collecting stale Foo's and mutating the registry + util._run_finalizers() + except Exception as e: + exc = e + + def make_finalizers(): + nonlocal exc + d = {} + while not finish: + try: + # Old Foo's get gradually replaced and later + # collected by the GC (because of the cyclic ref) + d[random.getrandbits(5)] = {Foo() for i in range(10)} + except Exception as e: + exc = e + d.clear() + + old_interval = sys.getswitchinterval() + old_threshold = gc.get_threshold() + try: + sys.setswitchinterval(1e-6) + gc.set_threshold(5, 5, 5) + threads = [threading.Thread(target=run_finalizers), + threading.Thread(target=make_finalizers)] + with test.support.start_threads(threads): + time.sleep(4.0) # Wait a bit to trigger race condition + finish = True + if exc is not None: + raise exc + finally: + sys.setswitchinterval(old_interval) + gc.set_threshold(*old_threshold) + gc.collect() # Collect remaining Foo's + + # # Test that from ... import * works for each module # diff --git a/Misc/NEWS b/Misc/NEWS index c4c21e5662be9a..0ccbb9d0381af3 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,8 @@ Extension Modules Library ------- +- bpo-24484: Avoid race condition in multiprocessing cleanup. + - bpo-28994: The traceback no longer displayed for SystemExit raised in a callback registered by atexit. From ee0572fc96cbc4a61ae0de5b2408334a132faa12 Mon Sep 17 00:00:00 2001 From: csabella Date: Wed, 14 Jun 2017 12:26:22 -0400 Subject: [PATCH 279/340] Fix trivial typo in Python Setup documentation (GH-2185) (GH-2189) Replace platform with platforms. (cherry picked from commit 4ebf03d109f827c91a23256a447c1d74a203dfee) --- Doc/using/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/using/index.rst b/Doc/using/index.rst index 502afa90336564..a643e04031763e 100644 --- a/Doc/using/index.rst +++ b/Doc/using/index.rst @@ -6,7 +6,7 @@ This part of the documentation is devoted to general information on the setup -of the Python environment on different platform, the invocation of the +of the Python environment on different platforms, the invocation of the interpreter and things that make working with Python easier. From a3afdca2190201bf6572435226dd3f8668139002 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 14 Jun 2017 12:07:55 -0700 Subject: [PATCH 280/340] bpo-30659 : Use ** for kwargs in namedtuple._replace() signature (GH-2173) (GH-2197) (cherry picked from commit 184bd82ba8106785ba22f0d2477dbd08bef821fb) --- Doc/library/collections.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index d0aa62e3683edf..674cb202118f0d 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -855,7 +855,7 @@ field names, the method and attribute names start with an underscore. .. versionchanged:: 3.1 Returns an :class:`OrderedDict` instead of a regular :class:`dict`. -.. method:: somenamedtuple._replace(kwargs) +.. method:: somenamedtuple._replace(**kwargs) Return a new instance of the named tuple replacing specified fields with new values:: From 7895a0585b4b6a1c8082d17227307c6ce2c8bb8b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 14 Jun 2017 22:43:02 +0200 Subject: [PATCH 281/340] bpo-30231: Remove skipped test_imaplib tests (#1419) (#2193) The public cyrus.andrew.cmu.edu IMAP server (port 993) doesn't accept TLS connection using our self-signed x509 certificate. Remove the two tests which are already skipped. --- Lib/test/test_imaplib.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py index 7a821f3e973e4d..99903555001a4b 100644 --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -917,23 +917,6 @@ def test_logincapa(self): _server = self.imap_class(self.host, self.port) self.check_logincapa(_server) - @unittest.skipIf(True, - "bpo-30175: FIXME: cyrus.andrew.cmu.edu doesn't accept " - "our randomly generated client x509 certificate anymore") - def test_logincapa_with_client_certfile(self): - with transient_internet(self.host): - _server = self.imap_class(self.host, self.port, certfile=CERTFILE) - self.check_logincapa(_server) - - @unittest.skipIf(True, - "bpo-30175: FIXME: cyrus.andrew.cmu.edu doesn't accept " - "our randomly generated client x509 certificate anymore") - def test_logincapa_with_client_ssl_context(self): - with transient_internet(self.host): - _server = self.imap_class( - self.host, self.port, ssl_context=self.create_ssl_context()) - self.check_logincapa(_server) - def test_logout(self): with transient_internet(self.host): _server = self.imap_class(self.host, self.port) From 8c797ed8a0fea5e3162b9415f13e270d4d5d9549 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 15 Jun 2017 02:16:38 +0200 Subject: [PATCH 282/340] bpo-29591: Upgrade Modules/expat to libexpat 2.2 (#2164) (#2201) * bpo-29591: Upgrade Modules/expat to libexpat 2.2 * bpo-29591: Restore Python changes on expat * bpo-29591: Remove expat config of unsupported platforms Remove the configuration (Modules/expat/*config.h) of unsupported platforms: * Amiga * MacOS Classic on PPC32 * Open Watcom * bpo-29591: Remove useless XML_HAS_SET_HASH_SALT The XML_HAS_SET_HASH_SALT define of Modules/expat/expat.h became useless since our local expat copy was upgrade to expat 2.1 (it's now expat 2.2.0). (cherry picked from commit 23ec4b57e1359f9c539b8defc317542173ae087e) --- Misc/NEWS | 4 + Modules/expat/COPYING | 5 +- Modules/expat/amigaconfig.h | 32 ----- Modules/expat/expat.h | 17 ++- Modules/expat/expat_external.h | 14 ++ Modules/expat/internal.h | 22 ++++ Modules/expat/macconfig.h | 53 -------- Modules/expat/watcomconfig.h | 47 ------- Modules/expat/xmlparse.c | 113 +++++++++++----- Modules/expat/xmlrole.c | 224 ++++++++++++++++---------------- Modules/expat/xmltok.c | 230 +++++++++++++++++++++++---------- Modules/expat/xmltok.h | 10 +- Modules/expat/xmltok_impl.c | 226 ++++++++++++++++---------------- Modules/pyexpat.c | 6 +- 14 files changed, 527 insertions(+), 476 deletions(-) delete mode 100644 Modules/expat/amigaconfig.h delete mode 100644 Modules/expat/macconfig.h delete mode 100644 Modules/expat/watcomconfig.h diff --git a/Misc/NEWS b/Misc/NEWS index 0ccbb9d0381af3..766bbb03d5d3aa 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,10 @@ Extension Modules Library ------- +- [Security] bpo-29591: Update expat copy from 2.1.1 to 2.2.0 to get fixes + of CVE-2016-0718 and CVE-2016-4472. See + https://sourceforge.net/p/expat/bugs/537/ for more information. + - bpo-24484: Avoid race condition in multiprocessing cleanup. - bpo-28994: The traceback no longer displayed for SystemExit raised in diff --git a/Modules/expat/COPYING b/Modules/expat/COPYING index dcb4506429684b..092c83baee13ae 100644 --- a/Modules/expat/COPYING +++ b/Modules/expat/COPYING @@ -1,6 +1,5 @@ -Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd - and Clark Cooper -Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006 Expat maintainers. +Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper +Copyright (c) 2001-2016 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Modules/expat/amigaconfig.h b/Modules/expat/amigaconfig.h deleted file mode 100644 index 86c611504025fb..00000000000000 --- a/Modules/expat/amigaconfig.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef AMIGACONFIG_H -#define AMIGACONFIG_H - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 4321 - -/* Define to 1 if you have the `bcopy' function. */ -#define HAVE_BCOPY 1 - -/* Define to 1 if you have the header file. */ -#undef HAVE_CHECK_H - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* whether byteorder is bigendian */ -#define WORDS_BIGENDIAN - -/* Define to specify how much context to retain around the current parse - point. */ -#define XML_CONTEXT_BYTES 1024 - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS - -#endif /* AMIGACONFIG_H */ diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index e8eefddc6d8474..086e24b39c51ae 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -342,7 +342,7 @@ XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler); /* OBSOLETE -- OBSOLETE -- OBSOLETE - This handler has been superceded by the EntityDeclHandler above. + This handler has been superseded by the EntityDeclHandler above. It is provided here for backward compatibility. This is called for a declaration of an unparsed (NDATA) entity. @@ -915,8 +915,6 @@ XMLPARSEAPI(int) XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt); -#define XML_HAS_SET_HASH_SALT /* Python Only: Defined for pyexpat.c. */ - /* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then XML_GetErrorCode returns information about the error. */ @@ -975,9 +973,12 @@ XML_FreeContentModel(XML_Parser parser, XML_Content *model); /* Exposing the memory handling functions used in Expat */ XMLPARSEAPI(void *) +XML_ATTR_MALLOC +XML_ATTR_ALLOC_SIZE(2) XML_MemMalloc(XML_Parser parser, size_t size); XMLPARSEAPI(void *) +XML_ATTR_ALLOC_SIZE(3) XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); XMLPARSEAPI(void) @@ -1033,14 +1034,12 @@ XMLPARSEAPI(const XML_Feature *) XML_GetFeatureList(void); -/* Expat follows the GNU/Linux convention of odd number minor version for - beta/development releases and even number minor version for stable - releases. Micro is bumped with each release, and set to 0 with each - change to major or minor version. +/* Expat follows the semantic versioning convention. + See http://semver.org. */ #define XML_MAJOR_VERSION 2 -#define XML_MINOR_VERSION 1 -#define XML_MICRO_VERSION 1 +#define XML_MINOR_VERSION 2 +#define XML_MICRO_VERSION 0 #ifdef __cplusplus } diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index f337e1c5622a95..4860c5777aa018 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -69,12 +69,26 @@ #endif #endif /* not defined XML_STATIC */ +#if !defined(XMLIMPORT) && defined(__GNUC__) && (__GNUC__ >= 4) +#define XMLIMPORT __attribute__ ((visibility ("default"))) +#endif /* If we didn't define it above, define it away: */ #ifndef XMLIMPORT #define XMLIMPORT #endif +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)) +#define XML_ATTR_MALLOC __attribute__((__malloc__)) +#else +#define XML_ATTR_MALLOC +#endif + +#if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) +#define XML_ATTR_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#else +#define XML_ATTR_ALLOC_SIZE(x) +#endif #define XMLPARSEAPI(type) XMLIMPORT type XMLCALL diff --git a/Modules/expat/internal.h b/Modules/expat/internal.h index dd5454831da2b4..94cb98e15cae40 100644 --- a/Modules/expat/internal.h +++ b/Modules/expat/internal.h @@ -71,3 +71,25 @@ #define inline #endif #endif + +#ifndef UNUSED_P +# ifdef __GNUC__ +# define UNUSED_P(p) UNUSED_ ## p __attribute__((__unused__)) +# else +# define UNUSED_P(p) UNUSED_ ## p +# endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +void +align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef); + + +#ifdef __cplusplus +} +#endif diff --git a/Modules/expat/macconfig.h b/Modules/expat/macconfig.h deleted file mode 100644 index 2725caaf54a2e2..00000000000000 --- a/Modules/expat/macconfig.h +++ /dev/null @@ -1,53 +0,0 @@ -/*================================================================ -** Copyright 2000, Clark Cooper -** All rights reserved. -** -** This is free software. You are permitted to copy, distribute, or modify -** it under the terms of the MIT/X license (contained in the COPYING file -** with this distribution.) -** -*/ - -#ifndef MACCONFIG_H -#define MACCONFIG_H - - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 4321 - -/* Define to 1 if you have the `bcopy' function. */ -#undef HAVE_BCOPY - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* whether byteorder is bigendian */ -#define WORDS_BIGENDIAN - -/* Define to specify how much context to retain around the current parse - point. */ -#undef XML_CONTEXT_BYTES - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `long' if does not define. */ -#define off_t long - -/* Define to `unsigned' if does not define. */ -#undef size_t - - -#endif /* ifndef MACCONFIG_H */ diff --git a/Modules/expat/watcomconfig.h b/Modules/expat/watcomconfig.h deleted file mode 100644 index 2f05e3f227c162..00000000000000 --- a/Modules/expat/watcomconfig.h +++ /dev/null @@ -1,47 +0,0 @@ -/* expat_config.h for use with Open Watcom 1.5 and above. */ - -#ifndef WATCOMCONFIG_H -#define WATCOMCONFIG_H - -#ifdef __NT__ -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#endif - -/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ -#define BYTEORDER 1234 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "expat-bugs@mail.libexpat.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "expat" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "expat 2.0.0" - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "2.0.0" - -/* Define to specify how much context to retain around the current parse - point. */ -#define XML_CONTEXT_BYTES 1024 - -/* Define to make parameter entity parsing functionality available. */ -#define XML_DTD 1 - -/* Define to make XML Namespaces functionality available. */ -#define XML_NS 1 - -#endif - diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 412838794d703b..b308e67e2d390d 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -2,9 +2,22 @@ See the file COPYING for copying permission. */ +#include +#include /* memset(), memcpy() */ +#include +#include /* UINT_MAX */ + +#ifdef WIN32 +#define getpid GetCurrentProcessId +#else +#include /* gettimeofday() */ +#include /* getpid() */ +#include /* getpid() */ +#endif + #define XML_BUILDING_EXPAT 1 -#ifdef COMPILED_FROM_DSP +#ifdef WIN32 #include "winconfig.h" #elif defined(MACOS_CLASSIC) #include "macconfig.h" @@ -14,13 +27,7 @@ #include "watcomconfig.h" #elif defined(HAVE_EXPAT_CONFIG_H) #include -#endif /* ndef COMPILED_FROM_DSP */ - -#include -#include /* memset(), memcpy() */ -#include -#include /* UINT_MAX */ -#include /* time() */ +#endif /* ndef WIN32 */ #include "ascii.h" #include "expat.h" @@ -432,7 +439,7 @@ static ELEMENT_TYPE * getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr, const char *end); -static unsigned long generate_hash_secret_salt(void); +static unsigned long generate_hash_secret_salt(XML_Parser parser); static XML_Bool startParsing(XML_Parser parser); static XML_Parser @@ -691,11 +698,38 @@ static const XML_Char implicitContext[] = { }; static unsigned long -generate_hash_secret_salt(void) +gather_time_entropy(void) { - unsigned int seed = time(NULL) % UINT_MAX; - srand(seed); - return rand(); +#ifdef WIN32 + FILETIME ft; + GetSystemTimeAsFileTime(&ft); /* never fails */ + return ft.dwHighDateTime ^ ft.dwLowDateTime; +#else + struct timeval tv; + int gettimeofday_res; + + gettimeofday_res = gettimeofday(&tv, NULL); + assert (gettimeofday_res == 0); + + /* Microseconds time is <20 bits entropy */ + return tv.tv_usec; +#endif +} + +static unsigned long +generate_hash_secret_salt(XML_Parser parser) +{ + /* Process ID is 0 bits entropy if attacker has local access + * XML_Parser address is few bits of entropy if attacker has local access */ + const unsigned long entropy = + gather_time_entropy() ^ getpid() ^ (unsigned long)parser; + + /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ + if (sizeof(unsigned long) == 4) { + return entropy * 2147483647; + } else { + return entropy * (unsigned long)2305843009213693951; + } } static XML_Bool /* only valid for root parser */ @@ -703,7 +737,7 @@ startParsing(XML_Parser parser) { /* hash functions must be initialized before setContext() is called */ if (hash_secret_salt == 0) - hash_secret_salt = generate_hash_secret_salt(); + hash_secret_salt = generate_hash_secret_salt(parser); if (ns) { /* implicit context only set for root parser, since child parsers (i.e. external entity parsers) will inherit it @@ -1695,15 +1729,15 @@ XML_GetBuffer(XML_Parser parser, int len) if (len > bufferLim - bufferEnd) { #ifdef XML_CONTEXT_BYTES int keep; -#endif - int neededSize = len + (int)(bufferEnd - bufferPtr); +#endif /* defined XML_CONTEXT_BYTES */ + /* Do not invoke signed arithmetic overflow: */ + int neededSize = (int) ((unsigned)len + (unsigned)(bufferEnd - bufferPtr)); if (neededSize < 0) { errorCode = XML_ERROR_NO_MEMORY; return NULL; } #ifdef XML_CONTEXT_BYTES keep = (int)(bufferPtr - buffer); - if (keep > XML_CONTEXT_BYTES) keep = XML_CONTEXT_BYTES; neededSize += keep; @@ -1728,7 +1762,8 @@ XML_GetBuffer(XML_Parser parser, int len) if (bufferSize == 0) bufferSize = INIT_BUFFER_SIZE; do { - bufferSize *= 2; + /* Do not invoke signed arithmetic overflow: */ + bufferSize = (int) (2U * (unsigned) bufferSize); } while (bufferSize < neededSize && bufferSize > 0); if (bufferSize <= 0) { errorCode = XML_ERROR_NO_MEMORY; @@ -1855,7 +1890,7 @@ XML_Index XMLCALL XML_GetCurrentByteIndex(XML_Parser parser) { if (eventPtr) - return parseEndByteIndex - (parseEndPtr - eventPtr); + return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); return -1; } @@ -2429,11 +2464,11 @@ doContent(XML_Parser parser, for (;;) { int bufSize; int convLen; - XmlConvert(enc, + const enum XML_Convert_Result convert_res = XmlConvert(enc, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); convLen = (int)(toPtr - (XML_Char *)tag->buf); - if (fromPtr == rawNameEnd) { + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } @@ -2654,11 +2689,11 @@ doContent(XML_Parser parser, if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = s; charDataHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } @@ -3264,11 +3299,11 @@ doCdataSection(XML_Parser parser, if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); + const enum XML_Convert_Result convert_res = XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = next; charDataHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); - if (s == next) + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; *eventPP = s; } @@ -4927,9 +4962,9 @@ internalEntityProcessor(XML_Parser parser, static enum XML_Error PTRCALL errorProcessor(XML_Parser parser, - const char *s, - const char *end, - const char **nextPtr) + const char *UNUSED_P(s), + const char *UNUSED_P(end), + const char **UNUSED_P(nextPtr)) { return errorCode; } @@ -5345,6 +5380,7 @@ reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end) { if (MUST_CONVERT(enc, s)) { + enum XML_Convert_Result convert_res; const char **eventPP; const char **eventEndPP; if (enc == encoding) { @@ -5357,11 +5393,11 @@ reportDefault(XML_Parser parser, const ENCODING *enc, } do { ICHAR *dataPtr = (ICHAR *)dataBuf; - XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); + convert_res = XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); *eventEndPP = s; defaultHandler(handlerArg, dataBuf, (int)(dataPtr - (ICHAR *)dataBuf)); *eventPP = s; - } while (s != end); + } while ((convert_res != XML_CONVERT_COMPLETED) && (convert_res != XML_CONVERT_INPUT_INCOMPLETE)); } else defaultHandler(handlerArg, (XML_Char *)s, (int)((XML_Char *)end - (XML_Char *)s)); @@ -6166,8 +6202,8 @@ poolAppend(STRING_POOL *pool, const ENCODING *enc, if (!pool->ptr && !poolGrow(pool)) return NULL; for (;;) { - XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); - if (ptr == end) + const enum XML_Convert_Result convert_res = XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end); + if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) break; if (!poolGrow(pool)) return NULL; @@ -6251,8 +6287,13 @@ poolGrow(STRING_POOL *pool) } } if (pool->blocks && pool->start == pool->blocks->s) { - int blockSize = (int)(pool->end - pool->start)*2; - BLOCK *temp = (BLOCK *) + BLOCK *temp; + int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); + + if (blockSize < 0) + return XML_FALSE; + + temp = (BLOCK *) pool->mem->realloc_fcn(pool->blocks, (offsetof(BLOCK, s) + blockSize * sizeof(XML_Char))); @@ -6267,6 +6308,10 @@ poolGrow(STRING_POOL *pool) else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); + + if (blockSize < 0) + return XML_FALSE; + if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; else diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index 44772e21dd337b..fcd0dc6948f442 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -4,7 +4,7 @@ #include -#ifdef COMPILED_FROM_DSP +#ifdef WIN32 #include "winconfig.h" #elif defined(MACOS_CLASSIC) #include "macconfig.h" @@ -16,7 +16,7 @@ #ifdef HAVE_EXPAT_CONFIG_H #include #endif -#endif /* ndef COMPILED_FROM_DSP */ +#endif /* ndef WIN32 */ #include "expat_external.h" #include "internal.h" @@ -195,9 +195,9 @@ prolog1(PROLOG_STATE *state, static int PTRCALL prolog2(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -216,9 +216,9 @@ prolog2(PROLOG_STATE *state, static int PTRCALL doctype0(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -264,9 +264,9 @@ doctype1(PROLOG_STATE *state, static int PTRCALL doctype2(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -281,9 +281,9 @@ doctype2(PROLOG_STATE *state, static int PTRCALL doctype3(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -298,9 +298,9 @@ doctype3(PROLOG_STATE *state, static int PTRCALL doctype4(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -318,9 +318,9 @@ doctype4(PROLOG_STATE *state, static int PTRCALL doctype5(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -437,9 +437,9 @@ externalSubset1(PROLOG_STATE *state, static int PTRCALL entity0(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -457,9 +457,9 @@ entity0(PROLOG_STATE *state, static int PTRCALL entity1(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -502,9 +502,9 @@ entity2(PROLOG_STATE *state, static int PTRCALL entity3(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -519,9 +519,9 @@ entity3(PROLOG_STATE *state, static int PTRCALL entity4(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -559,9 +559,9 @@ entity5(PROLOG_STATE *state, static int PTRCALL entity6(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -605,9 +605,9 @@ entity7(PROLOG_STATE *state, static int PTRCALL entity8(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -622,9 +622,9 @@ entity8(PROLOG_STATE *state, static int PTRCALL entity9(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -639,9 +639,9 @@ entity9(PROLOG_STATE *state, static int PTRCALL entity10(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -656,9 +656,9 @@ entity10(PROLOG_STATE *state, static int PTRCALL notation0(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -697,9 +697,9 @@ notation1(PROLOG_STATE *state, static int PTRCALL notation2(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -714,9 +714,9 @@ notation2(PROLOG_STATE *state, static int PTRCALL notation3(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -732,9 +732,9 @@ notation3(PROLOG_STATE *state, static int PTRCALL notation4(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -753,9 +753,9 @@ notation4(PROLOG_STATE *state, static int PTRCALL attlist0(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -771,9 +771,9 @@ attlist0(PROLOG_STATE *state, static int PTRCALL attlist1(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -833,9 +833,9 @@ attlist2(PROLOG_STATE *state, static int PTRCALL attlist3(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -852,9 +852,9 @@ attlist3(PROLOG_STATE *state, static int PTRCALL attlist4(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -872,9 +872,9 @@ attlist4(PROLOG_STATE *state, static int PTRCALL attlist5(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -889,9 +889,9 @@ attlist5(PROLOG_STATE *state, static int PTRCALL attlist6(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -906,9 +906,9 @@ attlist6(PROLOG_STATE *state, static int PTRCALL attlist7(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -967,9 +967,9 @@ attlist8(PROLOG_STATE *state, static int PTRCALL attlist9(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -984,9 +984,9 @@ attlist9(PROLOG_STATE *state, static int PTRCALL element0(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1072,9 +1072,9 @@ element2(PROLOG_STATE *state, static int PTRCALL element3(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1097,9 +1097,9 @@ element3(PROLOG_STATE *state, static int PTRCALL element4(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1115,9 +1115,9 @@ element4(PROLOG_STATE *state, static int PTRCALL element5(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1136,9 +1136,9 @@ element5(PROLOG_STATE *state, static int PTRCALL element6(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1166,9 +1166,9 @@ element6(PROLOG_STATE *state, static int PTRCALL element7(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1240,9 +1240,9 @@ condSect0(PROLOG_STATE *state, static int PTRCALL condSect1(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1258,9 +1258,9 @@ condSect1(PROLOG_STATE *state, static int PTRCALL condSect2(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1277,9 +1277,9 @@ condSect2(PROLOG_STATE *state, static int PTRCALL declClose(PROLOG_STATE *state, int tok, - const char *ptr, - const char *end, - const ENCODING *enc) + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { switch (tok) { case XML_TOK_PROLOG_S: @@ -1292,11 +1292,11 @@ declClose(PROLOG_STATE *state, } static int PTRCALL -error(PROLOG_STATE *state, - int tok, - const char *ptr, - const char *end, - const ENCODING *enc) +error(PROLOG_STATE *UNUSED_P(state), + int UNUSED_P(tok), + const char *UNUSED_P(ptr), + const char *UNUSED_P(end), + const ENCODING *UNUSED_P(enc)) { return XML_ROLE_NONE; } diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index bf09dfc72b9fc8..a29d9e2f8ac386 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -4,7 +4,7 @@ #include -#ifdef COMPILED_FROM_DSP +#ifdef WIN32 #include "winconfig.h" #elif defined(MACOS_CLASSIC) #include "macconfig.h" @@ -16,7 +16,7 @@ #ifdef HAVE_EXPAT_CONFIG_H #include #endif -#endif /* ndef COMPILED_FROM_DSP */ +#endif /* ndef WIN32 */ #include "expat_external.h" #include "internal.h" @@ -46,7 +46,7 @@ #define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16) #define UCS2_GET_NAMING(pages, hi, lo) \ - (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F))) + (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1u << ((lo) & 0x1F))) /* A 2 byte UTF-8 representation splits the characters 11 bits between the bottom 5 and 6 bits of the bytes. We need 8 bits to index into @@ -56,7 +56,7 @@ (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \ + ((((byte)[0]) & 3) << 1) \ + ((((byte)[1]) >> 5) & 1)] \ - & (1 << (((byte)[1]) & 0x1F))) + & (1u << (((byte)[1]) & 0x1F))) /* A 3 byte UTF-8 representation splits the characters 16 bits between the bottom 4, 6 and 6 bits of the bytes. We need 8 bits to index @@ -69,7 +69,7 @@ << 3) \ + ((((byte)[1]) & 3) << 1) \ + ((((byte)[2]) >> 5) & 1)] \ - & (1 << (((byte)[2]) & 0x1F))) + & (1u << (((byte)[2]) & 0x1F))) #define UTF8_GET_NAMING(pages, p, n) \ ((n) == 2 \ @@ -122,19 +122,19 @@ ((*p) == 0xF4 ? (p)[1] > 0x8F : ((p)[1] & 0xC0) == 0xC0))) static int PTRFASTCALL -isNever(const ENCODING *enc, const char *p) +isNever(const ENCODING *UNUSED_P(enc), const char *UNUSED_P(p)) { return 0; } static int PTRFASTCALL -utf8_isName2(const ENCODING *enc, const char *p) +utf8_isName2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(namePages, (const unsigned char *)p); } static int PTRFASTCALL -utf8_isName3(const ENCODING *enc, const char *p) +utf8_isName3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(namePages, (const unsigned char *)p); } @@ -142,13 +142,13 @@ utf8_isName3(const ENCODING *enc, const char *p) #define utf8_isName4 isNever static int PTRFASTCALL -utf8_isNmstrt2(const ENCODING *enc, const char *p) +utf8_isNmstrt2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p); } static int PTRFASTCALL -utf8_isNmstrt3(const ENCODING *enc, const char *p) +utf8_isNmstrt3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p); } @@ -156,19 +156,19 @@ utf8_isNmstrt3(const ENCODING *enc, const char *p) #define utf8_isNmstrt4 isNever static int PTRFASTCALL -utf8_isInvalid2(const ENCODING *enc, const char *p) +utf8_isInvalid2(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID2((const unsigned char *)p); } static int PTRFASTCALL -utf8_isInvalid3(const ENCODING *enc, const char *p) +utf8_isInvalid3(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID3((const unsigned char *)p); } static int PTRFASTCALL -utf8_isInvalid4(const ENCODING *enc, const char *p) +utf8_isInvalid4(const ENCODING *UNUSED_P(enc), const char *p) { return UTF8_INVALID4((const unsigned char *)p); } @@ -222,6 +222,17 @@ struct normal_encoding { E ## isInvalid3, \ E ## isInvalid4 +#define NULL_VTABLE \ + /* isName2 */ NULL, \ + /* isName3 */ NULL, \ + /* isName4 */ NULL, \ + /* isNmstrt2 */ NULL, \ + /* isNmstrt3 */ NULL, \ + /* isNmstrt4 */ NULL, \ + /* isInvalid2 */ NULL, \ + /* isInvalid3 */ NULL, \ + /* isInvalid4 */ NULL + static int FASTCALL checkCharRefNumber(int); #include "xmltok_impl.h" @@ -318,39 +329,89 @@ enum { /* UTF8_cvalN is value of masked first byte of N byte sequence */ UTF8_cval4 = 0xf0 }; -static void PTRCALL -utf8_toUtf8(const ENCODING *enc, +void +align_limit_to_full_utf8_characters(const char * from, const char ** fromLimRef) +{ + const char * fromLim = *fromLimRef; + size_t walked = 0; + for (; fromLim > from; fromLim--, walked++) { + const unsigned char prev = (unsigned char)fromLim[-1]; + if ((prev & 0xf8u) == 0xf0u) { /* 4-byte character, lead by 0b11110xxx byte */ + if (walked + 1 >= 4) { + fromLim += 4 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xf0u) == 0xe0u) { /* 3-byte character, lead by 0b1110xxxx byte */ + if (walked + 1 >= 3) { + fromLim += 3 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0xe0u) == 0xc0u) { /* 2-byte character, lead by 0b110xxxxx byte */ + if (walked + 1 >= 2) { + fromLim += 2 - 1; + break; + } else { + walked = 0; + } + } else if ((prev & 0x80u) == 0x00u) { /* 1-byte character, matching 0b0xxxxxxx */ + break; + } + } + *fromLimRef = fromLim; +} + +static enum XML_Convert_Result PTRCALL +utf8_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; char *to; const char *from; if (fromLim - *fromP > toLim - *toP) { /* Avoid copying partial characters. */ - for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--) - if (((unsigned char)fromLim[-1] & 0xc0) != 0x80) - break; + res = XML_CONVERT_OUTPUT_EXHAUSTED; + fromLim = *fromP + (toLim - *toP); + align_limit_to_full_utf8_characters(*fromP, &fromLim); } - for (to = *toP, from = *fromP; from != fromLim; from++, to++) + for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) *to = *from; *fromP = from; *toP = to; + + if ((to == toLim) && (from < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return res; } -static void PTRCALL +static enum XML_Convert_Result PTRCALL utf8_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; unsigned short *to = *toP; const char *from = *fromP; - while (from != fromLim && to != toLim) { + while (from < fromLim && to < toLim) { switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) { case BT_LEAD2: + if (fromLim - from < 2) { + res = XML_CONVERT_INPUT_INCOMPLETE; + break; + } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; break; case BT_LEAD3: + if (fromLim - from < 3) { + res = XML_CONVERT_INPUT_INCOMPLETE; + break; + } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); from += 3; @@ -358,8 +419,14 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD4: { unsigned long n; - if (to + 1 == toLim) + if (toLim - to < 2) { + res = XML_CONVERT_OUTPUT_EXHAUSTED; goto after; + } + if (fromLim - from < 4) { + res = XML_CONVERT_INPUT_INCOMPLETE; + goto after; + } n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f); n -= 0x10000; @@ -377,6 +444,7 @@ utf8_toUtf16(const ENCODING *enc, after: *fromP = from; *toP = to; + return res; } #ifdef XML_NS @@ -425,38 +493,43 @@ static const struct normal_encoding internal_utf8_encoding = { STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_) }; -static void PTRCALL -latin1_toUtf8(const ENCODING *enc, +static enum XML_Convert_Result PTRCALL +latin1_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { for (;;) { unsigned char c; if (*fromP == fromLim) - break; + return XML_CONVERT_COMPLETED; c = (unsigned char)**fromP; if (c & 0x80) { if (toLim - *toP < 2) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = (char)((c >> 6) | UTF8_cval2); *(*toP)++ = (char)((c & 0x3f) | 0x80); (*fromP)++; } else { if (*toP == toLim) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; *(*toP)++ = *(*fromP)++; } } } -static void PTRCALL -latin1_toUtf16(const ENCODING *enc, +static enum XML_Convert_Result PTRCALL +latin1_toUtf16(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { - while (*fromP != fromLim && *toP != toLim) + while (*fromP < fromLim && *toP < toLim) *(*toP)++ = (unsigned char)*(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; } #ifdef XML_NS @@ -467,7 +540,7 @@ static const struct normal_encoding latin1_encoding_ns = { #include "asciitab.h" #include "latin1tab.h" }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif @@ -480,16 +553,21 @@ static const struct normal_encoding latin1_encoding = { #undef BT_COLON #include "latin1tab.h" }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; -static void PTRCALL -ascii_toUtf8(const ENCODING *enc, +static enum XML_Convert_Result PTRCALL +ascii_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { - while (*fromP != fromLim && *toP != toLim) + while (*fromP < fromLim && *toP < toLim) *(*toP)++ = *(*fromP)++; + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; } #ifdef XML_NS @@ -500,7 +578,7 @@ static const struct normal_encoding ascii_encoding_ns = { #include "asciitab.h" /* BT_NONXML == 0 */ }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; #endif @@ -513,7 +591,7 @@ static const struct normal_encoding ascii_encoding = { #undef BT_COLON /* BT_NONXML == 0 */ }, - STANDARD_VTABLE(sb_) + STANDARD_VTABLE(sb_) NULL_VTABLE }; static int PTRFASTCALL @@ -536,13 +614,14 @@ unicode_byte_type(char hi, char lo) } #define DEFINE_UTF16_TO_UTF8(E) \ -static void PTRCALL \ -E ## toUtf8(const ENCODING *enc, \ +static enum XML_Convert_Result PTRCALL \ +E ## toUtf8(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ char **toP, const char *toLim) \ { \ - const char *from; \ - for (from = *fromP; from != fromLim; from += 2) { \ + const char *from = *fromP; \ + fromLim = from + (((fromLim - from) >> 1) << 1); /* shrink to even */ \ + for (; from < fromLim; from += 2) { \ int plane; \ unsigned char lo2; \ unsigned char lo = GET_LO(from); \ @@ -552,7 +631,7 @@ E ## toUtf8(const ENCODING *enc, \ if (lo < 0x80) { \ if (*toP == toLim) { \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = lo; \ break; \ @@ -562,7 +641,7 @@ E ## toUtf8(const ENCODING *enc, \ case 0x4: case 0x5: case 0x6: case 0x7: \ if (toLim - *toP < 2) { \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ *(*toP)++ = ((lo >> 6) | (hi << 2) | UTF8_cval2); \ *(*toP)++ = ((lo & 0x3f) | 0x80); \ @@ -570,7 +649,7 @@ E ## toUtf8(const ENCODING *enc, \ default: \ if (toLim - *toP < 3) { \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ } \ /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \ *(*toP)++ = ((hi >> 4) | UTF8_cval3); \ @@ -580,7 +659,11 @@ E ## toUtf8(const ENCODING *enc, \ case 0xD8: case 0xD9: case 0xDA: case 0xDB: \ if (toLim - *toP < 4) { \ *fromP = from; \ - return; \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + } \ + if (fromLim - from < 4) { \ + *fromP = from; \ + return XML_CONVERT_INPUT_INCOMPLETE; \ } \ plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \ *(*toP)++ = ((plane >> 2) | UTF8_cval4); \ @@ -596,20 +679,32 @@ E ## toUtf8(const ENCODING *enc, \ } \ } \ *fromP = from; \ + if (from < fromLim) \ + return XML_CONVERT_INPUT_INCOMPLETE; \ + else \ + return XML_CONVERT_COMPLETED; \ } #define DEFINE_UTF16_TO_UTF16(E) \ -static void PTRCALL \ -E ## toUtf16(const ENCODING *enc, \ +static enum XML_Convert_Result PTRCALL \ +E ## toUtf16(const ENCODING *UNUSED_P(enc), \ const char **fromP, const char *fromLim, \ unsigned short **toP, const unsigned short *toLim) \ { \ + enum XML_Convert_Result res = XML_CONVERT_COMPLETED; \ + fromLim = *fromP + (((fromLim - *fromP) >> 1) << 1); /* shrink to even */ \ /* Avoid copying first half only of surrogate */ \ if (fromLim - *fromP > ((toLim - *toP) << 1) \ - && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \ + && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) { \ fromLim -= 2; \ - for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \ + res = XML_CONVERT_INPUT_INCOMPLETE; \ + } \ + for (; *fromP < fromLim && *toP < toLim; *fromP += 2) \ *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \ + if ((*toP == toLim) && (*fromP < fromLim)) \ + return XML_CONVERT_OUTPUT_EXHAUSTED; \ + else \ + return res; \ } #define SET2(ptr, ch) \ @@ -726,7 +821,7 @@ static const struct normal_encoding little2_encoding_ns = { #include "asciitab.h" #include "latin1tab.h" }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif @@ -745,7 +840,7 @@ static const struct normal_encoding little2_encoding = { #undef BT_COLON #include "latin1tab.h" }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; #if BYTEORDER != 4321 @@ -758,7 +853,7 @@ static const struct normal_encoding internal_little2_encoding_ns = { #include "iasciitab.h" #include "latin1tab.h" }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif @@ -771,7 +866,7 @@ static const struct normal_encoding internal_little2_encoding = { #undef BT_COLON #include "latin1tab.h" }, - STANDARD_VTABLE(little2_) + STANDARD_VTABLE(little2_) NULL_VTABLE }; #endif @@ -867,7 +962,7 @@ static const struct normal_encoding big2_encoding_ns = { #include "asciitab.h" #include "latin1tab.h" }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif @@ -886,7 +981,7 @@ static const struct normal_encoding big2_encoding = { #undef BT_COLON #include "latin1tab.h" }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; #if BYTEORDER != 1234 @@ -899,7 +994,7 @@ static const struct normal_encoding internal_big2_encoding_ns = { #include "iasciitab.h" #include "latin1tab.h" }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif @@ -912,7 +1007,7 @@ static const struct normal_encoding internal_big2_encoding = { #undef BT_COLON #include "latin1tab.h" }, - STANDARD_VTABLE(big2_) + STANDARD_VTABLE(big2_) NULL_VTABLE }; #endif @@ -938,7 +1033,7 @@ streqci(const char *s1, const char *s2) } static void PTRCALL -initUpdatePosition(const ENCODING *enc, const char *ptr, +initUpdatePosition(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, POSITION *pos) { normal_updatePosition(&utf8_encoding.enc, ptr, end, pos); @@ -1288,7 +1383,7 @@ unknown_isInvalid(const ENCODING *enc, const char *p) return (c & ~0xFFFF) || checkCharRefNumber(c) < 0; } -static void PTRCALL +static enum XML_Convert_Result PTRCALL unknown_toUtf8(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim) @@ -1299,21 +1394,21 @@ unknown_toUtf8(const ENCODING *enc, const char *utf8; int n; if (*fromP == fromLim) - break; + return XML_CONVERT_COMPLETED; utf8 = uenc->utf8[(unsigned char)**fromP]; n = *utf8++; if (n == 0) { int c = uenc->convert(uenc->userData, *fromP); n = XmlUtf8Encode(c, buf); if (n > toLim - *toP) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; utf8 = buf; *fromP += (AS_NORMAL_ENCODING(enc)->type[(unsigned char)**fromP] - (BT_LEAD2 - 2)); } else { if (n > toLim - *toP) - break; + return XML_CONVERT_OUTPUT_EXHAUSTED; (*fromP)++; } do { @@ -1322,13 +1417,13 @@ unknown_toUtf8(const ENCODING *enc, } } -static void PTRCALL +static enum XML_Convert_Result PTRCALL unknown_toUtf16(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, const unsigned short *toLim) { const struct unknown_encoding *uenc = AS_UNKNOWN_ENCODING(enc); - while (*fromP != fromLim && *toP != toLim) { + while (*fromP < fromLim && *toP < toLim) { unsigned short c = uenc->utf16[(unsigned char)**fromP]; if (c == 0) { c = (unsigned short) @@ -1340,6 +1435,11 @@ unknown_toUtf16(const ENCODING *enc, (*fromP)++; *(*toP)++ = c; } + + if ((*toP == toLim) && (*fromP < fromLim)) + return XML_CONVERT_OUTPUT_EXHAUSTED; + else + return XML_CONVERT_COMPLETED; } ENCODING * @@ -1503,7 +1603,7 @@ initScan(const ENCODING * const *encodingTable, { const ENCODING **encPtr; - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; encPtr = enc->encPtr; if (ptr + 1 == end) { diff --git a/Modules/expat/xmltok.h b/Modules/expat/xmltok.h index ca867aa6b429cf..752007e8b9e219 100644 --- a/Modules/expat/xmltok.h +++ b/Modules/expat/xmltok.h @@ -130,6 +130,12 @@ typedef int (PTRCALL *SCANNER)(const ENCODING *, const char *, const char **); +enum XML_Convert_Result { + XML_CONVERT_COMPLETED = 0, + XML_CONVERT_INPUT_INCOMPLETE = 1, + XML_CONVERT_OUTPUT_EXHAUSTED = 2 /* and therefore potentially input remaining as well */ +}; + struct encoding { SCANNER scanners[XML_N_STATES]; SCANNER literalScanners[XML_N_LITERAL_TYPES]; @@ -158,12 +164,12 @@ struct encoding { const char *ptr, const char *end, const char **badPtr); - void (PTRCALL *utf8Convert)(const ENCODING *enc, + enum XML_Convert_Result (PTRCALL *utf8Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, char **toP, const char *toLim); - void (PTRCALL *utf16Convert)(const ENCODING *enc, + enum XML_Convert_Result (PTRCALL *utf16Convert)(const ENCODING *enc, const char **fromP, const char *fromLim, unsigned short **toP, diff --git a/Modules/expat/xmltok_impl.c b/Modules/expat/xmltok_impl.c index 9c2895b87739ef..5f779c0571b5b1 100644 --- a/Modules/expat/xmltok_impl.c +++ b/Modules/expat/xmltok_impl.c @@ -87,27 +87,45 @@ #define PREFIX(ident) ident #endif + +#define HAS_CHARS(enc, ptr, end, count) \ + (end - ptr >= count * MINBPC(enc)) + +#define HAS_CHAR(enc, ptr, end) \ + HAS_CHARS(enc, ptr, end, 1) + +#define REQUIRE_CHARS(enc, ptr, end, count) \ + { \ + if (! HAS_CHARS(enc, ptr, end, count)) { \ + return XML_TOK_PARTIAL; \ + } \ + } + +#define REQUIRE_CHAR(enc, ptr, end) \ + REQUIRE_CHARS(enc, ptr, end, 1) + + /* ptr points to character following " */ switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) { case BT_S: case BT_CR: case BT_LF: case BT_PERCNT: @@ -175,7 +191,7 @@ PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, } static int PTRCALL -PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, +PREFIX(checkPiTarget)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, int *tokPtr) { int upper = 0; @@ -225,15 +241,14 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, { int tok; const char *target = ptr; - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: @@ -242,13 +257,12 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, return XML_TOK_INVALID; } ptr += MINBPC(enc); - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_QUEST: ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok; @@ -266,8 +280,7 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, return XML_TOK_INVALID; } ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr + MINBPC(enc); return tok; @@ -282,15 +295,14 @@ PREFIX(scanPi)(const ENCODING *enc, const char *ptr, } static int PTRCALL -PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, +PREFIX(scanCdataSection)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end, const char **nextTokPtr) { static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB }; int i; /* CDATA[ */ - if (end - ptr < 6 * MINBPC(enc)) - return XML_TOK_PARTIAL; + REQUIRE_CHARS(enc, ptr, end, 6); for (i = 0; i < 6; i++, ptr += MINBPC(enc)) { if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) { *nextTokPtr = ptr; @@ -305,7 +317,7 @@ static int PTRCALL PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; @@ -319,13 +331,11 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, switch (BYTE_TYPE(enc, ptr)) { case BT_RSQB: ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); break; @@ -334,8 +344,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, return XML_TOK_CDATA_SECT_CLOSE; case BT_CR: ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); *nextTokPtr = ptr; @@ -348,7 +357,7 @@ PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, ptr += MINBPC(enc); break; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ @@ -383,19 +392,18 @@ static int PTRCALL PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { + for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: case BT_LF: break; @@ -432,7 +440,7 @@ static int PTRCALL PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr != end) { + if (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: @@ -441,7 +449,7 @@ PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, *nextTokPtr = ptr; return XML_TOK_INVALID; } - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { + for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: @@ -464,7 +472,7 @@ static int PTRCALL PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr != end) { + if (HAS_CHAR(enc, ptr, end)) { if (CHAR_MATCHES(enc, ptr, ASCII_x)) return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); switch (BYTE_TYPE(enc, ptr)) { @@ -474,7 +482,7 @@ PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, *nextTokPtr = ptr; return XML_TOK_INVALID; } - for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) { + for (ptr += MINBPC(enc); HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: break; @@ -496,8 +504,7 @@ static int PTRCALL PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_NUM: @@ -506,7 +513,7 @@ PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end, *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: @@ -529,7 +536,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, #ifdef XML_NS int hadColon = 0; #endif - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS @@ -540,8 +547,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, } hadColon = 1; ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: @@ -555,8 +561,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, int t; ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == BT_EQUALS) break; @@ -579,8 +584,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, #endif for (;;) { ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); open = BYTE_TYPE(enc, ptr); if (open == BT_QUOT || open == BT_APOS) break; @@ -598,8 +602,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, /* in attribute value */ for (;;) { int t; - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); t = BYTE_TYPE(enc, ptr); if (t == open) break; @@ -624,8 +627,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, } } ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_CR: @@ -642,8 +644,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, /* ptr points to closing quote */ for (;;) { ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_CR: case BT_LF: @@ -655,8 +656,7 @@ PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end, case BT_SOL: sol: ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -688,13 +688,12 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, #ifdef XML_NS int hadColon; #endif - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_EXCL: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_MINUS: return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr); @@ -716,7 +715,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, hadColon = 0; #endif /* we have a start-tag */ - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) #ifdef XML_NS @@ -727,8 +726,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, } hadColon = 1; ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: @@ -740,7 +738,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, case BT_S: case BT_CR: case BT_LF: { ptr += MINBPC(enc); - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_GT: @@ -765,8 +763,7 @@ PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end, case BT_SOL: sol: ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { *nextTokPtr = ptr; return XML_TOK_INVALID; @@ -785,7 +782,7 @@ static int PTRCALL PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; @@ -803,7 +800,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr); case BT_CR: ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); @@ -814,12 +811,12 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_DATA_NEWLINE; case BT_RSQB: ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB)) break; ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_RSQB; if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr -= MINBPC(enc); @@ -832,7 +829,7 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); break; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ @@ -845,12 +842,12 @@ PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end, LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4) #undef LEAD_CASE case BT_RSQB: - if (ptr + MINBPC(enc) != end) { + if (HAS_CHARS(enc, ptr, end, 2)) { if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) { ptr += MINBPC(enc); break; } - if (ptr + 2*MINBPC(enc) != end) { + if (HAS_CHARS(enc, ptr, end, 3)) { if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) { ptr += MINBPC(enc); break; @@ -884,8 +881,7 @@ static int PTRCALL PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) case BT_S: case BT_LF: case BT_CR: case BT_PERCNT: @@ -895,7 +891,7 @@ PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end, *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_SEMI: @@ -913,15 +909,14 @@ static int PTRCALL PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) default: *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_CR: case BT_LF: case BT_S: @@ -941,7 +936,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { int t = BYTE_TYPE(enc, ptr); switch (t) { INVALID_CASES(ptr, nextTokPtr) @@ -950,7 +945,7 @@ PREFIX(scanLit)(int open, const ENCODING *enc, ptr += MINBPC(enc); if (t != open) break; - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_LITERAL; *nextTokPtr = ptr; switch (BYTE_TYPE(enc, ptr)) { @@ -973,7 +968,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { int tok; - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; if (MINBPC(enc) > 1) { size_t n = end - ptr; @@ -992,8 +987,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_LT: { ptr += MINBPC(enc); - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); switch (BYTE_TYPE(enc, ptr)) { case BT_EXCL: return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr); @@ -1021,7 +1015,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, case BT_S: case BT_LF: for (;;) { ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) break; switch (BYTE_TYPE(enc, ptr)) { case BT_S: case BT_LF: @@ -1048,11 +1042,10 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_OPEN_BRACKET; case BT_RSQB: ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_BRACKET; if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if (ptr + MINBPC(enc) == end) - return XML_TOK_PARTIAL; + REQUIRE_CHARS(enc, ptr, end, 2); if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) { *nextTokPtr = ptr + 2*MINBPC(enc); return XML_TOK_COND_SECT_CLOSE; @@ -1065,7 +1058,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, return XML_TOK_OPEN_PAREN; case BT_RPAR: ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return -XML_TOK_CLOSE_PAREN; switch (BYTE_TYPE(enc, ptr)) { case BT_AST: @@ -1141,7 +1134,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, *nextTokPtr = ptr; return XML_TOK_INVALID; } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) case BT_GT: case BT_RPAR: case BT_COMMA: @@ -1154,8 +1147,7 @@ PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end, ptr += MINBPC(enc); switch (tok) { case XML_TOK_NAME: - if (ptr == end) - return XML_TOK_PARTIAL; + REQUIRE_CHAR(enc, ptr, end); tok = XML_TOK_PREFIXED_NAME; switch (BYTE_TYPE(enc, ptr)) { CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) @@ -1204,10 +1196,12 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_PARTIAL; start = ptr; - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break; @@ -1232,7 +1226,7 @@ PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, case BT_CR: if (ptr == start) { ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); @@ -1262,10 +1256,12 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end, const char **nextTokPtr) { const char *start; - if (ptr == end) + if (ptr >= end) return XML_TOK_NONE; + else if (! HAS_CHAR(enc, ptr, end)) + return XML_TOK_PARTIAL; start = ptr; - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: ptr += n; break; @@ -1294,7 +1290,7 @@ PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, case BT_CR: if (ptr == start) { ptr += MINBPC(enc); - if (ptr == end) + if (! HAS_CHAR(enc, ptr, end)) return XML_TOK_TRAILING_CR; if (BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); @@ -1326,15 +1322,15 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, end = ptr + n; } } - while (ptr != end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { INVALID_CASES(ptr, nextTokPtr) case BT_LT: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) { ++level; ptr += MINBPC(enc); @@ -1342,11 +1338,11 @@ PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, } break; case BT_RSQB: - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) { - if ((ptr += MINBPC(enc)) == end) - return XML_TOK_PARTIAL; + ptr += MINBPC(enc); + REQUIRE_CHAR(enc, ptr, end); if (CHAR_MATCHES(enc, ptr, ASCII_GT)) { ptr += MINBPC(enc); if (level == 0) { @@ -1373,7 +1369,7 @@ PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end, { ptr += MINBPC(enc); end -= MINBPC(enc); - for (; ptr != end; ptr += MINBPC(enc)) { + for (; HAS_CHAR(enc, ptr, end); ptr += MINBPC(enc)) { switch (BYTE_TYPE(enc, ptr)) { case BT_DIGIT: case BT_HEX: @@ -1521,7 +1517,7 @@ PREFIX(getAtts)(const ENCODING *enc, const char *ptr, } static int PTRFASTCALL -PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) +PREFIX(charRefNumber)(const ENCODING *UNUSED_P(enc), const char *ptr) { int result = 0; /* skip &# */ @@ -1565,7 +1561,7 @@ PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr) } static int PTRCALL -PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, +PREFIX(predefinedEntityName)(const ENCODING *UNUSED_P(enc), const char *ptr, const char *end) { switch ((end - ptr)/MINBPC(enc)) { @@ -1683,11 +1679,11 @@ PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2) } static int PTRCALL -PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, +PREFIX(nameMatchesAscii)(const ENCODING *UNUSED_P(enc), const char *ptr1, const char *end1, const char *ptr2) { for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) { - if (ptr1 == end1) + if (end1 - ptr1 < MINBPC(enc)) return 0; if (!CHAR_MATCHES(enc, ptr1, *ptr2)) return 0; @@ -1744,7 +1740,7 @@ PREFIX(updatePosition)(const ENCODING *enc, const char *end, POSITION *pos) { - while (ptr < end) { + while (HAS_CHAR(enc, ptr, end)) { switch (BYTE_TYPE(enc, ptr)) { #define LEAD_CASE(n) \ case BT_LEAD ## n: \ @@ -1760,7 +1756,7 @@ PREFIX(updatePosition)(const ENCODING *enc, case BT_CR: pos->lineNumber++; ptr += MINBPC(enc); - if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF) + if (HAS_CHAR(enc, ptr, end) && BYTE_TYPE(enc, ptr) == BT_LF) ptr += MINBPC(enc); pos->columnNumber = (XML_Size)-1; break; diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index 3a6e590ef21ba6..adc9b6cde859da 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -1190,10 +1190,8 @@ newxmlparseobject(const char *encoding, const char *namespace_separator, PyObjec Py_DECREF(self); return NULL; } -#if XML_COMBINED_VERSION >= 20100 || defined(XML_HAS_SET_HASH_SALT) - /* This feature was added upstream in libexpat 2.1.0. Our expat copy - * has a backport of this feature where we also define XML_HAS_SET_HASH_SALT - * to indicate that we can still use it. */ +#if XML_COMBINED_VERSION >= 20100 + /* This feature was added upstream in libexpat 2.1.0. */ XML_SetHashSalt(self->itself, (unsigned long)_Py_HashSecret.expat.hashsalt); #endif From b39c78a73c203dcaf8f2061da81827c667440402 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 15 Jun 2017 16:58:15 +0300 Subject: [PATCH 283/340] [3.5] bpo-30650: Fixed a syntax error: missed right parentheses (GH-2154) (#2216) (cherry picked from commit 0d32218) --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 00da3c086521a4..9dd26f51ed33de 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12812,7 +12812,7 @@ all_ins(PyObject *m) if (PyModule_AddIntMacro(m, SCHED_RR)) return -1; #endif #ifdef SCHED_SPORADIC - if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1; + if (PyModule_AddIntMacro(m, SCHED_SPORADIC)) return -1; #endif #ifdef SCHED_BATCH if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1; From c5a6fb654a280c7b17f1d348e2e40d62ca04c5d3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 15 Jun 2017 17:16:55 +0300 Subject: [PATCH 284/340] [3.5] bpo-29931 fix __lt__ check in ipaddress.ip_interface for both v4 and v6. (GH-879) (#2218) the original logic was just comparing the network address but this is wrong because if the network address is equal then we need to compare the ip address for breaking the tie add more ip_interface comparison tests. (cherry picked from commit 7bd8d3e794782582a4ad1c9749424fff86802c3e) --- Lib/ipaddress.py | 6 ++++-- Lib/test/test_ipaddress.py | 37 +++++++++++++++++++++++++++++-------- Misc/NEWS | 3 +++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/Lib/ipaddress.py b/Lib/ipaddress.py index 1f900583826a80..35ca38e54fe214 100644 --- a/Lib/ipaddress.py +++ b/Lib/ipaddress.py @@ -1410,7 +1410,8 @@ def __lt__(self, other): if address_less is NotImplemented: return NotImplemented try: - return self.network < other.network + return (self.network < other.network or + self.network == other.network and address_less) except AttributeError: # We *do* allow addresses and interfaces to be sorted. The # unassociated address is considered less than all interfaces. @@ -2100,7 +2101,8 @@ def __lt__(self, other): if address_less is NotImplemented: return NotImplemented try: - return self.network < other.network + return (self.network < other.network or + self.network == other.network and address_less) except AttributeError: # We *do* allow addresses and interfaces to be sorted. The # unassociated address is considered less than all interfaces. diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py index 91ae8d85edfc21..e3dec87ed990f7 100644 --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1404,14 +1404,35 @@ def testAddressComparison(self): ipaddress.ip_address('::2')) def testInterfaceComparison(self): - self.assertTrue(ipaddress.ip_interface('1.1.1.1') <= - ipaddress.ip_interface('1.1.1.1')) - self.assertTrue(ipaddress.ip_interface('1.1.1.1') <= - ipaddress.ip_interface('1.1.1.2')) - self.assertTrue(ipaddress.ip_interface('::1') <= - ipaddress.ip_interface('::1')) - self.assertTrue(ipaddress.ip_interface('::1') <= - ipaddress.ip_interface('::2')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') == + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/16') < + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') < + ipaddress.ip_interface('1.1.1.2/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.2/16') < + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > + ipaddress.ip_interface('1.1.1.1/16')) + self.assertTrue(ipaddress.ip_interface('1.1.1.2/24') > + ipaddress.ip_interface('1.1.1.1/24')) + self.assertTrue(ipaddress.ip_interface('1.1.1.1/24') > + ipaddress.ip_interface('1.1.1.2/16')) + + self.assertTrue(ipaddress.ip_interface('::1/64') == + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::1/80')) + self.assertTrue(ipaddress.ip_interface('::1/64') < + ipaddress.ip_interface('::2/64')) + self.assertTrue(ipaddress.ip_interface('::2/48') < + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/80') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::2/64') > + ipaddress.ip_interface('::1/64')) + self.assertTrue(ipaddress.ip_interface('::1/64') > + ipaddress.ip_interface('::2/48')) def testNetworkComparison(self): # ip1 and ip2 have the same network address diff --git a/Misc/NEWS b/Misc/NEWS index 766bbb03d5d3aa..3fb908a74746d0 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. + Patch by Sanjay Sundaresan. + - [Security] bpo-29591: Update expat copy from 2.1.1 to 2.2.0 to get fixes of CVE-2016-0718 and CVE-2016-4472. See https://sourceforge.net/p/expat/bugs/537/ for more information. From fb0825c2784f80689c4c00c3ede22958faaf512c Mon Sep 17 00:00:00 2001 From: Dong-hee Na Date: Thu, 15 Jun 2017 23:42:01 +0900 Subject: [PATCH 285/340] bpo-30149: Fix partialmethod without explicit self parameter (#1308) (#1663) --- Lib/inspect.py | 13 +++++++++---- Lib/test/test_inspect.py | 35 +++++++++++++++++++++++++++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/Lib/inspect.py b/Lib/inspect.py index 4a11006746acb4..424c945db0d1b1 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2220,11 +2220,16 @@ def _signature_from_callable(obj, *, sigcls=sigcls) sig = _signature_get_partial(wrapped_sig, partialmethod, (None,)) - first_wrapped_param = tuple(wrapped_sig.parameters.values())[0] - new_params = (first_wrapped_param,) + tuple(sig.parameters.values()) - - return sig.replace(parameters=new_params) + if first_wrapped_param.kind is Parameter.VAR_POSITIONAL: + # First argument of the wrapped callable is `*args`, as in + # `partialmethod(lambda *args)`. + return sig + else: + sig_params = tuple(sig.parameters.values()) + assert first_wrapped_param is not sig_params[0] + new_params = (first_wrapped_param,) + sig_params + return sig.replace(parameters=new_params) if isfunction(obj) or _signature_is_functionlike(obj): # If it's a pure Python function, or an object that is duck type diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 2283000c860246..95c5ead24d397a 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -1954,6 +1954,41 @@ def test(a, b:'foo'=10, *args:'bar', spam:'baz', ham=123, **kwargs:int): ('kwargs', ..., int, "var_keyword")), ...)) + def test_signature_without_self(self): + def test_args_only(*args): # NOQA + pass + + def test_args_kwargs_only(*args, **kwargs): # NOQA + pass + + class A: + @classmethod + def test_classmethod(*args): # NOQA + pass + + @staticmethod + def test_staticmethod(*args): # NOQA + pass + + f1 = functools.partialmethod((test_classmethod), 1) + f2 = functools.partialmethod((test_args_only), 1) + f3 = functools.partialmethod((test_staticmethod), 1) + f4 = functools.partialmethod((test_args_kwargs_only),1) + + self.assertEqual(self.signature(test_args_only), + ((('args', ..., ..., 'var_positional'),), ...)) + self.assertEqual(self.signature(test_args_kwargs_only), + ((('args', ..., ..., 'var_positional'), + ('kwargs', ..., ..., 'var_keyword')), ...)) + self.assertEqual(self.signature(A.f1), + ((('args', ..., ..., 'var_positional'),), ...)) + self.assertEqual(self.signature(A.f2), + ((('args', ..., ..., 'var_positional'),), ...)) + self.assertEqual(self.signature(A.f3), + ((('args', ..., ..., 'var_positional'),), ...)) + self.assertEqual(self.signature(A.f4), + ((('args', ..., ..., 'var_positional'), + ('kwargs', ..., ..., 'var_keyword')), ...)) @cpython_only @unittest.skipIf(MISSING_C_DOCSTRINGS, "Signature information for builtins requires docstrings") diff --git a/Misc/NEWS b/Misc/NEWS index 3fb908a74746d0..8b62d792367aba 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,10 @@ Extension Modules Library ------- +- bpo-30149: inspect.signature() now supports callables with + variable-argument parameters wrapped with partialmethod. + Patch by Dong-hee Na. + - bpo-29931: Fixed comparison check for ipaddress.ip_interface objects. Patch by Sanjay Sundaresan. From 263dcc39daa74066c2b2fcb007a4bd4f7ec65073 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 15 Jun 2017 21:15:26 +0300 Subject: [PATCH 286/340] [3.5] bpo-30626: Fix error handling in PyImport_Import(). (GH-2103) (#2222) In rare circumstances PyImport_Import() could return NULL without raising an error. (cherry picked from commit 145541c) --- Python/import.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Python/import.c b/Python/import.c index ea8bc00a73a782..4f08d5ebb7785f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1806,9 +1806,13 @@ PyImport_Import(PyObject *module_name) Py_DECREF(r); modules = PyImport_GetModuleDict(); - r = PyDict_GetItem(modules, module_name); - if (r != NULL) + r = PyDict_GetItemWithError(modules, module_name); + if (r != NULL) { Py_INCREF(r); + } + else if (!PyErr_Occurred()) { + PyErr_SetObject(PyExc_KeyError, module_name); + } err: Py_XDECREF(globals); From 33cf0c4cd6e8abe138c3469ca9ec1502410945f0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 16 Jun 2017 00:08:39 +0200 Subject: [PATCH 287/340] bpo-30675: Fix multiprocessing code in regrtest (#2220) * Rewrite code to pass slaveargs from the master process to worker processes: reuse the same code of the Python master branch * Move code to initialize tests in a new setup_tests() function, similar change was done in the master branch * In a worker process, call setup_tests() with the namespace built from slaveargs to initialize correctly tests Before this change, warm_caches() was not called in worker processes because the setup was done before rebuilding the namespace from slaveargs. As a consequence, the huntrleaks feature was unstable. For example, test_zipfile reported randomly false positive on reference leaks. --- Lib/test/regrtest.py | 110 +++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 47 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 6cb9d5ae0e3fc5..e5aa3e3f7dfbc0 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -140,6 +140,7 @@ import tempfile import time import traceback +import types import unittest import warnings from inspect import isabstract @@ -448,17 +449,15 @@ def run_test_in_subprocess(testname, ns): # required to spawn a new process with PGO flag on/off if ns.pgo: base_cmd = base_cmd + ['--pgo'] - slaveargs = ( - (testname, ns.verbose, ns.quiet), - dict(huntrleaks=ns.huntrleaks, - use_resources=ns.use_resources, - output_on_failure=ns.verbose3, - timeout=ns.timeout, failfast=ns.failfast, - match_tests=ns.match_tests, pgo=ns.pgo)) + + ns_dict = vars(ns) + slaveargs = (ns_dict, testname) + slaveargs = json.dumps(slaveargs) + # Running the child from the same working directory as regrtest's original # invocation ensures that TEMPDIR for the child is the same when # sysconfig.is_python_build() is true. See issue 15300. - popen = Popen(base_cmd + ['--slaveargs', json.dumps(slaveargs)], + popen = Popen(base_cmd + ['--slaveargs', slaveargs], stdout=PIPE, stderr=PIPE, universal_newlines=True, close_fds=(os.name != 'nt'), @@ -468,6 +467,43 @@ def run_test_in_subprocess(testname, ns): return retcode, stdout, stderr +def setup_tests(ns): + if ns.huntrleaks: + # Avoid false positives due to various caches + # filling slowly with random data: + warm_caches() + if ns.memlimit is not None: + support.set_memlimit(ns.memlimit) + if ns.threshold is not None: + import gc + gc.set_threshold(ns.threshold) + if ns.nowindows: + print('The --nowindows (-n) option is deprecated. ' + 'Use -vv to display assertions in stderr.') + try: + import msvcrt + except ImportError: + pass + else: + msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| + msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| + msvcrt.SEM_NOGPFAULTERRORBOX| + msvcrt.SEM_NOOPENFILEERRORBOX) + try: + msvcrt.CrtSetReportMode + except AttributeError: + # release build + pass + else: + for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: + if ns.verbose and ns.verbose >= 2: + msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) + msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) + else: + msvcrt.CrtSetReportMode(m, 0) + + + def main(tests=None, **kwargs): """Execute a test suite. @@ -509,58 +545,38 @@ def main(tests=None, **kwargs): ns = _parse_args(sys.argv[1:], **kwargs) - if ns.huntrleaks: - # Avoid false positives due to various caches - # filling slowly with random data: - warm_caches() - if ns.memlimit is not None: - support.set_memlimit(ns.memlimit) - if ns.threshold is not None: - import gc - gc.set_threshold(ns.threshold) - if ns.nowindows: - print('The --nowindows (-n) option is deprecated. ' - 'Use -vv to display assertions in stderr.') - try: - import msvcrt - except ImportError: - pass - else: - msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS| - msvcrt.SEM_NOALIGNMENTFAULTEXCEPT| - msvcrt.SEM_NOGPFAULTERRORBOX| - msvcrt.SEM_NOOPENFILEERRORBOX) - try: - msvcrt.CrtSetReportMode - except AttributeError: - # release build - pass - else: - for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]: - if ns.verbose and ns.verbose >= 2: - msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE) - msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR) - else: - msvcrt.CrtSetReportMode(m, 0) - if ns.wait: - input("Press any key to continue...") - if ns.slaveargs is not None: - args, kwargs = json.loads(ns.slaveargs) - if kwargs.get('huntrleaks'): + ns_dict, testname = json.loads(ns.slaveargs) + ns = types.SimpleNamespace(**ns_dict) + + setup_tests(ns) + + if ns.huntrleaks: unittest.BaseTestSuite._cleanup = False + try: - result = runtest(*args, **kwargs) + result = runtest(testname, ns.verbose, ns.quiet, + ns.huntrleaks, + output_on_failure=ns.verbose3, + timeout=ns.timeout, failfast=ns.failfast, + match_tests=ns.match_tests, pgo=ns.pgo, + use_resources=ns.use_resources) except KeyboardInterrupt: result = INTERRUPTED, '' except BaseException as e: traceback.print_exc() result = CHILD_ERROR, str(e) + sys.stdout.flush() print() # Force a newline (just in case) print(json.dumps(result)) sys.exit(0) + setup_tests(ns) + + if ns.wait: + input("Press any key to continue...") + good = [] bad = [] skipped = [] From ab4ea09604ea7754a80e4fc36280f5772bf4a8b2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 16 Jun 2017 00:14:45 +0200 Subject: [PATCH 288/340] bpo-30673: test.bat: add -t option (timeout) (#2211) (#2226) (cherry picked from commit 258bfc462b1e58689b43f662a10e44ece3a10bef) --- Tools/buildbot/test.bat | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index a2c47839deadab..2b94a000b857ca 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,11 +1,19 @@ @echo off -rem Used by the buildbot "test" step. +rem Script to run the Python test suite used by the "test" step +rem of Windows buildbot slaves. +rem +rem See PCbuild/rt.bat for options, extra options: +rem -t TIMEOUT: set a timeout in seconds + setlocal set here=%~dp0 set rt_opts=-q -d set regrtest_args= +rem Use a timeout of 60 minutes per test file by default +set timeout=3600 + :CheckOpts if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts @@ -13,7 +21,8 @@ if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts +if "%1"=="-t" (set timeout=%2) & shift & shift & goto CheckOpts if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts echo on -call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=3600 %regrtest_args% +call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=%timeout% %regrtest_args% From 3dc573c8d19dc42ed786ca3237afdad183c41ca0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 16 Jun 2017 00:51:24 +0200 Subject: [PATCH 289/340] Fix ref cycles in TestCase.assertRaises() (#193) (#2228) bpo-23890: unittest.TestCase.assertRaises() now manually breaks a reference cycle to not keep objects alive longer than expected. (cherry picked from commit bbd3cf8f1ef1e91a8d6dac6411e18b4b9084abf5) --- Lib/unittest/case.py | 52 ++++++++++++++++++++-------------- Lib/unittest/test/test_case.py | 13 +++++++++ Misc/NEWS | 3 ++ 3 files changed, 46 insertions(+), 22 deletions(-) diff --git a/Lib/unittest/case.py b/Lib/unittest/case.py index b523f73ff22784..f4dbc52852dc13 100644 --- a/Lib/unittest/case.py +++ b/Lib/unittest/case.py @@ -153,28 +153,32 @@ def handle(self, name, args, kwargs): If args is not empty, call a callable passing positional and keyword arguments. """ - if not _is_subtype(self.expected, self._base_type): - raise TypeError('%s() arg 1 must be %s' % - (name, self._base_type_str)) - if args and args[0] is None: - warnings.warn("callable is None", - DeprecationWarning, 3) - args = () - if not args: - self.msg = kwargs.pop('msg', None) - if kwargs: - warnings.warn('%r is an invalid keyword argument for ' - 'this function' % next(iter(kwargs)), - DeprecationWarning, 3) - return self - - callable_obj, *args = args try: - self.obj_name = callable_obj.__name__ - except AttributeError: - self.obj_name = str(callable_obj) - with self: - callable_obj(*args, **kwargs) + if not _is_subtype(self.expected, self._base_type): + raise TypeError('%s() arg 1 must be %s' % + (name, self._base_type_str)) + if args and args[0] is None: + warnings.warn("callable is None", + DeprecationWarning, 3) + args = () + if not args: + self.msg = kwargs.pop('msg', None) + if kwargs: + warnings.warn('%r is an invalid keyword argument for ' + 'this function' % next(iter(kwargs)), + DeprecationWarning, 3) + return self + + callable_obj, *args = args + try: + self.obj_name = callable_obj.__name__ + except AttributeError: + self.obj_name = str(callable_obj) + with self: + callable_obj(*args, **kwargs) + finally: + # bpo-23890: manually break a reference cycle + self = None class _AssertRaisesContext(_AssertRaisesBaseContext): @@ -725,7 +729,11 @@ def assertRaises(self, expected_exception, *args, **kwargs): self.assertEqual(the_exception.error_code, 3) """ context = _AssertRaisesContext(expected_exception, self) - return context.handle('assertRaises', args, kwargs) + try: + return context.handle('assertRaises', args, kwargs) + finally: + # bpo-23890: manually break a reference cycle + context = None def assertWarns(self, expected_warning, *args, **kwargs): """Fail unless a warning of class warnClass is triggered diff --git a/Lib/unittest/test/test_case.py b/Lib/unittest/test/test_case.py index 8f752b8ae0d0e2..b84959150542bd 100644 --- a/Lib/unittest/test/test_case.py +++ b/Lib/unittest/test/test_case.py @@ -1273,6 +1273,19 @@ def testAssertRaisesNoExceptionType(self): with self.assertRaises(TypeError): self.assertRaises((ValueError, object)) + def testAssertRaisesRefcount(self): + # bpo-23890: assertRaises() must not keep objects alive longer + # than expected + def func() : + try: + raise ValueError + except ValueError: + raise ValueError + + refcount = sys.getrefcount(func) + self.assertRaises(ValueError, func) + self.assertEqual(refcount, sys.getrefcount(func)) + def testAssertRaisesRegex(self): class ExceptionMock(Exception): pass diff --git a/Misc/NEWS b/Misc/NEWS index 8b62d792367aba..b6bab9be07d5ec 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -56,6 +56,9 @@ Extension Modules Library ------- +- bpo-23890: unittest.TestCase.assertRaises() now manually breaks a reference + cycle to not keep objects alive longer than expected. + - bpo-30149: inspect.signature() now supports callables with variable-argument parameters wrapped with partialmethod. Patch by Dong-hee Na. From 0b13f58497d3a36d062c3b3b827abb05db5afbc1 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 15 Jun 2017 18:49:54 -0700 Subject: [PATCH 290/340] bpo-30656: Fix Python C API Module Objects documentation (GH-2170) (GH-2231) `PyModule_New()` now refers to `PyModule_NewObject()` (cherry picked from commit 2d0afef82a07afdb666f2ca0c533aac5d39155cd) --- Doc/c-api/module.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/c-api/module.rst b/Doc/c-api/module.rst index 7724350d3c5f95..d3125b86f0729a 100644 --- a/Doc/c-api/module.rst +++ b/Doc/c-api/module.rst @@ -50,7 +50,7 @@ Module Objects .. c:function:: PyObject* PyModule_New(const char *name) - Similar to :c:func:`PyImport_NewObject`, but the name is a UTF-8 encoded + Similar to :c:func:`PyModule_NewObject`, but the name is a UTF-8 encoded string instead of a Unicode object. From 820b71464c2c0e8cca1abfb5dfe47fa7f7ffec75 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 15 Jun 2017 19:38:12 -0700 Subject: [PATCH 291/340] [email] bpo-29478: Fix passing max_line_length=None from Compat32 policy (GH-595) (GH-2234) If max_line_length=None is specified while using the Compat32 policy, it is no longer ignored.. (cherry picked from commit b459f7482612d340b88b62edc024628595ec6337) --- Lib/email/_policybase.py | 8 ++++++-- Lib/test/test_email/test_generator.py | 7 +++++++ Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py index c0d98a4f542935..7326d3a2b1671e 100644 --- a/Lib/email/_policybase.py +++ b/Lib/email/_policybase.py @@ -357,8 +357,12 @@ def _fold(self, name, value, sanitize): # Assume it is a Header-like object. h = value if h is not None: - parts.append(h.encode(linesep=self.linesep, - maxlinelen=self.max_line_length)) + # The Header class interprets a value of None for maxlinelen as the + # default value of 78, as recommended by RFC 2822. + maxlinelen = 0 + if self.max_line_length is not None: + maxlinelen = self.max_line_length + parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen)) parts.append(self.linesep) return ''.join(parts) diff --git a/Lib/test/test_email/test_generator.py b/Lib/test/test_email/test_generator.py index b1cbce26d5c1fb..226c5f98c4039c 100644 --- a/Lib/test/test_email/test_generator.py +++ b/Lib/test/test_email/test_generator.py @@ -162,6 +162,13 @@ def test_set_mangle_from_via_policy(self): g.flatten(msg) self.assertEqual(s.getvalue(), self.typ(expected)) + def test_compat32_max_line_length_does_not_fold_when_none(self): + msg = self.msgmaker(self.typ(self.refold_long_expected[0])) + s = self.ioclass() + g = self.genclass(s, policy=policy.compat32.clone(max_line_length=None)) + g.flatten(msg) + self.assertEqual(s.getvalue(), self.typ(self.refold_long_expected[0])) + class TestGenerator(TestGeneratorBase, TestEmailBase): diff --git a/Misc/ACKS b/Misc/ACKS index 1ed9e5bc98abf5..d728d43395b534 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -304,6 +304,7 @@ Garrett Cooper Greg Copeland Ian Cordasco Aldo Cortesi +Mircea Cosbuc David Costanzo Scott Cotton Greg Couch diff --git a/Misc/NEWS b/Misc/NEWS index b6bab9be07d5ec..9ed427de35449e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,9 @@ Core and Builtins - Issue #29337: Fixed possible BytesWarning when compare the code objects. Warnings could be emitted at compile time. +- bpo-29478: If max_line_length=None is specified while using the Compat32 policy, + it is no longer ignored. Patch by Mircea Cosbuc. + Extension Modules ----------------- From f50a3b1e7a74f3132d6b5e1afc793ace6de7e631 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 16 Jun 2017 14:38:50 +0200 Subject: [PATCH 292/340] Revert "bpo-30673: test.bat: add -t option (timeout) (#2211) (#2226)" (#2247) This reverts commit ab4ea09604ea7754a80e4fc36280f5772bf4a8b2. --- Tools/buildbot/test.bat | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/Tools/buildbot/test.bat b/Tools/buildbot/test.bat index 2b94a000b857ca..a2c47839deadab 100644 --- a/Tools/buildbot/test.bat +++ b/Tools/buildbot/test.bat @@ -1,19 +1,11 @@ @echo off -rem Script to run the Python test suite used by the "test" step -rem of Windows buildbot slaves. -rem -rem See PCbuild/rt.bat for options, extra options: -rem -t TIMEOUT: set a timeout in seconds - +rem Used by the buildbot "test" step. setlocal set here=%~dp0 set rt_opts=-q -d set regrtest_args= -rem Use a timeout of 60 minutes per test file by default -set timeout=3600 - :CheckOpts if "%1"=="-x64" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-d" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts @@ -21,8 +13,7 @@ if "%1"=="-O" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="-q" (set rt_opts=%rt_opts% %1) & shift & goto CheckOpts if "%1"=="+d" (set rt_opts=%rt_opts:-d=%) & shift & goto CheckOpts if "%1"=="+q" (set rt_opts=%rt_opts:-q=%) & shift & goto CheckOpts -if "%1"=="-t" (set timeout=%2) & shift & shift & goto CheckOpts if NOT "%1"=="" (set regrtest_args=%regrtest_args% %1) & shift & goto CheckOpts echo on -call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=%timeout% %regrtest_args% +call "%here%..\..\PCbuild\rt.bat" %rt_opts% -uall -rwW --timeout=3600 %regrtest_args% From 46e299c1536da541b9dbf76c0cb909bf8c79f589 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 16 Jun 2017 18:04:38 +0200 Subject: [PATCH 293/340] [3.5] bpo-30540, bpo-30523: Add --matchfile and --list-cases options to regrtest (#2250) * bpo-30540: regrtest: add --matchfile option * Add a new option taking a filename to get a list of test names to filter tests. * support.match_tests becomes a list. * Modify run_unittest() to accept to match the whole test identifier, not just a part of a test identifier. For example, the following command only runs test_access() of the FileTests class of test_os: $ ./python -m test -v -m test.test_os.FileTests.test_access test_os * bpo-30523: regrtest: Add --list-cases option * Add --list-cases option to regrtest * Add get_abs_module() function, use it in list_cases() * Add ns mandatory positional argument to runtest() and runtest_inner() * Add file optional parameter to printlist() Co-Authored-By: Louie Lu --- Lib/test/regrtest.py | 120 ++++++++++++++++++++++++++--------- Lib/test/support/__init__.py | 10 ++- Lib/test/test_regrtest.py | 17 ++++- 3 files changed, 113 insertions(+), 34 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index e5aa3e3f7dfbc0..214bf3000441ee 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -117,6 +117,13 @@ To enable all resources except one, use '-uall,-'. For example, to run all the tests except for the gui tests, give the option '-uall,-gui'. + +--matchfile filters tests using a text file, one pattern per line. +Pattern examples: + +- test method: test_stat_attributes +- test class: FileTests +- test identifier: test_os.FileTests.test_stat_attributes """ # We import importlib *ASAP* in order to test #15386 @@ -276,8 +283,12 @@ def _create_parser(): help='single step through a set of tests.' + more_details) group.add_argument('-m', '--match', metavar='PAT', - dest='match_tests', + dest='match_tests', action='append', help='match test cases and methods with glob pattern PAT') + group.add_argument('--matchfile', metavar='FILENAME', + dest='match_filename', + help='similar to --match but get patterns from a ' + 'text file, one pattern per line') group.add_argument('-G', '--failfast', action='store_true', help='fail as soon as a test fails (only with -v or -W)') group.add_argument('-u', '--use', metavar='RES1,RES2,...', @@ -323,6 +334,9 @@ def _create_parser(): group.add_argument('-F', '--forever', action='store_true', help='run the specified tests in a loop, until an ' 'error happens') + group.add_argument('--list-cases', action='store_true', + help='only write the name of test cases that will be run' + ' , don\'t execute them') group.add_argument('-P', '--pgo', dest='pgo', action='store_true', help='enable Profile Guided Optimization training') @@ -361,7 +375,8 @@ def _parse_args(args, **kwargs): findleaks=False, use_resources=None, trace=False, coverdir='coverage', runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, random_seed=None, use_mp=None, verbose3=False, forever=False, - header=False, failfast=False, match_tests=None, pgo=False) + header=False, failfast=False, match_tests=None, match_filename=None, + pgo=False) for k, v in kwargs.items(): if not hasattr(ns, k): raise TypeError('%r is an invalid keyword argument ' @@ -431,6 +446,13 @@ def _parse_args(args, **kwargs): print("WARNING: Disable --verbose3 because it's incompatible with " "--huntrleaks: see http://bugs.python.org/issue27103", file=sys.stderr) + if ns.match_filename: + if ns.match_tests is None: + ns.match_tests = [] + filename = os.path.join(support.SAVEDCWD, ns.match_filename) + with open(filename) as fp: + for line in fp: + ns.match_tests.append(line.strip()) return ns @@ -555,7 +577,7 @@ def main(tests=None, **kwargs): unittest.BaseTestSuite._cleanup = False try: - result = runtest(testname, ns.verbose, ns.quiet, + result = runtest(ns, testname, ns.verbose, ns.quiet, ns.huntrleaks, output_on_failure=ns.verbose3, timeout=ns.timeout, failfast=ns.failfast, @@ -632,18 +654,6 @@ def main(tests=None, **kwargs): nottests.add(arg) ns.args = [] - # For a partial run, we do not need to clutter the output. - if (ns.verbose or ns.header or - not (ns.pgo or ns.quiet or ns.single or tests or ns.args)): - # Print basic platform information - print("==", platform.python_implementation(), *sys.version.split()) - print("== ", platform.platform(aliased=True), - "%s-endian" % sys.byteorder) - print("== ", "hash algorithm:", sys.hash_info.algorithm, - "64bit" if sys.maxsize > 2**32 else "32bit") - print("== ", os.getcwd()) - print("Testing with flags:", sys.flags) - # if testdir is set, then we are not running the python tests suite, so # don't add default tests to be executed or skipped (pass empty values) if ns.testdir: @@ -697,6 +707,10 @@ def accumulate_result(test, result): skipped.append(test) resource_denieds.append(test) + if ns.list_cases: + list_cases(ns, selected) + sys.exit(0) + if ns.forever: def test_forever(tests=list(selected)): while True: @@ -712,6 +726,18 @@ def test_forever(tests=list(selected)): test_count = '/{}'.format(len(selected)) test_count_width = len(test_count) - 1 + # For a partial run, we do not need to clutter the output. + if (ns.verbose or ns.header or + not (ns.pgo or ns.quiet or ns.single or tests or ns.args)): + # Print basic platform information + print("==", platform.python_implementation(), *sys.version.split()) + print("== ", platform.platform(aliased=True), + "%s-endian" % sys.byteorder) + print("== ", "hash algorithm:", sys.hash_info.algorithm, + "64bit" if sys.maxsize > 2**32 else "32bit") + print("== ", os.getcwd()) + print("Testing with flags:", sys.flags) + if ns.use_mp: try: from threading import Thread @@ -797,11 +823,11 @@ def work(): if ns.trace: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. - tracer.runctx('runtest(test, ns.verbose, ns.quiet, timeout=ns.timeout)', + tracer.runctx('runtest(ns, test, ns.verbose, ns.quiet, timeout=ns.timeout)', globals=globals(), locals=vars()) else: try: - result = runtest(test, ns.verbose, ns.quiet, + result = runtest(ns, test, ns.verbose, ns.quiet, ns.huntrleaks, output_on_failure=ns.verbose3, timeout=ns.timeout, failfast=ns.failfast, @@ -859,7 +885,7 @@ def work(): sys.stdout.flush() try: ns.verbose = True - ok = runtest(test, True, ns.quiet, ns.huntrleaks, + ok = runtest(ns, test, True, ns.quiet, ns.huntrleaks, timeout=ns.timeout, pgo=ns.pgo) except KeyboardInterrupt: # print a newline separate from the ^C @@ -956,7 +982,7 @@ def restore_stdout(): sys.stdout = stdout atexit.register(restore_stdout) -def runtest(test, verbose, quiet, +def runtest(ns, test, verbose, quiet, huntrleaks=False, use_resources=None, output_on_failure=False, failfast=False, match_tests=None, timeout=None, *, pgo=False): @@ -1011,8 +1037,9 @@ def runtest(test, verbose, quiet, try: sys.stdout = stream sys.stderr = stream - result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=False, pgo=pgo) + result = runtest_inner(ns, test, verbose, quiet, huntrleaks, + display_failure=False, + pgo=pgo) if result[0] != PASSED and not pgo: output = stream.getvalue() orig_stderr.write(output) @@ -1022,8 +1049,9 @@ def runtest(test, verbose, quiet, sys.stderr = orig_stderr else: support.verbose = verbose # Tell tests to be moderately quiet - result = runtest_inner(test, verbose, quiet, huntrleaks, - display_failure=not verbose, pgo=pgo) + result = runtest_inner(ns, test, verbose, quiet, huntrleaks, + display_failure=not verbose, + pgo=pgo) return result finally: if use_timeout: @@ -1294,18 +1322,14 @@ def __exit__(self, exc_type, exc_val, exc_tb): return False -def runtest_inner(test, verbose, quiet, +def runtest_inner(ns, test, verbose, quiet, huntrleaks=False, display_failure=True, pgo=False): support.unload(test) test_time = 0.0 refleak = False # True if the test leaked references. try: - if test.startswith('test.'): - abstest = test - else: - # Always import it from the test package - abstest = 'test.' + test + abstest = get_abs_module(ns, test) clear_caches() with saved_test_environment(test, verbose, quiet, pgo=pgo) as environment: start_time = time.time() @@ -1646,7 +1670,7 @@ def count(n, word): else: return "%d %ss" % (n, word) -def printlist(x, width=70, indent=4): +def printlist(x, width=70, indent=4, file=None): """Print the elements of iterable x to stdout. Optional arg width (default 70) is the maximum line length. @@ -1658,7 +1682,41 @@ def printlist(x, width=70, indent=4): blanks = ' ' * indent # Print the sorted list: 'x' may be a '--random' list or a set() print(fill(' '.join(str(elt) for elt in sorted(x)), width, - initial_indent=blanks, subsequent_indent=blanks)) + initial_indent=blanks, subsequent_indent=blanks), file=file) + + +def get_abs_module(ns, test): + if test.startswith('test.') or ns.testdir: + return test + else: + # Always import it from the test package + return 'test.' + test + + +def _list_cases(suite): + for test in suite: + if isinstance(test, unittest.loader._FailedTest): + continue + if isinstance(test, unittest.TestSuite): + _list_cases(test) + elif isinstance(test, unittest.TestCase): + print(test.id()) + + +def list_cases(ns, selected): + skipped = [] + for test in selected: + abstest = get_abs_module(ns, test) + try: + suite = unittest.defaultTestLoader.loadTestsFromName(abstest) + _list_cases(suite) + except unittest.SkipTest: + skipped.append(test) + + if skipped: + print(file=sys.stderr) + print(count(len(skipped), "test"), "skipped:", file=sys.stderr) + printlist(skipped, file=sys.stderr) def main_in_temp_cwd(): diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index a9f8fd5b3d7449..92599b31e208fd 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1883,9 +1883,15 @@ def run_unittest(*classes): def case_pred(test): if match_tests is None: return True - for name in test.id().split("."): - if fnmatch.fnmatchcase(name, match_tests): + test_id = test.id() + + for match_test in match_tests: + if fnmatch.fnmatchcase(test_id, match_test): return True + + for name in test_id.split("."): + if fnmatch.fnmatchcase(name, match_test): + return True return False _filter_suite(suite, case_pred) _run_suite(suite) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index e2c2f2da869272..98dca01e2370a5 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -129,9 +129,24 @@ def test_match(self): for opt in '-m', '--match': with self.subTest(opt=opt): ns = regrtest._parse_args([opt, 'pattern']) - self.assertEqual(ns.match_tests, 'pattern') + self.assertEqual(ns.match_tests, ['pattern']) self.checkError([opt], 'expected one argument') + ns = regrtest._parse_args(['-m', 'pattern1', + '-m', 'pattern2']) + self.assertEqual(ns.match_tests, ['pattern1', 'pattern2']) + + self.addCleanup(support.unlink, support.TESTFN) + with open(support.TESTFN, "w") as fp: + print('matchfile1', file=fp) + print('matchfile2', file=fp) + + filename = os.path.abspath(support.TESTFN) + ns = regrtest._parse_args(['-m', 'match', + '--matchfile', filename]) + self.assertEqual(ns.match_tests, + ['match', 'matchfile1', 'matchfile2']) + def test_failfast(self): for opt in '-G', '--failfast': with self.subTest(opt=opt): From 04521c275e47e4df59046ee0297810f06c208350 Mon Sep 17 00:00:00 2001 From: Xiang Zhang Date: Mon, 19 Jun 2017 22:06:59 +0800 Subject: [PATCH 294/340] bpo-30176: Add missing curses cell attributes constants (#2277) --- Doc/library/curses.rst | 54 +++++++++++++++++++++++++++++++++++------- Misc/NEWS | 2 ++ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/Doc/library/curses.rst b/Doc/library/curses.rst index 3442e4e75a3e45..668d2826b0a1b3 100644 --- a/Doc/library/curses.rst +++ b/Doc/library/curses.rst @@ -1271,27 +1271,63 @@ The :mod:`curses` module defines the following data members: A string representing the current version of the module. Also available as :const:`__version__`. -Several constants are available to specify character cell attributes: +Some constants are available to specify character cell attributes. +The exact constants available are system dependent. +------------------+-------------------------------+ | Attribute | Meaning | +==================+===============================+ -| ``A_ALTCHARSET`` | Alternate character set mode. | +| ``A_ALTCHARSET`` | Alternate character set mode | +------------------+-------------------------------+ -| ``A_BLINK`` | Blink mode. | +| ``A_BLINK`` | Blink mode | +------------------+-------------------------------+ -| ``A_BOLD`` | Bold mode. | +| ``A_BOLD`` | Bold mode | +------------------+-------------------------------+ -| ``A_DIM`` | Dim mode. | +| ``A_DIM`` | Dim mode | +------------------+-------------------------------+ -| ``A_NORMAL`` | Normal attribute. | +| ``A_INVIS`` | Invisible or blank mode | ++------------------+-------------------------------+ +| ``A_NORMAL`` | Normal attribute | ++------------------+-------------------------------+ +| ``A_PROTECT`` | Protected mode | +------------------+-------------------------------+ | ``A_REVERSE`` | Reverse background and | -| | foreground colors. | +| | foreground colors | ++------------------+-------------------------------+ +| ``A_STANDOUT`` | Standout mode | ++------------------+-------------------------------+ +| ``A_UNDERLINE`` | Underline mode | ++------------------+-------------------------------+ +| ``A_HORIZONTAL`` | Horizontal highlight | ++------------------+-------------------------------+ +| ``A_LEFT`` | Left highlight | ++------------------+-------------------------------+ +| ``A_LOW`` | Low highlight | ++------------------+-------------------------------+ +| ``A_RIGHT`` | Right highlight | ++------------------+-------------------------------+ +| ``A_TOP`` | Top highlight | ++------------------+-------------------------------+ +| ``A_VERTICAL`` | Vertical highlight | ++------------------+-------------------------------+ +| ``A_CHARTEXT`` | Bit-mask to extract a | +| | character | ++------------------+-------------------------------+ + +Several constants are available to extract corresponding attributes returned +by some methods. + ++------------------+-------------------------------+ +| Bit-mask | Meaning | ++==================+===============================+ +| ``A_ATTRIBUTES`` | Bit-mask to extract | +| | attributes | +------------------+-------------------------------+ -| ``A_STANDOUT`` | Standout mode. | +| ``A_CHARTEXT`` | Bit-mask to extract a | +| | character | +------------------+-------------------------------+ -| ``A_UNDERLINE`` | Underline mode. | +| ``A_COLOR`` | Bit-mask to extract | +| | color-pair field information | +------------------+-------------------------------+ Keys are referred to by integer constants with names starting with ``KEY_``. diff --git a/Misc/NEWS b/Misc/NEWS index 9ed427de35449e..f985f5a7687a02 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -270,6 +270,8 @@ C API Documentation ------------- +- bpo-30176: Add missing attribute related constants in curses documentation. + - bpo-26985: Add missing info of code object in inspect documentation. - bpo-28929: Link the documentation to its source file on GitHub. From a601fcca3bf2061e43d4d2710a730536cf26327b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 19 Jun 2017 18:33:21 +0200 Subject: [PATCH 295/340] [3.5] bpo-30383: Backport regrtest and test_regrtest enhancements from master to 3.5 (#2279) * bpo-30383: regrtest: prepend testdir to sys.path * bpo-30383: Backport test_regrtest * regrtest: rename --slow option to --slowest The old --slow syntax is still accepted. * regrtest: add a single oneliner summary Example: "Tests result: SUCCESS" * test_regrtest: add test_coverage() regrtest now also displays the number of successful tests when coverage is used. * test_regrtest: add test_crashed() Handle correctly crashing test: account the crash has a failed test, but continue to run other tests. * regrtest: backport --list-tests feature * regrtest: backport --fromfile enhancements * regrtest: backport displaying progress enhancements * test_regrtest: backport test_randseed() * regrtest: Fix --coverage on Windows Don't ignore any directory anymore. Change backported from master. --- Lib/test/regrtest.py | 111 +++++--- Lib/test/test_regrtest.py | 569 +++++++++++++++++++++++++++++++++++++- 2 files changed, 636 insertions(+), 44 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 214bf3000441ee..299416cf24c8d4 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -131,6 +131,7 @@ import argparse import builtins +import datetime import faulthandler import io import json @@ -262,7 +263,7 @@ def _create_parser(): help='display test output on failure') group.add_argument('-q', '--quiet', action='store_true', help='no output unless one or more tests fail') - group.add_argument('-o', '--slow', action='store_true', dest='print_slow', + group.add_argument('-o', '--slowest', action='store_true', dest='print_slow', help='print the slowest 10 tests') group.add_argument('--header', action='store_true', help='print header with interpreter info') @@ -334,6 +335,9 @@ def _create_parser(): group.add_argument('-F', '--forever', action='store_true', help='run the specified tests in a loop, until an ' 'error happens') + group.add_argument('--list-tests', action='store_true', + help="only write the name of tests that will be run, " + "don't execute them") group.add_argument('--list-cases', action='store_true', help='only write the name of test cases that will be run' ' , don\'t execute them') @@ -490,6 +494,10 @@ def run_test_in_subprocess(testname, ns): def setup_tests(ns): + if ns.testdir: + # Prepend test directory to sys.path, so runtest() will be able + # to locate tests + sys.path.insert(0, os.path.abspath(ns.testdir)) if ns.huntrleaks: # Avoid false positives due to various caches # filling slowly with random data: @@ -549,6 +557,8 @@ def main(tests=None, **kwargs): directly to set the values that would normally be set by flags on the command line. """ + start_time = time.monotonic() + # Display the Python traceback on fatal errors (e.g. segfault) faulthandler.enable(all_threads=True) @@ -634,12 +644,15 @@ def main(tests=None, **kwargs): if ns.fromfile: tests = [] with open(os.path.join(support.SAVEDCWD, ns.fromfile)) as fp: - count_pat = re.compile(r'\[\s*\d+/\s*\d+\]') + # regex to match 'test_builtin' in line: + # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec' + regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b') for line in fp: - line = count_pat.sub('', line) - guts = line.split() # assuming no test has whitespace in its name - if guts and not guts[0].startswith('#'): - tests.extend(guts) + line = line.split('#', 1)[0] + line = line.strip() + match = regex.search(line) + if match is not None: + tests.append(match.group()) # Strip .py extensions. removepy(ns.args) @@ -682,9 +695,7 @@ def main(tests=None, **kwargs): random.shuffle(selected) if ns.trace: import trace, tempfile - tracer = trace.Trace(ignoredirs=[sys.base_prefix, sys.base_exec_prefix, - tempfile.gettempdir()], - trace=False, count=True) + tracer = trace.Trace(trace=False, count=True) test_times = [] support.verbose = ns.verbose # Tell tests to be moderately quiet @@ -697,7 +708,7 @@ def accumulate_result(test, result): test_times.append((test_time, test)) if ok == PASSED: good.append(test) - elif ok == FAILED: + elif ok in (FAILED, CHILD_ERROR): bad.append(test) elif ok == ENV_CHANGED: environment_changed.append(test) @@ -706,6 +717,13 @@ def accumulate_result(test, result): elif ok == RESOURCE_DENIED: skipped.append(test) resource_denieds.append(test) + elif ok != INTERRUPTED: + raise ValueError("invalid test result: %r" % ok) + + if ns.list_tests: + for name in selected: + print(name) + sys.exit(0) if ns.list_cases: list_cases(ns, selected) @@ -738,6 +756,27 @@ def test_forever(tests=list(selected)): print("== ", os.getcwd()) print("Testing with flags:", sys.flags) + def display_progress(test_index, test): + if ns.quiet: + return + + # "[ 51/405/1] test_tcl passed" + line = "{0:{1}}{2}".format(test_index, test_count_width, test_count) + if bad and not ns.pgo: + line = "{0}/{1}".format(line, len(bad)) + line = "[{0}] {1}".format(line, test) + + # add the system load prefix: "load avg: 1.80 " + if hasattr(os, 'getloadavg'): + load_avg_1min = os.getloadavg()[0] + line = "load avg: {0:.2f} {1}".format(load_avg_1min, line) + + # add the timestamp prefix: "0:01:05 " + test_time = time.monotonic() - start_time + test_time = datetime.timedelta(seconds=int(test_time)) + line = "{0} {1}".format(test_time, line) + print(line, flush=True) + if ns.use_mp: try: from threading import Thread @@ -765,7 +804,7 @@ def work(): if retcode != 0: result = (CHILD_ERROR, "Exit code %s" % retcode) output.put((test, stdout.rstrip(), stderr.rstrip(), result)) - return + continue if not result: output.put((None, None, None, None)) return @@ -786,14 +825,7 @@ def work(): finished += 1 continue accumulate_result(test, result) - if not ns.quiet: - if bad and not ns.pgo: - fmt = "[{1:{0}}{2}/{3}] {4}" - else: - fmt = "[{1:{0}}{2}] {4}" - print(fmt.format( - test_count_width, test_index, test_count, - len(bad), test)) + display_progress(test_index, test) if stdout: print(stdout) if stderr and not ns.pgo: @@ -802,8 +834,6 @@ def work(): sys.stderr.flush() if result[0] == INTERRUPTED: raise KeyboardInterrupt - if result[0] == CHILD_ERROR: - raise Exception("Child error on {}: {}".format(test, result[1])) test_index += 1 except KeyboardInterrupt: interrupted = True @@ -812,27 +842,24 @@ def work(): worker.join() else: for test_index, test in enumerate(tests, 1): - if not ns.quiet: - if bad and not ns.pgo: - fmt = "[{1:{0}}{2}/{3}] {4}" - else: - fmt = "[{1:{0}}{2}] {4}" - print(fmt.format( - test_count_width, test_index, test_count, len(bad), test)) - sys.stdout.flush() + display_progress(test_index, test) + + def runtest_accumulate(): + result = runtest(ns, test, ns.verbose, ns.quiet, + ns.huntrleaks, + output_on_failure=ns.verbose3, + timeout=ns.timeout, failfast=ns.failfast, + match_tests=ns.match_tests, pgo=ns.pgo) + accumulate_result(test, result) + if ns.trace: # If we're tracing code coverage, then we don't exit with status # if on a false return value from main. - tracer.runctx('runtest(ns, test, ns.verbose, ns.quiet, timeout=ns.timeout)', + tracer.runctx('runtest_accumulate()', globals=globals(), locals=vars()) else: try: - result = runtest(ns, test, ns.verbose, ns.quiet, - ns.huntrleaks, - output_on_failure=ns.verbose3, - timeout=ns.timeout, failfast=ns.failfast, - match_tests=ns.match_tests, pgo=ns.pgo) - accumulate_result(test, result) + runtest_accumulate() except KeyboardInterrupt: interrupted = True break @@ -864,8 +891,8 @@ def work(): if ns.print_slow: test_times.sort(reverse=True) print("10 slowest tests:") - for time, test in test_times[:10]: - print("%s: %.1fs" % (test, time)) + for test_time, test in test_times[:10]: + print("- %s: %.1fs" % (test, test_time)) if bad and not ns.pgo: print(count(len(bad), "test"), "failed:") printlist(bad) @@ -913,6 +940,14 @@ def work(): if ns.runleaks: os.system("leaks %d" % os.getpid()) + if bad: + result = "FAILURE" + elif interrupted: + result = "INTERRUPTED" + else: + result = "SUCCESS" + print("Tests result: %s" % result) + sys.exit(len(bad) > 0 or interrupted) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 98dca01e2370a5..3568004b176b17 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -1,13 +1,37 @@ """ Tests of regrtest.py. + +Note: test_regrtest cannot be run twice in parallel. """ -import argparse import faulthandler -import getopt import os.path +import platform +import re +import subprocess +import sys +import sysconfig +import tempfile +import textwrap import unittest -from test import regrtest, support +from test import regrtest +from test import support + + +Py_DEBUG = hasattr(sys, 'getobjects') +ROOT_DIR = os.path.join(os.path.dirname(__file__), '..', '..') +ROOT_DIR = os.path.abspath(os.path.normpath(ROOT_DIR)) + +TEST_INTERRUPTED = textwrap.dedent(""" + from signal import SIGINT + try: + from _testcapi import raise_signal + raise_signal(SIGINT) + except ImportError: + import os + os.kill(os.getpid(), SIGINT) + """) + class ParseArgsTestCase(unittest.TestCase): @@ -82,7 +106,7 @@ def test_quiet(self): self.assertEqual(ns.verbose, 0) def test_slow(self): - for opt in '-o', '--slow': + for opt in '-o', '--slowest': with self.subTest(opt=opt): ns = regrtest._parse_args([opt]) self.assertTrue(ns.print_slow) @@ -98,7 +122,7 @@ def test_randomize(self): self.assertTrue(ns.randomize) def test_randseed(self): - ns = regrtest._parse_args(['--randseed', '12345']) + ns = libregrtest._parse_args(['--randseed', '12345']) self.assertEqual(ns.random_seed, 12345) self.assertTrue(ns.randomize) self.checkError(['--randseed'], 'expected one argument') @@ -112,6 +136,13 @@ def test_fromfile(self): self.checkError([opt], 'expected one argument') self.checkError([opt, 'foo', '-s'], "don't go together") + def test_randseed(self): + ns = regrtest._parse_args(['--randseed', '12345']) + self.assertEqual(ns.random_seed, 12345) + self.assertTrue(ns.randomize) + self.checkError(['--randseed'], 'expected one argument') + self.checkError(['--randseed', 'foo'], 'invalid int value') + def test_exclude(self): for opt in '-x', '--exclude': with self.subTest(opt=opt): @@ -259,7 +290,6 @@ def test_forever(self): ns = regrtest._parse_args([opt]) self.assertTrue(ns.forever) - def test_unrecognized_argument(self): self.checkError(['--xxx'], 'usage:') @@ -298,6 +328,533 @@ def test_unknown_option(self): 'unrecognized arguments: --unknown-option') +class BaseTestCase(unittest.TestCase): + TEST_UNIQUE_ID = 1 + TESTNAME_PREFIX = 'test_regrtest_' + TESTNAME_REGEX = r'test_[a-zA-Z0-9_]+' + + def setUp(self): + self.testdir = os.path.realpath(os.path.dirname(__file__)) + + self.tmptestdir = tempfile.mkdtemp() + self.addCleanup(support.rmtree, self.tmptestdir) + + def create_test(self, name=None, code=''): + if not name: + name = 'noop%s' % BaseTestCase.TEST_UNIQUE_ID + BaseTestCase.TEST_UNIQUE_ID += 1 + + # test_regrtest cannot be run twice in parallel because + # of setUp() and create_test() + name = self.TESTNAME_PREFIX + name + path = os.path.join(self.tmptestdir, name + '.py') + + self.addCleanup(support.unlink, path) + # Use 'x' mode to ensure that we do not override existing tests + try: + with open(path, 'x', encoding='utf-8') as fp: + fp.write(code) + except PermissionError as exc: + if not sysconfig.is_python_build(): + self.skipTest("cannot write %s: %s" % (path, exc)) + raise + return name + + def regex_search(self, regex, output): + match = re.search(regex, output, re.MULTILINE) + if not match: + self.fail("%r not found in %r" % (regex, output)) + return match + + def check_line(self, output, regex): + regex = re.compile(r'^' + regex, re.MULTILINE) + self.assertRegex(output, regex) + + def parse_executed_tests(self, output): + regex = (r'^[0-9]+:[0-9]+:[0-9]+ (?:load avg: [0-9]+\.[0-9]{2} )?\[ *[0-9]+(?:/ *[0-9]+)*\] (%s)' + % self.TESTNAME_REGEX) + parser = re.finditer(regex, output, re.MULTILINE) + return list(match.group(1) for match in parser) + + def check_executed_tests(self, output, tests, skipped=(), failed=(), + omitted=(), randomize=False, interrupted=False): + if isinstance(tests, str): + tests = [tests] + if isinstance(skipped, str): + skipped = [skipped] + if isinstance(failed, str): + failed = [failed] + if isinstance(omitted, str): + omitted = [omitted] + ntest = len(tests) + nskipped = len(skipped) + nfailed = len(failed) + nomitted = len(omitted) + + executed = self.parse_executed_tests(output) + if randomize: + self.assertEqual(set(executed), set(tests), output) + else: + self.assertEqual(executed, tests, output) + + def plural(count): + return 's' if count != 1 else '' + + def list_regex(line_format, tests): + count = len(tests) + names = ' '.join(sorted(tests)) + regex = line_format % (count, plural(count)) + regex = r'%s:\n %s$' % (regex, names) + return regex + + if skipped: + regex = list_regex('%s test%s skipped', skipped) + self.check_line(output, regex) + + if failed: + regex = list_regex('%s test%s failed', failed) + self.check_line(output, regex) + + if omitted: + regex = list_regex('%s test%s omitted', omitted) + self.check_line(output, regex) + + good = ntest - nskipped - nfailed - nomitted + if good: + regex = r'%s test%s OK\.$' % (good, plural(good)) + if not skipped and not failed and good > 1: + regex = 'All %s' % regex + self.check_line(output, regex) + + if interrupted: + self.check_line(output, 'Test suite interrupted by signal SIGINT.') + + if nfailed: + result = 'FAILURE' + elif interrupted: + result = 'INTERRUPTED' + else: + result = 'SUCCESS' + self.check_line(output, 'Tests result: %s' % result) + + def parse_random_seed(self, output): + match = self.regex_search(r'Using random seed ([0-9]+)', output) + randseed = int(match.group(1)) + self.assertTrue(0 <= randseed <= 10000000, randseed) + return randseed + + def run_command(self, args, input=None, exitcode=0, **kw): + if not input: + input = '' + if 'stderr' not in kw: + kw['stderr'] = subprocess.PIPE + proc = subprocess.run(args, + universal_newlines=True, + input=input, + stdout=subprocess.PIPE, + **kw) + if proc.returncode != exitcode: + msg = ("Command %s failed with exit code %s\n" + "\n" + "stdout:\n" + "---\n" + "%s\n" + "---\n" + % (str(args), proc.returncode, proc.stdout)) + if proc.stderr: + msg += ("\n" + "stderr:\n" + "---\n" + "%s" + "---\n" + % proc.stderr) + self.fail(msg) + return proc + + def run_python(self, args, **kw): + args = [sys.executable, '-X', 'faulthandler', '-I', *args] + proc = self.run_command(args, **kw) + return proc.stdout + + +class ProgramsTestCase(BaseTestCase): + """ + Test various ways to run the Python test suite. Use options close + to options used on the buildbot. + """ + + NTEST = 4 + + def setUp(self): + super().setUp() + + # Create NTEST tests doing nothing + self.tests = [self.create_test() for index in range(self.NTEST)] + + self.python_args = ['-Wd', '-E', '-bb'] + self.regrtest_args = ['-uall', '-rwW', + '--testdir=%s' % self.tmptestdir] + if hasattr(faulthandler, 'dump_traceback_later'): + self.regrtest_args.extend(('--timeout', '3600', '-j4')) + if sys.platform == 'win32': + self.regrtest_args.append('-n') + + def check_output(self, output): + self.parse_random_seed(output) + self.check_executed_tests(output, self.tests, randomize=True) + + def run_tests(self, args): + output = self.run_python(args) + self.check_output(output) + + def test_script_regrtest(self): + # Lib/test/regrtest.py + script = os.path.join(self.testdir, 'regrtest.py') + + args = [*self.python_args, script, *self.regrtest_args, *self.tests] + self.run_tests(args) + + def test_module_test(self): + # -m test + args = [*self.python_args, '-m', 'test', + *self.regrtest_args, *self.tests] + self.run_tests(args) + + def test_module_regrtest(self): + # -m test.regrtest + args = [*self.python_args, '-m', 'test.regrtest', + *self.regrtest_args, *self.tests] + self.run_tests(args) + + def test_module_autotest(self): + # -m test.autotest + args = [*self.python_args, '-m', 'test.autotest', + *self.regrtest_args, *self.tests] + self.run_tests(args) + + def test_module_from_test_autotest(self): + # from test import autotest + code = 'from test import autotest' + args = [*self.python_args, '-c', code, + *self.regrtest_args, *self.tests] + self.run_tests(args) + + def test_script_autotest(self): + # Lib/test/autotest.py + script = os.path.join(self.testdir, 'autotest.py') + args = [*self.python_args, script, *self.regrtest_args, *self.tests] + self.run_tests(args) + + @unittest.skipUnless(sysconfig.is_python_build(), + 'run_tests.py script is not installed') + def test_tools_script_run_tests(self): + # Tools/scripts/run_tests.py + script = os.path.join(ROOT_DIR, 'Tools', 'scripts', 'run_tests.py') + args = [script, *self.regrtest_args, *self.tests] + self.run_tests(args) + + def run_batch(self, *args): + proc = self.run_command(args) + self.check_output(proc.stdout) + + @unittest.skipUnless(sysconfig.is_python_build(), + 'test.bat script is not installed') + @unittest.skipUnless(sys.platform == 'win32', 'Windows only') + def test_tools_buildbot_test(self): + # Tools\buildbot\test.bat + script = os.path.join(ROOT_DIR, 'Tools', 'buildbot', 'test.bat') + test_args = ['--testdir=%s' % self.tmptestdir] + if platform.architecture()[0] == '64bit': + test_args.append('-x64') # 64-bit build + if not Py_DEBUG: + test_args.append('+d') # Release build, use python.exe + self.run_batch(script, *test_args, *self.tests) + + @unittest.skipUnless(sys.platform == 'win32', 'Windows only') + def test_pcbuild_rt(self): + # PCbuild\rt.bat + script = os.path.join(ROOT_DIR, r'PCbuild\rt.bat') + rt_args = ["-q"] # Quick, don't run tests twice + if platform.architecture()[0] == '64bit': + rt_args.append('-x64') # 64-bit build + if Py_DEBUG: + rt_args.append('-d') # Debug build, use python_d.exe + self.run_batch(script, *rt_args, *self.regrtest_args, *self.tests) + + +class ArgsTestCase(BaseTestCase): + """ + Test arguments of the Python test suite. + """ + + def run_tests(self, *testargs, **kw): + cmdargs = ['-m', 'test', '--testdir=%s' % self.tmptestdir, *testargs] + return self.run_python(cmdargs, **kw) + + def test_failing_test(self): + # test a failing test + code = textwrap.dedent(""" + import unittest + + class FailingTest(unittest.TestCase): + def test_failing(self): + self.fail("bug") + """) + test_ok = self.create_test('ok') + test_failing = self.create_test('failing', code=code) + tests = [test_ok, test_failing] + + output = self.run_tests(*tests, exitcode=1) + self.check_executed_tests(output, tests, failed=test_failing) + + def test_resources(self): + # test -u command line option + tests = {} + for resource in ('audio', 'network'): + code = 'from test import support\nsupport.requires(%r)' % resource + tests[resource] = self.create_test(resource, code) + test_names = sorted(tests.values()) + + # -u all: 2 resources enabled + output = self.run_tests('-u', 'all', *test_names) + self.check_executed_tests(output, test_names) + + # -u audio: 1 resource enabled + output = self.run_tests('-uaudio', *test_names) + self.check_executed_tests(output, test_names, + skipped=tests['network']) + + # no option: 0 resources enabled + output = self.run_tests(*test_names) + self.check_executed_tests(output, test_names, + skipped=test_names) + + def test_random(self): + # test -r and --randseed command line option + code = textwrap.dedent(""" + import random + print("TESTRANDOM: %s" % random.randint(1, 1000)) + """) + test = self.create_test('random', code) + + # first run to get the output with the random seed + output = self.run_tests('-r', test) + randseed = self.parse_random_seed(output) + match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) + test_random = int(match.group(1)) + + # try to reproduce with the random seed + output = self.run_tests('-r', '--randseed=%s' % randseed, test) + randseed2 = self.parse_random_seed(output) + self.assertEqual(randseed2, randseed) + + match = self.regex_search(r'TESTRANDOM: ([0-9]+)', output) + test_random2 = int(match.group(1)) + self.assertEqual(test_random2, test_random) + + def test_fromfile(self): + # test --fromfile + tests = [self.create_test() for index in range(5)] + + # Write the list of files using a format similar to regrtest output: + # [1/2] test_1 + # [2/2] test_2 + filename = support.TESTFN + self.addCleanup(support.unlink, filename) + + # test format '0:00:00 [2/7] test_opcodes -- test_grammar took 0 sec' + with open(filename, "w") as fp: + previous = None + for index, name in enumerate(tests, 1): + line = ("00:00:%02i [%s/%s] %s" + % (index, index, len(tests), name)) + if previous: + line += " -- %s took 0 sec" % previous + print(line, file=fp) + previous = name + + output = self.run_tests('--fromfile', filename) + self.check_executed_tests(output, tests) + + # test format '[2/7] test_opcodes' + with open(filename, "w") as fp: + for index, name in enumerate(tests, 1): + print("[%s/%s] %s" % (index, len(tests), name), file=fp) + + output = self.run_tests('--fromfile', filename) + self.check_executed_tests(output, tests) + + # test format 'test_opcodes' + with open(filename, "w") as fp: + for name in tests: + print(name, file=fp) + + output = self.run_tests('--fromfile', filename) + self.check_executed_tests(output, tests) + + # test format 'Lib/test/test_opcodes.py' + with open(filename, "w") as fp: + for name in tests: + print('Lib/test/%s.py' % name, file=fp) + + output = self.run_tests('--fromfile', filename) + self.check_executed_tests(output, tests) + + def test_interrupted(self): + code = TEST_INTERRUPTED + test = self.create_test('sigint', code=code) + output = self.run_tests(test, exitcode=1) + self.check_executed_tests(output, test, omitted=test, + interrupted=True) + + def test_slowest(self): + # test --slowest + tests = [self.create_test() for index in range(3)] + output = self.run_tests("--slowest", *tests) + self.check_executed_tests(output, tests) + regex = ('10 slowest tests:\n' + '(?:- %s: .*\n){%s}' + % (self.TESTNAME_REGEX, len(tests))) + self.check_line(output, regex) + + def test_slow_interrupted(self): + # Issue #25373: test --slowest with an interrupted test + code = TEST_INTERRUPTED + test = self.create_test("sigint", code=code) + + try: + import threading + tests = (False, True) + except ImportError: + tests = (False,) + for multiprocessing in tests: + if multiprocessing: + args = ("--slowest", "-j2", test) + else: + args = ("--slowest", test) + output = self.run_tests(*args, exitcode=1) + self.check_executed_tests(output, test, + omitted=test, interrupted=True) + + regex = ('10 slowest tests:\n') + self.check_line(output, regex) + + def test_coverage(self): + # test --coverage + test = self.create_test('coverage') + output = self.run_tests("--coverage", test) + self.check_executed_tests(output, [test]) + regex = (r'lines +cov% +module +\(path\)\n' + r'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+') + self.check_line(output, regex) + + def test_wait(self): + # test --wait + test = self.create_test('wait') + output = self.run_tests("--wait", test, input='key') + self.check_line(output, 'Press any key to continue') + + def test_forever(self): + # test --forever + code = textwrap.dedent(""" + import builtins + import unittest + + class ForeverTester(unittest.TestCase): + def test_run(self): + # Store the state in the builtins module, because the test + # module is reload at each run + if 'RUN' in builtins.__dict__: + builtins.__dict__['RUN'] += 1 + if builtins.__dict__['RUN'] >= 3: + self.fail("fail at the 3rd runs") + else: + builtins.__dict__['RUN'] = 1 + """) + test = self.create_test('forever', code=code) + output = self.run_tests('--forever', test, exitcode=1) + self.check_executed_tests(output, [test]*3, failed=test) + + def test_list_tests(self): + # test --list-tests + tests = [self.create_test() for i in range(5)] + output = self.run_tests('--list-tests', *tests) + self.assertEqual(output.rstrip().splitlines(), + tests) + + def test_list_cases(self): + # test --list-cases + code = textwrap.dedent(""" + import unittest + + class Tests(unittest.TestCase): + def test_method1(self): + pass + def test_method2(self): + pass + """) + testname = self.create_test(code=code) + all_methods = ['%s.Tests.test_method1' % testname, + '%s.Tests.test_method2' % testname] + output = self.run_tests('--list-cases', testname) + self.assertEqual(output.splitlines(), all_methods) + + def test_crashed(self): + # Any code which causes a crash + code = 'import faulthandler; faulthandler._sigsegv()' + crash_test = self.create_test(name="crash", code=code) + ok_test = self.create_test(name="ok") + + tests = [crash_test, ok_test] + output = self.run_tests("-j2", *tests, exitcode=1) + self.check_executed_tests(output, tests, failed=crash_test, + randomize=True) + + def parse_methods(self, output): + regex = re.compile("^(test[^ ]+).*ok$", flags=re.MULTILINE) + return [match.group(1) for match in regex.finditer(output)] + + def test_matchfile(self): + code = textwrap.dedent(""" + import unittest + + class Tests(unittest.TestCase): + def test_method1(self): + pass + def test_method2(self): + pass + def test_method3(self): + pass + def test_method4(self): + pass + """) + all_methods = ['test_method1', 'test_method2', + 'test_method3', 'test_method4'] + testname = self.create_test(code=code) + + # by default, all methods should be run + output = self.run_tests("-v", testname) + methods = self.parse_methods(output) + self.assertEqual(methods, all_methods) + + # only run a subset + filename = support.TESTFN + self.addCleanup(support.unlink, filename) + + subset = [ + # only match the method name + 'test_method1', + # match the full identifier + '%s.Tests.test_method3' % testname] + with open(filename, "w") as fp: + for name in subset: + print(name, file=fp) + + output = self.run_tests("-v", "--matchfile", filename, testname) + methods = self.parse_methods(output) + subset = ['test_method1', 'test_method3'] + self.assertEqual(methods, subset) + if __name__ == '__main__': unittest.main() From 2c899ccffda92a7f3d4e7a01f14a666504db07b5 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 19 Jun 2017 11:32:34 -0700 Subject: [PATCH 296/340] bpo-30687: Fixes build scripts to find msbuild.exe and stop relying on vcvarsall.bat (#2252) (#2281) * Fixes build scripts to find msbuild.exe and stop relying on vcvarsall.bat Also fixes bdist_wininst.vcxproj to use correct version in generated name. --- Misc/NEWS | 3 + PC/bdist_wininst/bdist_wininst.vcxproj | 4 ++ PC/bdist_wininst/build.bat | 11 ++- PCbuild/build.bat | 32 +++------ PCbuild/find_msbuild.bat | 51 ++++++++++++++ PCbuild/python.vcxproj | 5 +- Tools/msi/build.bat | 10 +-- Tools/msi/buildrelease.bat | 92 ++++++++++++-------------- Tools/msi/uploadrelease.bat | 15 +++-- Tools/nuget/build.bat | 7 +- 10 files changed, 135 insertions(+), 95 deletions(-) create mode 100644 PCbuild/find_msbuild.bat diff --git a/Misc/NEWS b/Misc/NEWS index f985f5a7687a02..177be218256e5d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -252,6 +252,9 @@ Library Windows ------- +- bpo-30687: Locate msbuild.exe on Windows when building rather than + vcvarsall.bat + - Issue #29392: Prevent crash when passing invalid arguments into msvcrt module. C API diff --git a/PC/bdist_wininst/bdist_wininst.vcxproj b/PC/bdist_wininst/bdist_wininst.vcxproj index 4dc5009b58e6ac..9bbfda28ccbe2b 100644 --- a/PC/bdist_wininst/bdist_wininst.vcxproj +++ b/PC/bdist_wininst/bdist_wininst.vcxproj @@ -58,6 +58,10 @@ $(PySourcePath)lib\distutils\command\ false wininst-$(VisualStudioVersion) + wininst-14.0 + wininst-12.0 + wininst-11.0 + wininst-10.0 $(TargetName)-amd64 .exe
diff --git a/PC/bdist_wininst/build.bat b/PC/bdist_wininst/build.bat index ee6856754faa8c..d5cf75206dd810 100644 --- a/PC/bdist_wininst/build.bat +++ b/PC/bdist_wininst/build.bat @@ -7,16 +7,13 @@ set PCBUILD=%~dp0..\..\PCBuild\ echo Building Lib\distutils\command\wininst-xx.0.exe -call "%PCBUILD%env.bat" x86 -if errorlevel 1 goto :eof +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) -msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 +%MSBUILD% "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=Win32 if errorlevel 1 goto :eof echo Building Lib\distutils\command\wininst-xx.0-amd64.exe -call "%PCBUILD%env.bat" x86_amd64 -if errorlevel 1 goto :eof - -msbuild "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 +%MSBUILD% "%D%bdist_wininst.vcxproj" "/p:SolutionDir=%PCBUILD%\" /p:Configuration=Release /p:Platform=x64 diff --git a/PCbuild/build.bat b/PCbuild/build.bat index 8936fd75b7cace..714b12441497da 100644 --- a/PCbuild/build.bat +++ b/PCbuild/build.bat @@ -48,7 +48,6 @@ exit /b 127 :Run setlocal set platf=Win32 -set vs_platf=x86 set conf=Release set target=Build set dir=%~dp0 @@ -57,10 +56,6 @@ set verbose=/nologo /v:m set kill= set do_pgo= set pgo_job=-m test --pgo -set on_64_bit=true - -rem This may not be 100% accurate, but close enough. -if "%ProgramFiles(x86)%"=="" (set on_64_bit=false) :CheckOpts if "%~1"=="-h" goto Usage @@ -90,18 +85,12 @@ if "%IncludeTkinter%"=="" set IncludeTkinter=true if "%IncludeExternals%"=="true" call "%dir%get_externals.bat" -if "%platf%"=="x64" ( - if "%on_64_bit%"=="true" ( - rem This ought to always be correct these days... - set vs_platf=amd64 - ) else ( - if "%do_pgo%"=="true" ( - echo.ERROR: Cannot cross-compile with PGO - echo. 32bit operating system detected, if this is incorrect, - echo. make sure the ProgramFiles(x86^) environment variable is set - exit /b 1 - ) - set vs_platf=x86_amd64 +if "%do_pgo%" EQU "true" if "%platf%" EQU "x64" ( + if "%PROCESSOR_ARCHITEW6432%" NEQ "AMD64" if "%PROCESSOR_ARCHITECTURE%" NEQ "AMD64" ( + echo.ERROR: Cannot cross-compile with PGO + echo. 32bit operating system detected. Ensure your PROCESSOR_ARCHITECTURE + echo. and PROCESSOR_ARCHITEW6432 environment variables are correct. + exit /b 1 ) ) @@ -110,7 +99,8 @@ if exist "%GIT%" set GITProperty=/p:GIT="%GIT%" if not exist "%GIT%" echo Cannot find Git on PATH & set GITProperty= rem Setup the environment -call "%dir%env.bat" %vs_platf% >nul +call "%dir%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if "%kill%"=="true" call :Kill @@ -129,7 +119,7 @@ goto Build :Kill echo on -msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ +%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^ /p:Configuration=%conf% /p:Platform=%platf%^ /p:KillPython=true @@ -141,7 +131,7 @@ rem Call on MSBuild to do the work, echo the command. rem Passing %1-9 is not the preferred option, but argument parsing in rem batch is, shall we say, "lackluster" echo on -msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ +%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^ /p:Configuration=%conf% /p:Platform=%platf%^ /p:IncludeExternals=%IncludeExternals%^ /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^ @@ -153,4 +143,4 @@ goto :eof :Version rem Display the current build version information -msbuild "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 +%MSBUILD% "%dir%python.props" /t:ShowVersionInfo /v:m /nologo %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/PCbuild/find_msbuild.bat b/PCbuild/find_msbuild.bat new file mode 100644 index 00000000000000..1877906e00a55d --- /dev/null +++ b/PCbuild/find_msbuild.bat @@ -0,0 +1,51 @@ +@rem +@rem Searches for MSBuild.exe. This is the only tool we need to initiate +@rem a build, so we no longer search for the full VC toolset. +@rem +@rem This file is supposed to modify the state of the caller (specifically +@rem the MSBUILD variable), so we do not use setlocal or echo, and avoid +@rem changing any other persistent state. +@rem + +@rem No arguments provided means do full search +@if '%1' EQU '' goto :begin_search + +@rem One argument may be the full path. Use a goto so we don't try to +@rem parse the next if statement - incorrect quoting in the multi-arg +@rem case can cause us to break immediately. +@if '%2' EQU '' goto :one_arg + +@rem Entire command line may represent the full path if quoting failed. +@if exist "%*" (set MSBUILD="%*") & (set _Py_MSBuild_Source=environment) & goto :found +@goto :begin_search + +:one_arg +@if exist "%~1" (set MSBUILD="%~1") & (set _Py_MSBuild_Source=environment) & goto :found + +:begin_search +@set MSBUILD= + +@rem If msbuild.exe is on the PATH, assume that the user wants that one. +@where msbuild > "%TEMP%\msbuild.loc" 2> nul && set /P MSBUILD= < "%TEMP%\msbuild.loc" & del "%TEMP%\msbuild.loc" +@if exist "%MSBUILD%" set MSBUILD="%MSBUILD%" & (set _Py_MSBuild_Source=PATH) & goto :found + +@rem VS 2017 sets exactly one install as the "main" install, so we may find MSBuild in there. +@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32 >nul 2>nul +@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\SxS\VS7" /v 15.0 /reg:32') DO @( + @if "%%i"=="15.0" @if exist "%%k\MSBuild\15.0\Bin\msbuild.exe" @(set MSBUILD="%%k\MSBuild\15.0\Bin\msbuild.exe") +) +@if exist %MSBUILD% (set _Py_MSBuild_Source=Visual Studio 2017 registry) & goto :found + +@rem VS 2015 and earlier register MSBuild separately, so we can find it. +@reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32 >nul 2>nul +@if NOT ERRORLEVEL 1 @for /F "tokens=1,2*" %%i in ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\14.0" /v MSBuildToolsPath /reg:32') DO @( + @if "%%i"=="MSBuildToolsPath" @if exist "%%k\msbuild.exe" @(set MSBUILD="%%k\msbuild.exe") +) +@if exist %MSBUILD% (set _Py_MSBuild_Source=registry) & goto :found + + +@exit /b 1 + +:found +@echo Using %MSBUILD% (found in the %_Py_MSBuild_Source%) +@set _Py_MSBuild_Source= diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index 807213f12a76f4..2786ac2ebf7b6b 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -83,7 +83,7 @@ - + ucrtbase ucrtbased @@ -94,6 +94,8 @@ set PYTHONPATH=$(PySourcePath)Lib + <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'Win32'">@set PATH=%PATH%%3B$(VCInstallDir)bin + <_PGOPath Condition="$(Configuration) == 'PGInstrument' and $(Platform) == 'x64'">@set PATH=%PATH%%3B$(VCInstallDir)bin\amd64 <_Content>@rem This script invokes the most recently built Python with all arguments @rem passed through to the interpreter. This file is generated by the @rem build process and any changes *will* be thrown away by the next @@ -103,6 +105,7 @@ set PYTHONPATH=$(PySourcePath)Lib @echo Running $(Configuration)^|$(Platform) interpreter... @setlocal @set PYTHONHOME=$(PySourcePath) +$(_PGOPath) @"$(OutDir)python$(PyDebugExt).exe" %* <_ExistingContent Condition="Exists('$(PySourcePath)python.bat')">$([System.IO.File]::ReadAllText('$(PySourcePath)python.bat')) diff --git a/Tools/msi/build.bat b/Tools/msi/build.bat index 59e0261c6d5236..f720ea9a86a8cb 100644 --- a/Tools/msi/build.bat +++ b/Tools/msi/build.bat @@ -22,8 +22,8 @@ if "%~1" EQU "-r" (set REBUILD=-r) && shift && goto CheckOpts if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) call "%D%get_externals.bat" - -call "%PCBUILD%env.bat" x86 +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if defined BUILDX86 ( call "%PCBUILD%build.bat" -d -e %REBUILD% %BUILDTEST% @@ -44,7 +44,7 @@ if defined BUILDDOC ( ) rem Build the launcher MSI separately -msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 +%MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 set BUILD_CMD="%D%bundle\snapshot.wixproj" if defined BUILDTEST ( @@ -58,11 +58,11 @@ if defined REBUILD ( ) if defined BUILDX86 ( - msbuild %BUILD_CMD% + %MSBUILD% %BUILD_CMD% if errorlevel 1 goto :eof ) if defined BUILDX64 ( - msbuild /p:Platform=x64 %BUILD_CMD% + %MSBUILD% /p:Platform=x64 %BUILD_CMD% if errorlevel 1 goto :eof ) diff --git a/Tools/msi/buildrelease.bat b/Tools/msi/buildrelease.bat index c316cd7f24d303..9a2a67287d47e8 100644 --- a/Tools/msi/buildrelease.bat +++ b/Tools/msi/buildrelease.bat @@ -57,6 +57,7 @@ if "%1" EQU "--build" (set TARGET=Build) && shift && goto CheckOpts if "%1" EQU "-x86" (set BUILDX86=1) && shift && goto CheckOpts if "%1" EQU "-x64" (set BUILDX64=1) && shift && goto CheckOpts if "%1" EQU "--pgo" (set PGO=%~2) && shift && shift && goto CheckOpts +if "%1" EQU "--skip-pgo" (set PGO=) && shift && goto CheckOpts if "%1" EQU "--skip-nuget" (set BUILDNUGET=) && shift && goto CheckOpts if "%1" EQU "--skip-zip" (set BUILDZIP=) && shift && goto CheckOpts @@ -68,6 +69,8 @@ if not exist "%GIT%" where git > "%TEMP%\git.loc" 2> nul && set /P GIT= < "%TEMP if not exist "%GIT%" echo Cannot find Git on PATH && exit /B 1 call "%D%get_externals.bat" +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) :builddoc if "%SKIPBUILD%" EQU "1" goto skipdoc @@ -82,7 +85,7 @@ if errorlevel 1 goto :eof where dlltool /q && goto skipdlltoolsearch set _DLLTOOL_PATH= -where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" +where /R "%EXTERNALS%\" dlltool > "%TEMP%\dlltool.loc" 2> nul && set /P _DLLTOOL_PATH= < "%TEMP%\dlltool.loc" & del "%TEMP%\dlltool.loc" if not exist "%_DLLTOOL_PATH%" echo Cannot find binutils on PATH or in external && exit /B 1 for %%f in (%_DLLTOOL_PATH%) do set PATH=%PATH%;%%~dpf set _DLLTOOL_PATH= @@ -109,21 +112,14 @@ exit /B 0 @echo off if "%1" EQU "x86" ( - call "%PCBUILD%env.bat" x86 + set PGO= set BUILD=%PCBUILD%win32\ set BUILD_PLAT=Win32 set OUTDIR_PLAT=win32 set OBJDIR_PLAT=x86 -) else if "%~2" NEQ "" ( - call "%PCBUILD%env.bat" amd64 - set PGO=%~2 - set BUILD=%PCBUILD%amd64-pgo\ - set BUILD_PLAT=x64 - set OUTDIR_PLAT=amd64 - set OBJDIR_PLAT=x64 ) else ( - call "%PCBUILD%env.bat" amd64 set BUILD=%PCBUILD%amd64\ + set PGO=%~2 set BUILD_PLAT=x64 set OUTDIR_PLAT=amd64 set OBJDIR_PLAT=x64 @@ -135,6 +131,12 @@ if exist "%BUILD%en-us" ( if errorlevel 1 exit /B ) +if exist "%D%obj\Debug_%OBJDIR_PLAT%" ( + echo Deleting "%D%obj\Debug_%OBJDIR_PLAT%" + rmdir /q/s "%D%obj\Debug_%OBJDIR_PLAT%" + if errorlevel 1 exit /B +) + if exist "%D%obj\Release_%OBJDIR_PLAT%" ( echo Deleting "%D%obj\Release_%OBJDIR_PLAT%" rmdir /q/s "%D%obj\Release_%OBJDIR_PLAT%" @@ -146,54 +148,46 @@ if not "%CERTNAME%" EQU "" ( ) else ( set CERTOPTS= ) - +if not "%PGO%" EQU "" ( + set PGOOPTS=--pgo-job "%PGO%" +) else ( + set PGOOPTS= +) if not "%SKIPBUILD%" EQU "1" ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -d -t %TARGET% %CERTOPTS% + @echo call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% + @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %PGOOPTS% %CERTOPTS% @if errorlevel 1 exit /B @rem build.bat turns echo back on, so we disable it again @echo off - - if "%PGO%" EQU "" ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -t %TARGET% %CERTOPTS% - ) else ( - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGInstrument -t %TARGET% %CERTOPTS% - @if errorlevel 1 exit /B - - @del "%BUILD%*.pgc" - if "%PGO%" EQU "default" ( - "%BUILD%python.exe" -m test -q --pgo - ) else if "%PGO%" EQU "default2" ( - "%BUILD%python.exe" -m test -r -q --pgo - "%BUILD%python.exe" -m test -r -q --pgo - ) else if "%PGO%" EQU "default10" ( - for /L %%i in (0, 1, 9) do "%BUILD%python.exe" -m test -q -r --pgo - ) else if "%PGO%" EQU "pybench" ( - "%BUILD%python.exe" "%PCBUILD%..\Tools\pybench\pybench.py" - ) else ( - "%BUILD%python.exe" %PGO% - ) - - @call "%PCBUILD%build.bat" -e -p %BUILD_PLAT% -c PGUpdate -t Build %CERTOPTS% - ) + + @echo call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% + @call "%PCBUILD%build.bat" -d -e -p %BUILD_PLAT% -t %TARGET% @if errorlevel 1 exit /B + @rem build.bat turns echo back on, so we disable it again @echo off ) -set BUILDOPTS=/p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% -if "%PGO%" NEQ "" set BUILDOPTS=%BUILDOPTS% /p:PGOBuildPath=%BUILD% -msbuild "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% -msbuild "%D%bundle\releaselocal.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true +if "%OUTDIR_PLAT%" EQU "win32" ( + %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% + if errorlevel 1 exit /B +) else if not exist "%PCBUILD%win32\en-us\launcher.msi" ( + %MSBUILD% "%D%launcher\launcher.wixproj" /p:Platform=x86 %CERTOPTS% /p:ReleaseUri=%RELEASE_URI% + if errorlevel 1 exit /B +) + +set BUILDOPTS=/p:Platform=%1 /p:BuildForRelease=true /p:DownloadUrl=%DOWNLOAD_URL% /p:DownloadUrlBase=%DOWNLOAD_URL_BASE% /p:ReleaseUri=%RELEASE_URI% +%MSBUILD% "%D%bundle\releaselocal.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=true if errorlevel 1 exit /B -msbuild "%D%bundle\releaseweb.wixproj" /t:Rebuild /p:Platform=%1 %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false +%MSBUILD% "%D%bundle\releaseweb.wixproj" /t:Rebuild %BUILDOPTS% %CERTOPTS% /p:RebuildAll=false if errorlevel 1 exit /B if defined BUILDZIP ( - msbuild "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" + %MSBUILD% "%D%make_zip.proj" /t:Build %BUILDOPTS% %CERTOPTS% /p:OutputPath="%BUILD%en-us" if errorlevel 1 exit /B ) if defined BUILDNUGET ( - msbuild "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" + %MSBUILD% "%D%..\nuget\make_pkg.proj" /t:Build /p:Configuration=Release /p:Platform=%1 /p:OutputPath="%BUILD%en-us" if errorlevel 1 exit /B ) @@ -210,7 +204,7 @@ exit /B 0 :Help echo buildrelease.bat [--out DIR] [-x86] [-x64] [--certificate CERTNAME] [--build] [--pgo COMMAND] -echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] +echo [--skip-build] [--skip-doc] [--skip-nuget] [--skip-zip] [--skip-pgo] echo [--download DOWNLOAD URL] [--test TARGETDIR] echo [-h] echo. @@ -220,9 +214,10 @@ echo -x64 Build x64 installers echo --build (-b) Incrementally build Python rather than rebuilding echo --skip-build (-B) Do not build Python (just do the installers) echo --skip-doc (-D) Do not build documentation +echo --pgo Specify PGO command for x64 installers +echo --skip-pgo Build x64 installers without using PGO echo --skip-nuget Do not build Nuget packages echo --skip-zip Do not build embeddable package -echo --pgo Build x64 installers using PGO echo --download Specify the full download URL for MSIs echo --test Specify the test directory to run the installer tests echo -h Display this help information @@ -230,13 +225,8 @@ echo. echo If no architecture is specified, all architectures will be built. echo If --test is not specified, the installer tests are not run. echo. -echo For the --pgo option, any Python command line can be used as well as the -echo following shortcuts: -echo Shortcut Description -echo default Test suite with --pgo -echo default2 2x test suite with --pgo and randomized test order -echo default10 10x test suite with --pgo and randomized test order -echo pybench pybench script +echo For the --pgo option, any Python command line can be used, or 'default' to +echo use the default task (-m test --pgo). echo. echo The following substitutions will be applied to the download URL: echo Variable Description Example diff --git a/Tools/msi/uploadrelease.bat b/Tools/msi/uploadrelease.bat index 0873d55589f0db..610b092b863374 100644 --- a/Tools/msi/uploadrelease.bat +++ b/Tools/msi/uploadrelease.bat @@ -49,16 +49,17 @@ if defined NOGPG ( echo Found gpg2.exe at %GPG% ) -call "%PCBUILD%env.bat" > nul 2> nul +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) pushd "%D%" -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% -msbuild /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% +%MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x86 %PURGE_OPTION% +%MSBUILD% /v:m /nologo uploadrelease.proj /t:Upload /p:Platform=x64 /p:IncludeDoc=false %PURGE_OPTION% if not defined NOTEST ( - msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 - msbuild /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x86 + %MSBUILD% /v:m /nologo uploadrelease.proj /t:Test /p:Platform=x64 ) -msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 -msbuild /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false +%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x86 +%MSBUILD% /v:m /nologo uploadrelease.proj /t:ShowHashes /p:Platform=x64 /p:IncludeDoc=false popd exit /B 0 diff --git a/Tools/nuget/build.bat b/Tools/nuget/build.bat index 5068c17244456e..54498ca28a2471 100644 --- a/Tools/nuget/build.bat +++ b/Tools/nuget/build.bat @@ -21,7 +21,8 @@ if "%~1" EQU "-p" (set PACKAGES=%PACKAGES% %~2) && shift && shift && goto CheckO if not defined BUILDX86 if not defined BUILDX64 (set BUILDX86=1) && (set BUILDX64=1) call "%D%..\msi\get_externals.bat" -call "%PCBUILD%env.bat" x86 +call "%PCBUILD%find_msbuild.bat" %MSBUILD% +if ERRORLEVEL 1 (echo Cannot locate MSBuild.exe on PATH or as MSBUILD variable & exit /b 2) if defined PACKAGES set PACKAGES="/p:Packages=%PACKAGES%" @@ -30,7 +31,7 @@ if defined BUILDX86 ( ) else if not exist "%PCBUILD%win32\python.exe" call "%PCBUILD%build.bat" -e if errorlevel 1 goto :eof - msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x86 %OUTPUT% %PACKAGES% if errorlevel 1 goto :eof ) @@ -39,7 +40,7 @@ if defined BUILDX64 ( ) else if not exist "%PCBUILD%amd64\python.exe" call "%PCBUILD%build.bat" -p x64 -e if errorlevel 1 goto :eof - msbuild "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% + %MSBUILD% "%D%make_pkg.proj" /p:Configuration=Release /p:Platform=x64 %OUTPUT% %PACKAGES% if errorlevel 1 goto :eof ) From 070ba85a8f45819d9197bce4541cd594d79d247c Mon Sep 17 00:00:00 2001 From: Mariatta Date: Mon, 19 Jun 2017 23:31:11 -0700 Subject: [PATCH 297/340] [3.5] bpo-29887: Test normalization now fails if download fails (GH-905) (#2272) * [3.5] bpo-29887: Test normalization now fails if download fails (GH-905) * test_normalization fails if download fails bpo-29887. The test is still skipped if "-u urlfetch" option is not passed to regrtest (python3 -m test -u urlfetch test_normalization). * Fix ResourceWarning in test_normalization bpo-29887: Fix ResourceWarning in test_normalization if tests are interrupted by CTRL+c. (cherry picked from commit 722a3af092b94983aa26f5e591fb1b45e2c2a0ff) * bpo-29887: test_normalization handles PermissionError (#1196) Skip test_normalization.test_main() if download raises a permission error. (cherry picked from commit d13d54748d3a7db023d9db37223ea7d40bb8f8e3) * no f-strings :( --- Lib/test/test_normalization.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_normalization.py b/Lib/test/test_normalization.py index 30fa612645a386..40d58943adb353 100644 --- a/Lib/test/test_normalization.py +++ b/Lib/test/test_normalization.py @@ -37,15 +37,23 @@ def unistr(data): class NormalizationTest(unittest.TestCase): def test_main(self): - part = None - part1_data = {} # Hit the exception early try: testdata = open_urlresource(TESTDATAURL, encoding="utf-8", check=check_version) + except PermissionError: + self.skipTest("Permission error when downloading %s " + "into the test data directory" % TESTDATAURL) except (OSError, HTTPException): - self.skipTest("Could not retrieve " + TESTDATAURL) - self.addCleanup(testdata.close) + self.fail("Could not retrieve %s" % TESTDATAURL) + + with testdata: + self.run_normalization_tests(testdata) + + def run_normalization_tests(self, testdata): + part = None + part1_data = {} + for line in testdata: if '#' in line: line = line.split('#')[0] From 4899d847ed3f56b2a712799f896aa1f28540a5c0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 20 Jun 2017 15:33:35 +0200 Subject: [PATCH 298/340] bpo-30500: urllib: Simplify splithost by calling into urlparse. (#1849) (#2290) The current regex based splitting produces a wrong result. For example:: http://abc#@def Web browsers parse that URL as ``http://abc/#@def``, that is, the host is ``abc``, the path is ``/``, and the fragment is ``#@def``. (cherry picked from commit 90e01e50ef8a9e6c91f30d965563c378a4ad26de) --- Lib/test/test_urlparse.py | 51 ++++++++++++++++++++++++++++++--------- Lib/urllib/parse.py | 2 +- Misc/ACKS | 1 + Misc/NEWS | 5 ++++ 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 8dac4b14102635..e2cf1b7e0ff50f 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -757,28 +757,35 @@ def test_default_scheme(self): def test_parse_fragments(self): # Exercise the allow_fragments parameter of urlparse() and urlsplit() tests = ( - ("http:#frag", "path"), - ("//example.net#frag", "path"), - ("index.html#frag", "path"), - (";a=b#frag", "params"), - ("?a=b#frag", "query"), - ("#frag", "path"), + ("http:#frag", "path", "frag"), + ("//example.net#frag", "path", "frag"), + ("index.html#frag", "path", "frag"), + (";a=b#frag", "params", "frag"), + ("?a=b#frag", "query", "frag"), + ("#frag", "path", "frag"), + ("abc#@frag", "path", "@frag"), + ("//abc#@frag", "path", "@frag"), + ("//abc:80#@frag", "path", "@frag"), + ("//abc#@frag:80", "path", "@frag:80"), ) - for url, attr in tests: + for url, attr, expected_frag in tests: for func in (urllib.parse.urlparse, urllib.parse.urlsplit): if attr == "params" and func is urllib.parse.urlsplit: attr = "path" with self.subTest(url=url, function=func): result = func(url, allow_fragments=False) self.assertEqual(result.fragment, "") - self.assertTrue(getattr(result, attr).endswith("#frag")) + self.assertTrue( + getattr(result, attr).endswith("#" + expected_frag)) self.assertEqual(func(url, "", False).fragment, "") result = func(url, allow_fragments=True) - self.assertEqual(result.fragment, "frag") - self.assertFalse(getattr(result, attr).endswith("frag")) - self.assertEqual(func(url, "", True).fragment, "frag") - self.assertEqual(func(url).fragment, "frag") + self.assertEqual(result.fragment, expected_frag) + self.assertFalse( + getattr(result, attr).endswith(expected_frag)) + self.assertEqual(func(url, "", True).fragment, + expected_frag) + self.assertEqual(func(url).fragment, expected_frag) def test_mixed_types_rejected(self): # Several functions that process either strings or ASCII encoded bytes @@ -985,6 +992,26 @@ def test_splithost(self): self.assertEqual(splithost('/foo/bar/baz.html'), (None, '/foo/bar/baz.html')) + # bpo-30500: # starts a fragment. + self.assertEqual(splithost('//127.0.0.1#@host.com'), + ('127.0.0.1', '/#@host.com')) + self.assertEqual(splithost('//127.0.0.1#@host.com:80'), + ('127.0.0.1', '/#@host.com:80')) + self.assertEqual(splithost('//127.0.0.1:80#@host.com'), + ('127.0.0.1:80', '/#@host.com')) + + # Empty host is returned as empty string. + self.assertEqual(splithost("///file"), + ('', '/file')) + + # Trailing semicolon, question mark and hash symbol are kept. + self.assertEqual(splithost("//example.net/file;"), + ('example.net', '/file;')) + self.assertEqual(splithost("//example.net/file?"), + ('example.net', '/file?')) + self.assertEqual(splithost("//example.net/file#"), + ('example.net', '/file#')) + def test_splituser(self): splituser = urllib.parse.splituser self.assertEqual(splituser('User:Pass@www.python.org:080'), diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 5746a4ee019baa..62e8ddf04b052e 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -882,7 +882,7 @@ def splithost(url): """splithost('//host[:port]/path') --> 'host[:port]', '/path'.""" global _hostprog if _hostprog is None: - _hostprog = re.compile('//([^/?]*)(.*)', re.DOTALL) + _hostprog = re.compile('//([^/#?]*)(.*)', re.DOTALL) match = _hostprog.match(url) if match: diff --git a/Misc/ACKS b/Misc/ACKS index d728d43395b534..45358e7f9b8f2d 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1060,6 +1060,7 @@ Max Neunhöffer Anthon van der Neut George Neville-Neil Hieu Nguyen +Nam Nguyen Johannes Nicolai Samuel Nicolary Jonathan Niehof diff --git a/Misc/NEWS b/Misc/NEWS index 177be218256e5d..f839ad41287d99 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,11 @@ Extension Modules Library ------- +- [Security] bpo-30500: Fix urllib.parse.splithost() to correctly parse + fragments. For example, ``splithost('http://127.0.0.1#@evil.com/')`` now + correctly returns the ``127.0.0.1`` host, instead of treating ``@evil.com`` + as the host in an authentification (``login@host``). + - bpo-23890: unittest.TestCase.assertRaises() now manually breaks a reference cycle to not keep objects alive longer than expected. From 410860662f53945cddf5886801c5a88a84801fec Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 20 Jun 2017 16:09:06 +0200 Subject: [PATCH 299/340] bpo-30500: Fix the NEWS entry (#2295) splithost() expects an URL starting with "//" not with "http://". --- Misc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS b/Misc/NEWS index f839ad41287d99..9278c69c2e6d2e 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -60,7 +60,7 @@ Library ------- - [Security] bpo-30500: Fix urllib.parse.splithost() to correctly parse - fragments. For example, ``splithost('http://127.0.0.1#@evil.com/')`` now + fragments. For example, ``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the ``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an authentification (``login@host``). From 29c89d00bf4b57c5ee2aafe660002ce1b8cea176 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 20 Jun 2017 18:06:45 +0300 Subject: [PATCH 300/340] [3.5] bpo-29755: Fixed the lgettext() family of functions in the gettext module. (GH-2266) (#2298) They now always return bytes. Updated the gettext documentation. (cherry picked from commit 26cb465) --- Doc/library/gettext.rst | 161 +++++++++++++++++++-------------------- Lib/gettext.py | 40 +++++----- Lib/test/test_gettext.py | 132 +++++++++++++++++++++++++++++--- Misc/NEWS | 3 + 4 files changed, 229 insertions(+), 107 deletions(-) diff --git a/Doc/library/gettext.rst b/Doc/library/gettext.rst index 3a87bf591776c4..053d9d3840cfc0 100644 --- a/Doc/library/gettext.rst +++ b/Doc/library/gettext.rst @@ -48,9 +48,10 @@ class-based API instead. .. function:: bind_textdomain_codeset(domain, codeset=None) - Bind the *domain* to *codeset*, changing the encoding of strings returned by the - :func:`gettext` family of functions. If *codeset* is omitted, then the current - binding is returned. + Bind the *domain* to *codeset*, changing the encoding of byte strings + returned by the :func:`lgettext`, :func:`ldgettext`, :func:`lngettext` + and :func:`ldngettext` functions. + If *codeset* is omitted, then the current binding is returned. .. function:: textdomain(domain=None) @@ -67,28 +68,14 @@ class-based API instead. :func:`_` in the local namespace (see examples below). -.. function:: lgettext(message) - - Equivalent to :func:`gettext`, but the translation is returned in the - preferred system encoding, if no other encoding was explicitly set with - :func:`bind_textdomain_codeset`. - - .. function:: dgettext(domain, message) - Like :func:`gettext`, but look the message up in the specified *domain*. - - -.. function:: ldgettext(domain, message) - - Equivalent to :func:`dgettext`, but the translation is returned in the - preferred system encoding, if no other encoding was explicitly set with - :func:`bind_textdomain_codeset`. + Like :func:`.gettext`, but look the message up in the specified *domain*. .. function:: ngettext(singular, plural, n) - Like :func:`gettext`, but consider plural forms. If a translation is found, + Like :func:`.gettext`, but consider plural forms. If a translation is found, apply the plural formula to *n*, and return the resulting message (some languages have more than two plural forms). If no translation is found, return *singular* if *n* is 1; return *plural* otherwise. @@ -101,24 +88,33 @@ class-based API instead. formulas for a variety of languages. -.. function:: lngettext(singular, plural, n) - - Equivalent to :func:`ngettext`, but the translation is returned in the - preferred system encoding, if no other encoding was explicitly set with - :func:`bind_textdomain_codeset`. - - .. function:: dngettext(domain, singular, plural, n) Like :func:`ngettext`, but look the message up in the specified *domain*. +.. function:: lgettext(message) +.. function:: ldgettext(domain, message) +.. function:: lngettext(singular, plural, n) .. function:: ldngettext(domain, singular, plural, n) - Equivalent to :func:`dngettext`, but the translation is returned in the - preferred system encoding, if no other encoding was explicitly set with + Equivalent to the corresponding functions without the ``l`` prefix + (:func:`.gettext`, :func:`dgettext`, :func:`ngettext` and :func:`dngettext`), + but the translation is returned as a byte string encoded in the preferred + system encoding if no other encoding was explicitly set with :func:`bind_textdomain_codeset`. + .. warning:: + + These functions should be avoided in Python 3, because they return + encoded bytes. It's much better to use alternatives which return + Unicode strings instead, since most Python applications will want to + manipulate human readable text as strings instead of bytes. Further, + it's possible that you may get unexpected Unicode-related exceptions + if there are encoding problems with the translated strings. It is + possible that the ``l*()`` functions will be deprecated in future Python + versions due to their inherent problems and limitations. + Note that GNU :program:`gettext` also defines a :func:`dcgettext` method, but this was deemed not useful and so it is currently unimplemented. @@ -179,8 +175,9 @@ class can also install themselves in the built-in namespace as the function names are cached. The actual class instantiated is either *class_* if provided, otherwise :class:`GNUTranslations`. The class's constructor must take a single :term:`file object` argument. If provided, *codeset* will change - the charset used to encode translated strings in the :meth:`lgettext` and - :meth:`lngettext` methods. + the charset used to encode translated strings in the + :meth:`~NullTranslations.lgettext` and :meth:`~NullTranslations.lngettext` + methods. If multiple files are found, later files are used as fallbacks for earlier ones. To allow setting the fallback, :func:`copy.copy` is used to clone each @@ -250,26 +247,29 @@ are the methods of :class:`NullTranslations`: .. method:: gettext(message) - If a fallback has been set, forward :meth:`gettext` to the fallback. - Otherwise, return the translated message. Overridden in derived classes. - - - .. method:: lgettext(message) - - If a fallback has been set, forward :meth:`lgettext` to the fallback. - Otherwise, return the translated message. Overridden in derived classes. + If a fallback has been set, forward :meth:`.gettext` to the fallback. + Otherwise, return *message*. Overridden in derived classes. .. method:: ngettext(singular, plural, n) If a fallback has been set, forward :meth:`ngettext` to the fallback. - Otherwise, return the translated message. Overridden in derived classes. + Otherwise, return *singular* if *n* is 1; return *plural* otherwise. + Overridden in derived classes. + .. method:: lgettext(message) .. method:: lngettext(singular, plural, n) - If a fallback has been set, forward :meth:`lngettext` to the fallback. - Otherwise, return the translated message. Overridden in derived classes. + Equivalent to :meth:`.gettext` and :meth:`ngettext`, but the translation + is returned as a byte string encoded in the preferred system encoding + if no encoding was explicitly set with :meth:`set_output_charset`. + Overridden in derived classes. + + .. warning:: + + These methods should be avoided in Python 3. See the warning for the + :func:`lgettext` function. .. method:: info() @@ -279,32 +279,28 @@ are the methods of :class:`NullTranslations`: .. method:: charset() - Return the "protected" :attr:`_charset` variable, which is the encoding of - the message catalog file. + Return the encoding of the message catalog file. .. method:: output_charset() - Return the "protected" :attr:`_output_charset` variable, which defines the - encoding used to return translated messages in :meth:`lgettext` and - :meth:`lngettext`. + Return the encoding used to return translated messages in :meth:`.lgettext` + and :meth:`.lngettext`. .. method:: set_output_charset(charset) - Change the "protected" :attr:`_output_charset` variable, which defines the - encoding used to return translated messages. + Change the encoding used to return translated messages. .. method:: install(names=None) - This method installs :meth:`self.gettext` into the built-in namespace, + This method installs :meth:`.gettext` into the built-in namespace, binding it to ``_``. If the *names* parameter is given, it must be a sequence containing the names of functions you want to install in the builtins namespace in - addition to :func:`_`. Supported names are ``'gettext'`` (bound to - :meth:`self.gettext`), ``'ngettext'`` (bound to :meth:`self.ngettext`), + addition to :func:`_`. Supported names are ``'gettext'``, ``'ngettext'``, ``'lgettext'`` and ``'lngettext'``. Note that this is only one way, albeit the most convenient way, to make @@ -349,49 +345,52 @@ If the :file:`.mo` file's magic number is invalid, the major version number is unexpected, or if other problems occur while reading the file, instantiating a :class:`GNUTranslations` class can raise :exc:`OSError`. -The following methods are overridden from the base class implementation: - +.. class:: GNUTranslations -.. method:: GNUTranslations.gettext(message) + The following methods are overridden from the base class implementation: - Look up the *message* id in the catalog and return the corresponding message - string, as a Unicode string. If there is no entry in the catalog for the - *message* id, and a fallback has been set, the look up is forwarded to the - fallback's :meth:`gettext` method. Otherwise, the *message* id is returned. + .. method:: gettext(message) + Look up the *message* id in the catalog and return the corresponding message + string, as a Unicode string. If there is no entry in the catalog for the + *message* id, and a fallback has been set, the look up is forwarded to the + fallback's :meth:`~NullTranslations.gettext` method. Otherwise, the + *message* id is returned. -.. method:: GNUTranslations.lgettext(message) - Equivalent to :meth:`gettext`, but the translation is returned as a - bytestring encoded in the selected output charset, or in the preferred system - encoding if no encoding was explicitly set with :meth:`set_output_charset`. + .. method:: ngettext(singular, plural, n) + Do a plural-forms lookup of a message id. *singular* is used as the message id + for purposes of lookup in the catalog, while *n* is used to determine which + plural form to use. The returned message string is a Unicode string. -.. method:: GNUTranslations.ngettext(singular, plural, n) + If the message id is not found in the catalog, and a fallback is specified, + the request is forwarded to the fallback's :meth:`~NullTranslations.ngettext` + method. Otherwise, when *n* is 1 *singular* is returned, and *plural* is + returned in all other cases. - Do a plural-forms lookup of a message id. *singular* is used as the message id - for purposes of lookup in the catalog, while *n* is used to determine which - plural form to use. The returned message string is a Unicode string. + Here is an example:: - If the message id is not found in the catalog, and a fallback is specified, the - request is forwarded to the fallback's :meth:`ngettext` method. Otherwise, when - *n* is 1 *singular* is returned, and *plural* is returned in all other cases. + n = len(os.listdir('.')) + cat = GNUTranslations(somefile) + message = cat.ngettext( + 'There is %(num)d file in this directory', + 'There are %(num)d files in this directory', + n) % {'num': n} - Here is an example:: - n = len(os.listdir('.')) - cat = GNUTranslations(somefile) - message = cat.ngettext( - 'There is %(num)d file in this directory', - 'There are %(num)d files in this directory', - n) % {'num': n} + .. method:: lgettext(message) + .. method:: lngettext(singular, plural, n) + Equivalent to :meth:`.gettext` and :meth:`.ngettext`, but the translation + is returned as a byte string encoded in the preferred system encoding + if no encoding was explicitly set with + :meth:`~NullTranslations.set_output_charset`. -.. method:: GNUTranslations.lngettext(singular, plural, n) + .. warning:: - Equivalent to :meth:`gettext`, but the translation is returned as a - bytestring encoded in the selected output charset, or in the preferred system - encoding if no encoding was explicitly set with :meth:`set_output_charset`. + These methods should be avoided in Python 3. See the warning for the + :func:`lgettext` function. Solaris message catalog support @@ -509,7 +508,7 @@ module:: import gettext t = gettext.translation('spam', '/usr/share/locale') - _ = t.lgettext + _ = t.gettext Localizing your application diff --git a/Lib/gettext.py b/Lib/gettext.py index 57d2c74982e1d4..6b215af45ef317 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -270,7 +270,9 @@ def gettext(self, message): def lgettext(self, message): if self._fallback: return self._fallback.lgettext(message) - return message + if self._output_charset: + return message.encode(self._output_charset) + return message.encode(locale.getpreferredencoding()) def ngettext(self, msgid1, msgid2, n): if self._fallback: @@ -284,9 +286,12 @@ def lngettext(self, msgid1, msgid2, n): if self._fallback: return self._fallback.lngettext(msgid1, msgid2, n) if n == 1: - return msgid1 + tmsg = msgid1 else: - return msgid2 + tmsg = msgid2 + if self._output_charset: + return tmsg.encode(self._output_charset) + return tmsg.encode(locale.getpreferredencoding()) def info(self): return self._info @@ -368,7 +373,7 @@ def _parse(self, fp): if mlen == 0: # Catalog description lastk = None - for b_item in tmsg.split('\n'.encode("ascii")): + for b_item in tmsg.split(b'\n'): item = b_item.decode().strip() if not item: continue @@ -416,7 +421,7 @@ def lgettext(self, message): if tmsg is missing: if self._fallback: return self._fallback.lgettext(message) - return message + tmsg = message if self._output_charset: return tmsg.encode(self._output_charset) return tmsg.encode(locale.getpreferredencoding()) @@ -424,16 +429,16 @@ def lgettext(self, message): def lngettext(self, msgid1, msgid2, n): try: tmsg = self._catalog[(msgid1, self.plural(n))] - if self._output_charset: - return tmsg.encode(self._output_charset) - return tmsg.encode(locale.getpreferredencoding()) except KeyError: if self._fallback: return self._fallback.lngettext(msgid1, msgid2, n) if n == 1: - return msgid1 + tmsg = msgid1 else: - return msgid2 + tmsg = msgid2 + if self._output_charset: + return tmsg.encode(self._output_charset) + return tmsg.encode(locale.getpreferredencoding()) def gettext(self, message): missing = object() @@ -573,11 +578,11 @@ def dgettext(domain, message): return t.gettext(message) def ldgettext(domain, message): + codeset = _localecodesets.get(domain) try: - t = translation(domain, _localedirs.get(domain, None), - codeset=_localecodesets.get(domain)) + t = translation(domain, _localedirs.get(domain, None), codeset=codeset) except OSError: - return message + return message.encode(codeset or locale.getpreferredencoding()) return t.lgettext(message) def dngettext(domain, msgid1, msgid2, n): @@ -592,14 +597,15 @@ def dngettext(domain, msgid1, msgid2, n): return t.ngettext(msgid1, msgid2, n) def ldngettext(domain, msgid1, msgid2, n): + codeset = _localecodesets.get(domain) try: - t = translation(domain, _localedirs.get(domain, None), - codeset=_localecodesets.get(domain)) + t = translation(domain, _localedirs.get(domain, None), codeset=codeset) except OSError: if n == 1: - return msgid1 + tmsg = msgid1 else: - return msgid2 + tmsg = msgid2 + return tmsg.encode(codeset or locale.getpreferredencoding()) return t.lngettext(msgid1, msgid2, n) def gettext(message): diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py index f57e54689cd948..df3dc2b4366dea 100644 --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -2,6 +2,7 @@ import base64 import shutil import gettext +import locale import unittest from test import support @@ -453,6 +454,122 @@ def test_plural_number(self): self.assertRaises(TypeError, f, object()) +class LGettextTestCase(GettextBaseTest): + def setUp(self): + GettextBaseTest.setUp(self) + self.mofile = MOFILE + + def test_lgettext(self): + lgettext = gettext.lgettext + ldgettext = gettext.ldgettext + self.assertEqual(lgettext('mullusk'), b'bacon') + self.assertEqual(lgettext('spam'), b'spam') + self.assertEqual(ldgettext('gettext', 'mullusk'), b'bacon') + self.assertEqual(ldgettext('gettext', 'spam'), b'spam') + + def test_lgettext_2(self): + with open(self.mofile, 'rb') as fp: + t = gettext.GNUTranslations(fp) + lgettext = t.lgettext + self.assertEqual(lgettext('mullusk'), b'bacon') + self.assertEqual(lgettext('spam'), b'spam') + + def test_lgettext_bind_textdomain_codeset(self): + lgettext = gettext.lgettext + ldgettext = gettext.ldgettext + saved_codeset = gettext.bind_textdomain_codeset('gettext') + try: + gettext.bind_textdomain_codeset('gettext', 'utf-16') + self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16')) + self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16')) + self.assertEqual(ldgettext('gettext', 'mullusk'), 'bacon'.encode('utf-16')) + self.assertEqual(ldgettext('gettext', 'spam'), 'spam'.encode('utf-16')) + finally: + del gettext._localecodesets['gettext'] + gettext.bind_textdomain_codeset('gettext', saved_codeset) + + def test_lgettext_output_encoding(self): + with open(self.mofile, 'rb') as fp: + t = gettext.GNUTranslations(fp) + lgettext = t.lgettext + t.set_output_charset('utf-16') + self.assertEqual(lgettext('mullusk'), 'bacon'.encode('utf-16')) + self.assertEqual(lgettext('spam'), 'spam'.encode('utf-16')) + + def test_lngettext(self): + lngettext = gettext.lngettext + ldngettext = gettext.ldngettext + x = lngettext('There is %s file', 'There are %s files', 1) + self.assertEqual(x, b'Hay %s fichero') + x = lngettext('There is %s file', 'There are %s files', 2) + self.assertEqual(x, b'Hay %s ficheros') + x = lngettext('There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, b'There is %s directory') + x = lngettext('There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, b'There are %s directories') + x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1) + self.assertEqual(x, b'Hay %s fichero') + x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2) + self.assertEqual(x, b'Hay %s ficheros') + x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, b'There is %s directory') + x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, b'There are %s directories') + + def test_lngettext_2(self): + with open(self.mofile, 'rb') as fp: + t = gettext.GNUTranslations(fp) + lngettext = t.lngettext + x = lngettext('There is %s file', 'There are %s files', 1) + self.assertEqual(x, b'Hay %s fichero') + x = lngettext('There is %s file', 'There are %s files', 2) + self.assertEqual(x, b'Hay %s ficheros') + x = lngettext('There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, b'There is %s directory') + x = lngettext('There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, b'There are %s directories') + + def test_lngettext_bind_textdomain_codeset(self): + lngettext = gettext.lngettext + ldngettext = gettext.ldngettext + saved_codeset = gettext.bind_textdomain_codeset('gettext') + try: + gettext.bind_textdomain_codeset('gettext', 'utf-16') + x = lngettext('There is %s file', 'There are %s files', 1) + self.assertEqual(x, 'Hay %s fichero'.encode('utf-16')) + x = lngettext('There is %s file', 'There are %s files', 2) + self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16')) + x = lngettext('There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, 'There is %s directory'.encode('utf-16')) + x = lngettext('There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, 'There are %s directories'.encode('utf-16')) + x = ldngettext('gettext', 'There is %s file', 'There are %s files', 1) + self.assertEqual(x, 'Hay %s fichero'.encode('utf-16')) + x = ldngettext('gettext', 'There is %s file', 'There are %s files', 2) + self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16')) + x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, 'There is %s directory'.encode('utf-16')) + x = ldngettext('gettext', 'There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, 'There are %s directories'.encode('utf-16')) + finally: + del gettext._localecodesets['gettext'] + gettext.bind_textdomain_codeset('gettext', saved_codeset) + + def test_lngettext_output_encoding(self): + with open(self.mofile, 'rb') as fp: + t = gettext.GNUTranslations(fp) + lngettext = t.lngettext + t.set_output_charset('utf-16') + x = lngettext('There is %s file', 'There are %s files', 1) + self.assertEqual(x, 'Hay %s fichero'.encode('utf-16')) + x = lngettext('There is %s file', 'There are %s files', 2) + self.assertEqual(x, 'Hay %s ficheros'.encode('utf-16')) + x = lngettext('There is %s directory', 'There are %s directories', 1) + self.assertEqual(x, 'There is %s directory'.encode('utf-16')) + x = lngettext('There is %s directory', 'There are %s directories', 2) + self.assertEqual(x, 'There are %s directories'.encode('utf-16')) + + class GNUTranslationParsingTest(GettextBaseTest): def test_plural_form_error_issue17898(self): with open(MOFILE, 'wb') as fp: @@ -470,13 +587,10 @@ def setUp(self): self._ = self.t.gettext def test_unicode_msgid(self): - unless = self.assertTrue - unless(isinstance(self._(''), str)) - unless(isinstance(self._(''), str)) + self.assertIsInstance(self._(''), str) def test_unicode_msgstr(self): - eq = self.assertEqual - eq(self._('ab\xde'), '\xa4yz') + self.assertEqual(self._('ab\xde'), '\xa4yz') class WeirdMetadataTest(GettextBaseTest): @@ -539,7 +653,7 @@ def test_main(): # The original version was automatically generated from the sources with # pygettext. Later it was manually modified to add plural forms support. -''' +b''' # Dummy translation for the Python test_gettext.py module. # Copyright (C) 2001 Python Software Foundation # Barry Warsaw , 2000. @@ -599,7 +713,7 @@ def test_main(): # Here's the second example po file example, used to generate the UMO_DATA # containing utf-8 encoded Unicode strings -''' +b''' # Dummy translation for the Python test_gettext.py module. # Copyright (C) 2001 Python Software Foundation # Barry Warsaw , 2000. @@ -622,7 +736,7 @@ def test_main(): # Here's the third example po file, used to generate MMO_DATA -''' +b''' msgid "" msgstr "" "Project-Id-Version: No Project 0.0\n" @@ -641,7 +755,7 @@ def test_main(): # messages.po, used for bug 17898 # -''' +b''' # test file for http://bugs.python.org/issue17898 msgid "" msgstr "" diff --git a/Misc/NEWS b/Misc/NEWS index 9278c69c2e6d2e..b15b29610f7f1c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,9 @@ Extension Modules Library ------- +- bpo-29755: Fixed the lgettext() family of functions in the gettext module. + They now always return bytes. + - [Security] bpo-30500: Fix urllib.parse.splithost() to correctly parse fragments. For example, ``splithost('//127.0.0.1#@evil.com/')`` now correctly returns the ``127.0.0.1`` host, instead of treating ``@evil.com`` From 91d171be45942d37a973b0675521b5159a96be31 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 21 Jun 2017 16:05:14 +0200 Subject: [PATCH 301/340] bpo-30694: Upgrade Modules/expat/ to libexpat 2.2.1 (#2300) (#2314) New file: Modules/expat/siphash.h. (cherry picked from commit 5ff7132313eb651107b179d20218dfe5d4e47f13) --- Misc/NEWS | 9 + Modules/expat/COPYING | 2 +- Modules/expat/expat.h | 22 +- Modules/expat/expat_external.h | 5 +- Modules/expat/siphash.h | 344 +++++++++++++++++++ Modules/expat/winconfig.h | 10 + Modules/expat/xmlparse.c | 609 ++++++++++++++++++++++++++------- Modules/expat/xmlrole.c | 10 +- Modules/expat/xmltok.c | 34 +- 9 files changed, 887 insertions(+), 158 deletions(-) create mode 100644 Modules/expat/siphash.h diff --git a/Misc/NEWS b/Misc/NEWS index b15b29610f7f1c..d17e75e2911a9a 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,15 @@ Extension Modules Library ------- +- [Security] bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes + of multiple security vulnerabilities including: CVE-2017-9233 (External + entity infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix), + CVE-2016-0718 (Fix regression bugs from 2.2.0's fix to CVE-2016-0718) + and CVE-2012-0876 (Counter hash flooding with SipHash). + Note: the CVE-2016-5300 (Use os-specific entropy sources like getrandom) + doesn't impact Python, since Python already gets entropy from the OS to set + the expat secret using ``XML_SetHashSalt()``. + - bpo-29755: Fixed the lgettext() family of functions in the gettext module. They now always return bytes. diff --git a/Modules/expat/COPYING b/Modules/expat/COPYING index 092c83baee13ae..8d288f0f28fddd 100644 --- a/Modules/expat/COPYING +++ b/Modules/expat/COPYING @@ -1,5 +1,5 @@ Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper -Copyright (c) 2001-2016 Expat maintainers +Copyright (c) 2001-2017 Expat maintainers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Modules/expat/expat.h b/Modules/expat/expat.h index 086e24b39c51ae..28b0f954d41963 100644 --- a/Modules/expat/expat.h +++ b/Modules/expat/expat.h @@ -95,7 +95,9 @@ enum XML_Error { /* Added in 2.0. */ XML_ERROR_RESERVED_PREFIX_XML, XML_ERROR_RESERVED_PREFIX_XMLNS, - XML_ERROR_RESERVED_NAMESPACE_URI + XML_ERROR_RESERVED_NAMESPACE_URI, + /* Added in 2.2.1. */ + XML_ERROR_INVALID_ARGUMENT }; enum XML_Content_Type { @@ -706,6 +708,7 @@ XML_UseParserAsHandlerArg(XML_Parser parser); be called, despite an external subset being parsed. Note: If XML_DTD is not defined when Expat is compiled, returns XML_ERROR_FEATURE_REQUIRES_XML_DTD. + Note: If parser == NULL, returns XML_ERROR_INVALID_ARGUMENT. */ XMLPARSEAPI(enum XML_Error) XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); @@ -729,15 +732,16 @@ XML_GetBase(XML_Parser parser); to the XML_StartElementHandler that were specified in the start-tag rather than defaulted. Each attribute/value pair counts as 2; thus this correspondds to an index into the atts array passed to the - XML_StartElementHandler. + XML_StartElementHandler. Returns -1 if parser == NULL. */ XMLPARSEAPI(int) XML_GetSpecifiedAttributeCount(XML_Parser parser); /* Returns the index of the ID attribute passed in the last call to - XML_StartElementHandler, or -1 if there is no ID attribute. Each - attribute/value pair counts as 2; thus this correspondds to an - index into the atts array passed to the XML_StartElementHandler. + XML_StartElementHandler, or -1 if there is no ID attribute or + parser == NULL. Each attribute/value pair counts as 2; thus this + correspondds to an index into the atts array passed to the + XML_StartElementHandler. */ XMLPARSEAPI(int) XML_GetIdAttributeIndex(XML_Parser parser); @@ -901,6 +905,7 @@ enum XML_ParamEntityParsing { entities is requested; otherwise it will return non-zero. Note: If XML_SetParamEntityParsing is called after XML_Parse or XML_ParseBuffer, then it has no effect and will always return 0. + Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetParamEntityParsing(XML_Parser parser, @@ -910,6 +915,7 @@ XML_SetParamEntityParsing(XML_Parser parser, Helps in preventing DoS attacks based on predicting hash function behavior. This must be called before parsing is started. Returns 1 if successful, 0 when called after parsing has started. + Note: If parser == NULL, the function will do nothing and return 0. */ XMLPARSEAPI(int) XML_SetHashSalt(XML_Parser parser, @@ -936,6 +942,10 @@ XML_GetErrorCode(XML_Parser parser); the location is the location of the character at which the error was detected; otherwise the location is the location of the last parse event, as described above. + + Note: XML_GetCurrentLineNumber and XML_GetCurrentColumnNumber + return 0 to indicate an error. + Note: XML_GetCurrentByteIndex returns -1 to indicate an error. */ XMLPARSEAPI(XML_Size) XML_GetCurrentLineNumber(XML_Parser parser); XMLPARSEAPI(XML_Size) XML_GetCurrentColumnNumber(XML_Parser parser); @@ -1039,7 +1049,7 @@ XML_GetFeatureList(void); */ #define XML_MAJOR_VERSION 2 #define XML_MINOR_VERSION 2 -#define XML_MICRO_VERSION 0 +#define XML_MICRO_VERSION 1 #ifdef __cplusplus } diff --git a/Modules/expat/expat_external.h b/Modules/expat/expat_external.h index 4860c5777aa018..4c9e5eabdee2ce 100644 --- a/Modules/expat/expat_external.h +++ b/Modules/expat/expat_external.h @@ -97,7 +97,10 @@ extern "C" { #endif #ifdef XML_UNICODE_WCHAR_T -#define XML_UNICODE +# define XML_UNICODE +# if defined(__SIZEOF_WCHAR_T__) && (__SIZEOF_WCHAR_T__ != 2) +# error "sizeof(wchar_t) != 2; Need -fshort-wchar for both Expat and libc" +# endif #endif #ifdef XML_UNICODE /* Information is UTF-16 encoded. */ diff --git a/Modules/expat/siphash.h b/Modules/expat/siphash.h new file mode 100644 index 00000000000000..23b56d2ae48754 --- /dev/null +++ b/Modules/expat/siphash.h @@ -0,0 +1,344 @@ +/* ========================================================================== + * siphash.h - SipHash-2-4 in a single header file + * -------------------------------------------------------------------------- + * Derived by William Ahern from the reference implementation[1] published[2] + * by Jean-Philippe Aumasson and Daniel J. Berstein. Licensed in kind. + * by Jean-Philippe Aumasson and Daniel J. Berstein. + * Minimal changes by Sebastian Pipping on top, details below. + * Licensed under the CC0 Public Domain Dedication license. + * + * 1. https://www.131002.net/siphash/siphash24.c + * 2. https://www.131002.net/siphash/ + * -------------------------------------------------------------------------- + * HISTORY: + * + * 2017-06-10 (Sebastian Pipping) + * - Clarify license note in the header + * - Address C89 issues: + * - Stop using inline keyword (and let compiler decide) + * - Turn integer suffix ULL to UL + * - Replace _Bool by int + * - Turn macro siphash24 into a function + * - Address invalid conversion (void pointer) by explicit cast + * - Always expose sip24_valid (for self-tests) + * + * 2012-11-04 - Born. (William Ahern) + * -------------------------------------------------------------------------- + * USAGE: + * + * SipHash-2-4 takes as input two 64-bit words as the key, some number of + * message bytes, and outputs a 64-bit word as the message digest. This + * implementation employs two data structures: a struct sipkey for + * representing the key, and a struct siphash for representing the hash + * state. + * + * For converting a 16-byte unsigned char array to a key, use either the + * macro sip_keyof or the routine sip_tokey. The former instantiates a + * compound literal key, while the latter requires a key object as a + * parameter. + * + * unsigned char secret[16]; + * arc4random_buf(secret, sizeof secret); + * struct sipkey *key = sip_keyof(secret); + * + * For hashing a message, use either the convenience macro siphash24 or the + * routines sip24_init, sip24_update, and sip24_final. + * + * struct siphash state; + * void *msg; + * size_t len; + * uint64_t hash; + * + * sip24_init(&state, key); + * sip24_update(&state, msg, len); + * hash = sip24_final(&state); + * + * or + * + * hash = siphash24(msg, len, key); + * + * To convert the 64-bit hash value to a canonical 8-byte little-endian + * binary representation, use either the macro sip_binof or the routine + * sip_tobin. The former instantiates and returns a compound literal array, + * while the latter requires an array object as a parameter. + * -------------------------------------------------------------------------- + * NOTES: + * + * o Neither sip_keyof, sip_binof, nor siphash24 will work with compilers + * lacking compound literal support. Instead, you must use the lower-level + * interfaces which take as parameters the temporary state objects. + * + * o Uppercase macros may evaluate parameters more than once. Lowercase + * macros should not exhibit any such side effects. + * ========================================================================== + */ +#ifndef SIPHASH_H +#define SIPHASH_H + +#include /* size_t */ +#include /* uint64_t uint32_t uint8_t */ + + +#define SIP_ROTL(x, b) (uint64_t)(((x) << (b)) | ( (x) >> (64 - (b)))) + +#define SIP_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v) >> 0); (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); (p)[3] = (uint8_t)((v) >> 24); + +#define SIP_U64TO8_LE(p, v) \ + SIP_U32TO8_LE((p) + 0, (uint32_t)((v) >> 0)); \ + SIP_U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); + +#define SIP_U8TO64_LE(p) \ + (((uint64_t)((p)[0]) << 0) | \ + ((uint64_t)((p)[1]) << 8) | \ + ((uint64_t)((p)[2]) << 16) | \ + ((uint64_t)((p)[3]) << 24) | \ + ((uint64_t)((p)[4]) << 32) | \ + ((uint64_t)((p)[5]) << 40) | \ + ((uint64_t)((p)[6]) << 48) | \ + ((uint64_t)((p)[7]) << 56)) + + +#define SIPHASH_INITIALIZER { 0, 0, 0, 0, { 0 }, 0, 0 } + +struct siphash { + uint64_t v0, v1, v2, v3; + + unsigned char buf[8], *p; + uint64_t c; +}; /* struct siphash */ + + +#define SIP_KEYLEN 16 + +struct sipkey { + uint64_t k[2]; +}; /* struct sipkey */ + +#define sip_keyof(k) sip_tokey(&(struct sipkey){ { 0 } }, (k)) + +static struct sipkey *sip_tokey(struct sipkey *key, const void *src) { + key->k[0] = SIP_U8TO64_LE((const unsigned char *)src); + key->k[1] = SIP_U8TO64_LE((const unsigned char *)src + 8); + return key; +} /* sip_tokey() */ + + +#define sip_binof(v) sip_tobin((unsigned char[8]){ 0 }, (v)) + +static void *sip_tobin(void *dst, uint64_t u64) { + SIP_U64TO8_LE((unsigned char *)dst, u64); + return dst; +} /* sip_tobin() */ + + +static void sip_round(struct siphash *H, const int rounds) { + int i; + + for (i = 0; i < rounds; i++) { + H->v0 += H->v1; + H->v1 = SIP_ROTL(H->v1, 13); + H->v1 ^= H->v0; + H->v0 = SIP_ROTL(H->v0, 32); + + H->v2 += H->v3; + H->v3 = SIP_ROTL(H->v3, 16); + H->v3 ^= H->v2; + + H->v0 += H->v3; + H->v3 = SIP_ROTL(H->v3, 21); + H->v3 ^= H->v0; + + H->v2 += H->v1; + H->v1 = SIP_ROTL(H->v1, 17); + H->v1 ^= H->v2; + H->v2 = SIP_ROTL(H->v2, 32); + } +} /* sip_round() */ + + +static struct siphash *sip24_init(struct siphash *H, const struct sipkey *key) { + H->v0 = 0x736f6d6570736575UL ^ key->k[0]; + H->v1 = 0x646f72616e646f6dUL ^ key->k[1]; + H->v2 = 0x6c7967656e657261UL ^ key->k[0]; + H->v3 = 0x7465646279746573UL ^ key->k[1]; + + H->p = H->buf; + H->c = 0; + + return H; +} /* sip24_init() */ + + +#define sip_endof(a) (&(a)[sizeof (a) / sizeof *(a)]) + +static struct siphash *sip24_update(struct siphash *H, const void *src, size_t len) { + const unsigned char *p = (const unsigned char *)src, *pe = p + len; + uint64_t m; + + do { + while (p < pe && H->p < sip_endof(H->buf)) + *H->p++ = *p++; + + if (H->p < sip_endof(H->buf)) + break; + + m = SIP_U8TO64_LE(H->buf); + H->v3 ^= m; + sip_round(H, 2); + H->v0 ^= m; + + H->p = H->buf; + H->c += 8; + } while (p < pe); + + return H; +} /* sip24_update() */ + + +static uint64_t sip24_final(struct siphash *H) { + char left = H->p - H->buf; + uint64_t b = (H->c + left) << 56; + + switch (left) { + case 7: b |= (uint64_t)H->buf[6] << 48; + case 6: b |= (uint64_t)H->buf[5] << 40; + case 5: b |= (uint64_t)H->buf[4] << 32; + case 4: b |= (uint64_t)H->buf[3] << 24; + case 3: b |= (uint64_t)H->buf[2] << 16; + case 2: b |= (uint64_t)H->buf[1] << 8; + case 1: b |= (uint64_t)H->buf[0] << 0; + case 0: break; + } + + H->v3 ^= b; + sip_round(H, 2); + H->v0 ^= b; + H->v2 ^= 0xff; + sip_round(H, 4); + + return H->v0 ^ H->v1 ^ H->v2 ^ H->v3; +} /* sip24_final() */ + + +static uint64_t siphash24(const void *src, size_t len, const struct sipkey *key) { + struct siphash state = SIPHASH_INITIALIZER; + return sip24_final(sip24_update(sip24_init(&state, key), src, len)); +} /* siphash24() */ + + +/* + * SipHash-2-4 output with + * k = 00 01 02 ... + * and + * in = (empty string) + * in = 00 (1 byte) + * in = 00 01 (2 bytes) + * in = 00 01 02 (3 bytes) + * ... + * in = 00 01 02 ... 3e (63 bytes) + */ +static int sip24_valid(void) { + static const unsigned char vectors[64][8] = { + { 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, }, + { 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, }, + { 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, }, + { 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, }, + { 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, }, + { 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, }, + { 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, }, + { 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, }, + { 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, }, + { 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, }, + { 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, }, + { 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, }, + { 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, }, + { 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, }, + { 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, }, + { 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, }, + { 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, }, + { 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, }, + { 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, }, + { 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, }, + { 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, }, + { 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, }, + { 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, }, + { 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, }, + { 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, }, + { 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, }, + { 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, }, + { 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, }, + { 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, }, + { 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, }, + { 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, }, + { 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, }, + { 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, }, + { 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, }, + { 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, }, + { 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, }, + { 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, }, + { 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, }, + { 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, }, + { 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, }, + { 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, }, + { 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, }, + { 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, }, + { 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, }, + { 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, }, + { 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, }, + { 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, }, + { 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, }, + { 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, }, + { 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, }, + { 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, }, + { 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, }, + { 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, }, + { 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, }, + { 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, }, + { 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, }, + { 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, }, + { 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, }, + { 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, }, + { 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, }, + { 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, }, + { 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, }, + { 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, }, + { 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, } + }; + unsigned char in[64]; + struct sipkey k; + size_t i; + + sip_tokey(&k, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017"); + + for (i = 0; i < sizeof in; ++i) { + in[i] = i; + + if (siphash24(in, i, &k) != SIP_U8TO64_LE(vectors[i])) + return 0; + } + + return 1; +} /* sip24_valid() */ + + +#if SIPHASH_MAIN + +#include + +int main(void) { + int ok = sip24_valid(); + + if (ok) + puts("OK"); + else + puts("FAIL"); + + return !ok; +} /* main() */ + +#endif /* SIPHASH_MAIN */ + + +#endif /* SIPHASH_H */ diff --git a/Modules/expat/winconfig.h b/Modules/expat/winconfig.h index c1b791d62d0d0c..9bf014d7fbabd6 100644 --- a/Modules/expat/winconfig.h +++ b/Modules/expat/winconfig.h @@ -17,6 +17,12 @@ #include #include + +#if defined(HAVE_EXPAT_CONFIG_H) /* e.g. MinGW */ +# include +#else /* !defined(HAVE_EXPAT_CONFIG_H) */ + + #define XML_NS 1 #define XML_DTD 1 #define XML_CONTEXT_BYTES 1024 @@ -27,4 +33,8 @@ /* Windows has memmove() available. */ #define HAVE_MEMMOVE + +#endif /* !defined(HAVE_EXPAT_CONFIG_H) */ + + #endif /* ndef WINCONFIG_H */ diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index b308e67e2d390d..76f078e2505f90 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -1,13 +1,19 @@ /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd See the file COPYING for copying permission. + + 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+) */ +#define _GNU_SOURCE /* syscall prototype */ + #include #include /* memset(), memcpy() */ #include #include /* UINT_MAX */ +#include /* fprintf */ +#include /* getenv */ -#ifdef WIN32 +#ifdef _WIN32 #define getpid GetCurrentProcessId #else #include /* gettimeofday() */ @@ -17,20 +23,15 @@ #define XML_BUILDING_EXPAT 1 -#ifdef WIN32 +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #elif defined(HAVE_EXPAT_CONFIG_H) #include -#endif /* ndef WIN32 */ +#endif /* ndef _WIN32 */ #include "ascii.h" #include "expat.h" +#include "siphash.h" #ifdef XML_UNICODE #define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX @@ -109,17 +110,11 @@ typedef struct { const XML_Memory_Handling_Suite *mem; } HASH_TABLE; -/* Basic character hash algorithm, taken from Python's string hash: - h = h * 1000003 ^ character, the constant being a prime number. +static size_t +keylen(KEY s); -*/ -#ifdef XML_UNICODE -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned short)(c)) -#else -#define CHAR_HASH(h, c) \ - (((h) * 0xF4243) ^ (unsigned char)(c)) -#endif +static void +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key); /* For probing (after a collision) we need a step size relative prime to the hash table size, which is a power of 2. We use double-hashing, @@ -355,6 +350,8 @@ doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr, XML_Bool haveMore); #endif /* XML_DTD */ +static void +freeBindings(XML_Parser parser, BINDING *bindings); static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s, TAG_NAME *tagNamePtr, BINDING **bindingsPtr); @@ -697,10 +694,84 @@ static const XML_Char implicitContext[] = { ASCII_s, ASCII_p, ASCII_a, ASCII_c, ASCII_e, '\0' }; + +#if defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) +# include + +# if defined(HAVE_GETRANDOM) +# include /* getrandom */ +# else +# include /* syscall */ +# include /* SYS_getrandom */ +# endif + +/* Obtain entropy on Linux 3.17+ */ +static int +writeRandomBytes_getrandom(void * target, size_t count) { + int success = 0; /* full count bytes written? */ + size_t bytesWrittenTotal = 0; + const unsigned int getrandomFlags = 0; + + do { + void * const currentTarget = (void*)((char*)target + bytesWrittenTotal); + const size_t bytesToWrite = count - bytesWrittenTotal; + + const int bytesWrittenMore = +#if defined(HAVE_GETRANDOM) + getrandom(currentTarget, bytesToWrite, getrandomFlags); +#else + syscall(SYS_getrandom, currentTarget, bytesToWrite, getrandomFlags); +#endif + + if (bytesWrittenMore > 0) { + bytesWrittenTotal += bytesWrittenMore; + if (bytesWrittenTotal >= count) + success = 1; + } + } while (! success && (errno == EINTR || errno == EAGAIN)); + + return success; +} + +#endif /* defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) */ + + +#ifdef _WIN32 + +typedef BOOLEAN (APIENTRY *RTLGENRANDOM_FUNC)(PVOID, ULONG); + +/* Obtain entropy on Windows XP / Windows Server 2003 and later. + * Hint on RtlGenRandom and the following article from libsodioum. + * + * Michael Howard: Cryptographically Secure Random number on Windows without using CryptoAPI + * https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ + */ +static int +writeRandomBytes_RtlGenRandom(void * target, size_t count) { + int success = 0; /* full count bytes written? */ + const HMODULE advapi32 = LoadLibrary("ADVAPI32.DLL"); + + if (advapi32) { + const RTLGENRANDOM_FUNC RtlGenRandom + = (RTLGENRANDOM_FUNC)GetProcAddress(advapi32, "SystemFunction036"); + if (RtlGenRandom) { + if (RtlGenRandom((PVOID)target, (ULONG)count) == TRUE) { + success = 1; + } + } + FreeLibrary(advapi32); + } + + return success; +} + +#endif /* _WIN32 */ + + static unsigned long gather_time_entropy(void) { -#ifdef WIN32 +#ifdef _WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); /* never fails */ return ft.dwHighDateTime ^ ft.dwLowDateTime; @@ -716,20 +787,62 @@ gather_time_entropy(void) #endif } +#if defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_LIBBSD) +# include +#endif + +static unsigned long +ENTROPY_DEBUG(const char * label, unsigned long entropy) { + const char * const EXPAT_ENTROPY_DEBUG = getenv("EXPAT_ENTROPY_DEBUG"); + if (EXPAT_ENTROPY_DEBUG && ! strcmp(EXPAT_ENTROPY_DEBUG, "1")) { + fprintf(stderr, "Entropy: %s --> 0x%0*lx (%lu bytes)\n", + label, + (int)sizeof(entropy) * 2, entropy, + (unsigned long)sizeof(entropy)); + } + return entropy; +} + static unsigned long generate_hash_secret_salt(XML_Parser parser) { - /* Process ID is 0 bits entropy if attacker has local access - * XML_Parser address is few bits of entropy if attacker has local access */ - const unsigned long entropy = - gather_time_entropy() ^ getpid() ^ (unsigned long)parser; + unsigned long entropy; + (void)parser; +#if defined(HAVE_ARC4RANDOM_BUF) || defined(__CloudABI__) + (void)gather_time_entropy; + arc4random_buf(&entropy, sizeof(entropy)); + return ENTROPY_DEBUG("arc4random_buf", entropy); +#else + /* Try high quality providers first .. */ +#ifdef _WIN32 + if (writeRandomBytes_RtlGenRandom((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("RtlGenRandom", entropy); + } +#elif defined(HAVE_GETRANDOM) || defined(HAVE_SYSCALL_GETRANDOM) + if (writeRandomBytes_getrandom((void *)&entropy, sizeof(entropy))) { + return ENTROPY_DEBUG("getrandom", entropy); + } +#endif + /* .. and self-made low quality for backup: */ + + /* Process ID is 0 bits entropy if attacker has local access */ + entropy = gather_time_entropy() ^ getpid(); /* Factors are 2^31-1 and 2^61-1 (Mersenne primes M31 and M61) */ if (sizeof(unsigned long) == 4) { - return entropy * 2147483647; + return ENTROPY_DEBUG("fallback(4)", entropy * 2147483647); } else { - return entropy * (unsigned long)2305843009213693951; + return ENTROPY_DEBUG("fallback(8)", + entropy * (unsigned long)2305843009213693951); } +#endif +} + +static unsigned long +get_hash_secret_salt(XML_Parser parser) { + if (parser->m_parentParser != NULL) + return get_hash_secret_salt(parser->m_parentParser); + return parser->m_hash_secret_salt; } static XML_Bool /* only valid for root parser */ @@ -960,6 +1073,10 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) { TAG *tStk; OPEN_INTERNAL_ENTITY *openEntityList; + + if (parser == NULL) + return XML_FALSE; + if (parentParser) return XML_FALSE; /* move tagStack to freeTagList */ @@ -994,6 +1111,8 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) enum XML_Status XMLCALL XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) { + if (parser == NULL) + return XML_STATUS_ERROR; /* Block after XML_Parse()/XML_ParseBuffer() has been called. XXX There's no way for the caller to determine which of the XXX possible error cases caused the XML_STATUS_ERROR return. @@ -1017,52 +1136,88 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, { XML_Parser parser = oldParser; DTD *newDtd = NULL; - DTD *oldDtd = _dtd; - XML_StartElementHandler oldStartElementHandler = startElementHandler; - XML_EndElementHandler oldEndElementHandler = endElementHandler; - XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler; - XML_ProcessingInstructionHandler oldProcessingInstructionHandler - = processingInstructionHandler; - XML_CommentHandler oldCommentHandler = commentHandler; - XML_StartCdataSectionHandler oldStartCdataSectionHandler - = startCdataSectionHandler; - XML_EndCdataSectionHandler oldEndCdataSectionHandler - = endCdataSectionHandler; - XML_DefaultHandler oldDefaultHandler = defaultHandler; - XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler - = unparsedEntityDeclHandler; - XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler; - XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler - = startNamespaceDeclHandler; - XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler - = endNamespaceDeclHandler; - XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler; - XML_ExternalEntityRefHandler oldExternalEntityRefHandler - = externalEntityRefHandler; - XML_SkippedEntityHandler oldSkippedEntityHandler = skippedEntityHandler; - XML_UnknownEncodingHandler oldUnknownEncodingHandler - = unknownEncodingHandler; - XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler; - XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler; - XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler; - XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler; - ELEMENT_TYPE * oldDeclElementType = declElementType; - - void *oldUserData = userData; - void *oldHandlerArg = handlerArg; - XML_Bool oldDefaultExpandInternalEntities = defaultExpandInternalEntities; - XML_Parser oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; + DTD *oldDtd; + XML_StartElementHandler oldStartElementHandler; + XML_EndElementHandler oldEndElementHandler; + XML_CharacterDataHandler oldCharacterDataHandler; + XML_ProcessingInstructionHandler oldProcessingInstructionHandler; + XML_CommentHandler oldCommentHandler; + XML_StartCdataSectionHandler oldStartCdataSectionHandler; + XML_EndCdataSectionHandler oldEndCdataSectionHandler; + XML_DefaultHandler oldDefaultHandler; + XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler; + XML_NotationDeclHandler oldNotationDeclHandler; + XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler; + XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler; + XML_NotStandaloneHandler oldNotStandaloneHandler; + XML_ExternalEntityRefHandler oldExternalEntityRefHandler; + XML_SkippedEntityHandler oldSkippedEntityHandler; + XML_UnknownEncodingHandler oldUnknownEncodingHandler; + XML_ElementDeclHandler oldElementDeclHandler; + XML_AttlistDeclHandler oldAttlistDeclHandler; + XML_EntityDeclHandler oldEntityDeclHandler; + XML_XmlDeclHandler oldXmlDeclHandler; + ELEMENT_TYPE * oldDeclElementType; + + void *oldUserData; + void *oldHandlerArg; + XML_Bool oldDefaultExpandInternalEntities; + XML_Parser oldExternalEntityRefHandlerArg; #ifdef XML_DTD - enum XML_ParamEntityParsing oldParamEntityParsing = paramEntityParsing; - int oldInEntityValue = prologState.inEntityValue; + enum XML_ParamEntityParsing oldParamEntityParsing; + int oldInEntityValue; #endif - XML_Bool oldns_triplets = ns_triplets; + XML_Bool oldns_triplets; /* Note that the new parser shares the same hash secret as the old parser, so that dtdCopy and copyEntityTable can lookup values from hash tables associated with either parser without us having to worry which hash secrets each table has. */ - unsigned long oldhash_secret_salt = hash_secret_salt; + unsigned long oldhash_secret_salt; + + /* Validate the oldParser parameter before we pull everything out of it */ + if (oldParser == NULL) + return NULL; + + /* Stash the original parser contents on the stack */ + oldDtd = _dtd; + oldStartElementHandler = startElementHandler; + oldEndElementHandler = endElementHandler; + oldCharacterDataHandler = characterDataHandler; + oldProcessingInstructionHandler = processingInstructionHandler; + oldCommentHandler = commentHandler; + oldStartCdataSectionHandler = startCdataSectionHandler; + oldEndCdataSectionHandler = endCdataSectionHandler; + oldDefaultHandler = defaultHandler; + oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler; + oldNotationDeclHandler = notationDeclHandler; + oldStartNamespaceDeclHandler = startNamespaceDeclHandler; + oldEndNamespaceDeclHandler = endNamespaceDeclHandler; + oldNotStandaloneHandler = notStandaloneHandler; + oldExternalEntityRefHandler = externalEntityRefHandler; + oldSkippedEntityHandler = skippedEntityHandler; + oldUnknownEncodingHandler = unknownEncodingHandler; + oldElementDeclHandler = elementDeclHandler; + oldAttlistDeclHandler = attlistDeclHandler; + oldEntityDeclHandler = entityDeclHandler; + oldXmlDeclHandler = xmlDeclHandler; + oldDeclElementType = declElementType; + + oldUserData = userData; + oldHandlerArg = handlerArg; + oldDefaultExpandInternalEntities = defaultExpandInternalEntities; + oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg; +#ifdef XML_DTD + oldParamEntityParsing = paramEntityParsing; + oldInEntityValue = prologState.inEntityValue; +#endif + oldns_triplets = ns_triplets; + /* Note that the new parser shares the same hash secret as the old + parser, so that dtdCopy and copyEntityTable can lookup values + from hash tables associated with either parser without us having + to worry which hash secrets each table has. + */ + oldhash_secret_salt = hash_secret_salt; #ifdef XML_DTD if (!context) @@ -1228,12 +1383,15 @@ XML_ParserFree(XML_Parser parser) void XMLCALL XML_UseParserAsHandlerArg(XML_Parser parser) { - handlerArg = parser; + if (parser != NULL) + handlerArg = parser; } enum XML_Error XMLCALL XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; #ifdef XML_DTD /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) @@ -1248,6 +1406,8 @@ XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD) void XMLCALL XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) { + if (parser == NULL) + return; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return; @@ -1257,6 +1417,8 @@ XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) void XMLCALL XML_SetUserData(XML_Parser parser, void *p) { + if (parser == NULL) + return; if (handlerArg == userData) handlerArg = userData = p; else @@ -1266,6 +1428,8 @@ XML_SetUserData(XML_Parser parser, void *p) enum XML_Status XMLCALL XML_SetBase(XML_Parser parser, const XML_Char *p) { + if (parser == NULL) + return XML_STATUS_ERROR; if (p) { p = poolCopyString(&_dtd->pool, p); if (!p) @@ -1280,18 +1444,24 @@ XML_SetBase(XML_Parser parser, const XML_Char *p) const XML_Char * XMLCALL XML_GetBase(XML_Parser parser) { + if (parser == NULL) + return NULL; return curBase; } int XMLCALL XML_GetSpecifiedAttributeCount(XML_Parser parser) { + if (parser == NULL) + return -1; return nSpecifiedAtts; } int XMLCALL XML_GetIdAttributeIndex(XML_Parser parser) { + if (parser == NULL) + return -1; return idAttIndex; } @@ -1299,6 +1469,8 @@ XML_GetIdAttributeIndex(XML_Parser parser) const XML_AttrInfo * XMLCALL XML_GetAttributeInfo(XML_Parser parser) { + if (parser == NULL) + return NULL; return attInfo; } #endif @@ -1308,6 +1480,8 @@ XML_SetElementHandler(XML_Parser parser, XML_StartElementHandler start, XML_EndElementHandler end) { + if (parser == NULL) + return; startElementHandler = start; endElementHandler = end; } @@ -1315,34 +1489,39 @@ XML_SetElementHandler(XML_Parser parser, void XMLCALL XML_SetStartElementHandler(XML_Parser parser, XML_StartElementHandler start) { - startElementHandler = start; + if (parser != NULL) + startElementHandler = start; } void XMLCALL XML_SetEndElementHandler(XML_Parser parser, XML_EndElementHandler end) { - endElementHandler = end; + if (parser != NULL) + endElementHandler = end; } void XMLCALL XML_SetCharacterDataHandler(XML_Parser parser, XML_CharacterDataHandler handler) { - characterDataHandler = handler; + if (parser != NULL) + characterDataHandler = handler; } void XMLCALL XML_SetProcessingInstructionHandler(XML_Parser parser, XML_ProcessingInstructionHandler handler) { - processingInstructionHandler = handler; + if (parser != NULL) + processingInstructionHandler = handler; } void XMLCALL XML_SetCommentHandler(XML_Parser parser, XML_CommentHandler handler) { - commentHandler = handler; + if (parser != NULL) + commentHandler = handler; } void XMLCALL @@ -1350,6 +1529,8 @@ XML_SetCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start, XML_EndCdataSectionHandler end) { + if (parser == NULL) + return; startCdataSectionHandler = start; endCdataSectionHandler = end; } @@ -1357,19 +1538,23 @@ XML_SetCdataSectionHandler(XML_Parser parser, void XMLCALL XML_SetStartCdataSectionHandler(XML_Parser parser, XML_StartCdataSectionHandler start) { - startCdataSectionHandler = start; + if (parser != NULL) + startCdataSectionHandler = start; } void XMLCALL XML_SetEndCdataSectionHandler(XML_Parser parser, XML_EndCdataSectionHandler end) { - endCdataSectionHandler = end; + if (parser != NULL) + endCdataSectionHandler = end; } void XMLCALL XML_SetDefaultHandler(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; defaultHandler = handler; defaultExpandInternalEntities = XML_FALSE; } @@ -1378,6 +1563,8 @@ void XMLCALL XML_SetDefaultHandlerExpand(XML_Parser parser, XML_DefaultHandler handler) { + if (parser == NULL) + return; defaultHandler = handler; defaultExpandInternalEntities = XML_TRUE; } @@ -1387,6 +1574,8 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start, XML_EndDoctypeDeclHandler end) { + if (parser == NULL) + return; startDoctypeDeclHandler = start; endDoctypeDeclHandler = end; } @@ -1394,27 +1583,31 @@ XML_SetDoctypeDeclHandler(XML_Parser parser, void XMLCALL XML_SetStartDoctypeDeclHandler(XML_Parser parser, XML_StartDoctypeDeclHandler start) { - startDoctypeDeclHandler = start; + if (parser != NULL) + startDoctypeDeclHandler = start; } void XMLCALL XML_SetEndDoctypeDeclHandler(XML_Parser parser, XML_EndDoctypeDeclHandler end) { - endDoctypeDeclHandler = end; + if (parser != NULL) + endDoctypeDeclHandler = end; } void XMLCALL XML_SetUnparsedEntityDeclHandler(XML_Parser parser, XML_UnparsedEntityDeclHandler handler) { - unparsedEntityDeclHandler = handler; + if (parser != NULL) + unparsedEntityDeclHandler = handler; } void XMLCALL XML_SetNotationDeclHandler(XML_Parser parser, XML_NotationDeclHandler handler) { - notationDeclHandler = handler; + if (parser != NULL) + notationDeclHandler = handler; } void XMLCALL @@ -1422,6 +1615,8 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start, XML_EndNamespaceDeclHandler end) { + if (parser == NULL) + return; startNamespaceDeclHandler = start; endNamespaceDeclHandler = end; } @@ -1429,32 +1624,38 @@ XML_SetNamespaceDeclHandler(XML_Parser parser, void XMLCALL XML_SetStartNamespaceDeclHandler(XML_Parser parser, XML_StartNamespaceDeclHandler start) { - startNamespaceDeclHandler = start; + if (parser != NULL) + startNamespaceDeclHandler = start; } void XMLCALL XML_SetEndNamespaceDeclHandler(XML_Parser parser, XML_EndNamespaceDeclHandler end) { - endNamespaceDeclHandler = end; + if (parser != NULL) + endNamespaceDeclHandler = end; } void XMLCALL XML_SetNotStandaloneHandler(XML_Parser parser, XML_NotStandaloneHandler handler) { - notStandaloneHandler = handler; + if (parser != NULL) + notStandaloneHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandler(XML_Parser parser, XML_ExternalEntityRefHandler handler) { - externalEntityRefHandler = handler; + if (parser != NULL) + externalEntityRefHandler = handler; } void XMLCALL XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg) { + if (parser == NULL) + return; if (arg) externalEntityRefHandlerArg = (XML_Parser)arg; else @@ -1465,7 +1666,8 @@ void XMLCALL XML_SetSkippedEntityHandler(XML_Parser parser, XML_SkippedEntityHandler handler) { - skippedEntityHandler = handler; + if (parser != NULL) + skippedEntityHandler = handler; } void XMLCALL @@ -1473,6 +1675,8 @@ XML_SetUnknownEncodingHandler(XML_Parser parser, XML_UnknownEncodingHandler handler, void *data) { + if (parser == NULL) + return; unknownEncodingHandler = handler; unknownEncodingHandlerData = data; } @@ -1481,33 +1685,39 @@ void XMLCALL XML_SetElementDeclHandler(XML_Parser parser, XML_ElementDeclHandler eldecl) { - elementDeclHandler = eldecl; + if (parser != NULL) + elementDeclHandler = eldecl; } void XMLCALL XML_SetAttlistDeclHandler(XML_Parser parser, XML_AttlistDeclHandler attdecl) { - attlistDeclHandler = attdecl; + if (parser != NULL) + attlistDeclHandler = attdecl; } void XMLCALL XML_SetEntityDeclHandler(XML_Parser parser, XML_EntityDeclHandler handler) { - entityDeclHandler = handler; + if (parser != NULL) + entityDeclHandler = handler; } void XMLCALL XML_SetXmlDeclHandler(XML_Parser parser, XML_XmlDeclHandler handler) { - xmlDeclHandler = handler; + if (parser != NULL) + xmlDeclHandler = handler; } int XMLCALL XML_SetParamEntityParsing(XML_Parser parser, enum XML_ParamEntityParsing peParsing) { + if (parser == NULL) + return 0; /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return 0; @@ -1523,6 +1733,10 @@ int XMLCALL XML_SetHashSalt(XML_Parser parser, unsigned long hash_salt) { + if (parser == NULL) + return 0; + if (parser->m_parentParser) + return XML_SetHashSalt(parser->m_parentParser, hash_salt); /* block after XML_Parse()/XML_ParseBuffer() has been called */ if (ps_parsing == XML_PARSING || ps_parsing == XML_SUSPENDED) return 0; @@ -1533,6 +1747,10 @@ XML_SetHashSalt(XML_Parser parser, enum XML_Status XMLCALL XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) { + if ((parser == NULL) || (len < 0) || ((s == NULL) && (len != 0))) { + errorCode = XML_ERROR_INVALID_ARGUMENT; + return XML_STATUS_ERROR; + } switch (ps_parsing) { case XML_SUSPENDED: errorCode = XML_ERROR_SUSPENDED; @@ -1585,6 +1803,13 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) const char *end; int nLeftOver; enum XML_Status result; + /* Detect overflow (a+b > MAX <==> b > MAX-a) */ + if (len > ((XML_Size)-1) / 2 - parseEndByteIndex) { + errorCode = XML_ERROR_NO_MEMORY; + eventPtr = eventEndPtr = NULL; + processor = errorProcessor; + return XML_STATUS_ERROR; + } parseEndByteIndex += len; positionPtr = s; ps_finalBuffer = (XML_Bool)isFinal; @@ -1617,11 +1842,14 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) nLeftOver = s + len - end; if (nLeftOver) { if (buffer == NULL || nLeftOver > bufferLim - buffer) { - /* FIXME avoid integer overflow */ - char *temp; - temp = (buffer == NULL - ? (char *)MALLOC(len * 2) - : (char *)REALLOC(buffer, len * 2)); + /* avoid _signed_ integer overflow */ + char *temp = NULL; + const int bytesToAllocate = (int)((unsigned)len * 2U); + if (bytesToAllocate > 0) { + temp = (buffer == NULL + ? (char *)MALLOC(bytesToAllocate) + : (char *)REALLOC(buffer, bytesToAllocate)); + } if (temp == NULL) { errorCode = XML_ERROR_NO_MEMORY; eventPtr = eventEndPtr = NULL; @@ -1629,7 +1857,7 @@ XML_Parse(XML_Parser parser, const char *s, int len, int isFinal) return XML_STATUS_ERROR; } buffer = temp; - bufferLim = buffer + len * 2; + bufferLim = buffer + bytesToAllocate; } memcpy(buffer, end, nLeftOver); } @@ -1659,6 +1887,8 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) const char *start; enum XML_Status result = XML_STATUS_OK; + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { case XML_SUSPENDED: errorCode = XML_ERROR_SUSPENDED; @@ -1712,6 +1942,8 @@ XML_ParseBuffer(XML_Parser parser, int len, int isFinal) void * XMLCALL XML_GetBuffer(XML_Parser parser, int len) { + if (parser == NULL) + return NULL; if (len < 0) { errorCode = XML_ERROR_NO_MEMORY; return NULL; @@ -1808,6 +2040,8 @@ XML_GetBuffer(XML_Parser parser, int len) enum XML_Status XMLCALL XML_StopParser(XML_Parser parser, XML_Bool resumable) { + if (parser == NULL) + return XML_STATUS_ERROR; switch (ps_parsing) { case XML_SUSPENDED: if (resumable) { @@ -1840,6 +2074,8 @@ XML_ResumeParser(XML_Parser parser) { enum XML_Status result = XML_STATUS_OK; + if (parser == NULL) + return XML_STATUS_ERROR; if (ps_parsing != XML_SUSPENDED) { errorCode = XML_ERROR_NOT_SUSPENDED; return XML_STATUS_ERROR; @@ -1876,6 +2112,8 @@ XML_ResumeParser(XML_Parser parser) void XMLCALL XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) { + if (parser == NULL) + return; assert(status != NULL); *status = parser->m_parsingStatus; } @@ -1883,12 +2121,16 @@ XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status) enum XML_Error XMLCALL XML_GetErrorCode(XML_Parser parser) { + if (parser == NULL) + return XML_ERROR_INVALID_ARGUMENT; return errorCode; } XML_Index XMLCALL XML_GetCurrentByteIndex(XML_Parser parser) { + if (parser == NULL) + return -1; if (eventPtr) return (XML_Index)(parseEndByteIndex - (parseEndPtr - eventPtr)); return -1; @@ -1897,6 +2139,8 @@ XML_GetCurrentByteIndex(XML_Parser parser) int XMLCALL XML_GetCurrentByteCount(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventEndPtr && eventPtr) return (int)(eventEndPtr - eventPtr); return 0; @@ -1906,11 +2150,19 @@ const char * XMLCALL XML_GetInputContext(XML_Parser parser, int *offset, int *size) { #ifdef XML_CONTEXT_BYTES + if (parser == NULL) + return NULL; if (eventPtr && buffer) { - *offset = (int)(eventPtr - buffer); - *size = (int)(bufferEnd - buffer); + if (offset != NULL) + *offset = (int)(eventPtr - buffer); + if (size != NULL) + *size = (int)(bufferEnd - buffer); return buffer; } +#else + (void)parser; + (void)offset; + (void)size; #endif /* defined XML_CONTEXT_BYTES */ return (char *) 0; } @@ -1918,6 +2170,8 @@ XML_GetInputContext(XML_Parser parser, int *offset, int *size) XML_Size XMLCALL XML_GetCurrentLineNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; @@ -1928,6 +2182,8 @@ XML_GetCurrentLineNumber(XML_Parser parser) XML_Size XMLCALL XML_GetCurrentColumnNumber(XML_Parser parser) { + if (parser == NULL) + return 0; if (eventPtr && eventPtr >= positionPtr) { XmlUpdatePosition(encoding, positionPtr, eventPtr, &position); positionPtr = eventPtr; @@ -1938,30 +2194,38 @@ XML_GetCurrentColumnNumber(XML_Parser parser) void XMLCALL XML_FreeContentModel(XML_Parser parser, XML_Content *model) { - FREE(model); + if (parser != NULL) + FREE(model); } void * XMLCALL XML_MemMalloc(XML_Parser parser, size_t size) { + if (parser == NULL) + return NULL; return MALLOC(size); } void * XMLCALL XML_MemRealloc(XML_Parser parser, void *ptr, size_t size) { + if (parser == NULL) + return NULL; return REALLOC(ptr, size); } void XMLCALL XML_MemFree(XML_Parser parser, void *ptr) { - FREE(ptr); + if (parser != NULL) + FREE(ptr); } void XMLCALL XML_DefaultCurrent(XML_Parser parser) { + if (parser == NULL) + return; if (defaultHandler) { if (openInternalEntities) reportDefault(parser, @@ -2468,7 +2732,7 @@ doContent(XML_Parser parser, &fromPtr, rawNameEnd, (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1); convLen = (int)(toPtr - (XML_Char *)tag->buf); - if ((convert_res == XML_CONVERT_COMPLETED) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { + if ((fromPtr >= rawNameEnd) || (convert_res == XML_CONVERT_INPUT_INCOMPLETE)) { tag->name.strLen = convLen; break; } @@ -2511,8 +2775,10 @@ doContent(XML_Parser parser, return XML_ERROR_NO_MEMORY; poolFinish(&tempPool); result = storeAtts(parser, enc, s, &name, &bindings); - if (result) + if (result != XML_ERROR_NONE) { + freeBindings(parser, bindings); return result; + } poolFinish(&tempPool); if (startElementHandler) { startElementHandler(handlerArg, name.str, (const XML_Char **)atts); @@ -2527,15 +2793,7 @@ doContent(XML_Parser parser, if (noElmHandlers && defaultHandler) reportDefault(parser, enc, s, next); poolClear(&tempPool); - while (bindings) { - BINDING *b = bindings; - if (endNamespaceDeclHandler) - endNamespaceDeclHandler(handlerArg, b->prefix->name); - bindings = bindings->nextTagBinding; - b->nextTagBinding = freeBindingList; - freeBindingList = b; - b->prefix->binding = b->prevPrefixBinding; - } + freeBindings(parser, bindings); } if (tagLevel == 0) return epilogProcessor(parser, next, end, nextPtr); @@ -2733,6 +2991,29 @@ doContent(XML_Parser parser, /* not reached */ } +/* This function does not call free() on the allocated memory, merely + * moving it to the parser's freeBindingList where it can be freed or + * reused as appropriate. + */ +static void +freeBindings(XML_Parser parser, BINDING *bindings) +{ + while (bindings) { + BINDING *b = bindings; + + /* startNamespaceDeclHandler will have been called for this + * binding in addBindings(), so call the end handler now. + */ + if (endNamespaceDeclHandler) + endNamespaceDeclHandler(handlerArg, b->prefix->name); + + bindings = bindings->nextTagBinding; + b->nextTagBinding = freeBindingList; + freeBindingList = b; + b->prefix->binding = b->prevPrefixBinding; + } +} + /* Precondition: all arguments must be non-NULL; Purpose: - normalize attributes @@ -2957,7 +3238,13 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (s[-1] == 2) { /* prefixed */ ATTRIBUTE_ID *id; const BINDING *b; - unsigned long uriHash = hash_secret_salt; + unsigned long uriHash; + struct siphash sip_state; + struct sipkey sip_key; + + copy_salt_to_sipkey(parser, &sip_key); + sip24_init(&sip_state, &sip_key); + ((XML_Char *)s)[-1] = 0; /* clear flag */ id = (ATTRIBUTE_ID *)lookup(parser, &dtd->attributeIds, s, 0); if (!id || !id->prefix) @@ -2966,22 +3253,26 @@ storeAtts(XML_Parser parser, const ENCODING *enc, if (!b) return XML_ERROR_UNBOUND_PREFIX; - /* as we expand the name we also calculate its hash value */ for (j = 0; j < b->uriLen; j++) { const XML_Char c = b->uri[j]; if (!poolAppendChar(&tempPool, c)) return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); } + + sip24_update(&sip_state, b->uri, b->uriLen * sizeof(XML_Char)); + while (*s++ != XML_T(ASCII_COLON)) ; + + sip24_update(&sip_state, s, keylen(s) * sizeof(XML_Char)); + do { /* copies null terminator */ - const XML_Char c = *s; if (!poolAppendChar(&tempPool, *s)) return XML_ERROR_NO_MEMORY; - uriHash = CHAR_HASH(uriHash, c); } while (*s++); + uriHash = (unsigned long)sip24_final(&sip_state); + { /* Check hash table for duplicate of expanded name (uriName). Derived from code in lookup(parser, HASH_TABLE *table, ...). */ @@ -3695,6 +3986,14 @@ entityValueInitProcessor(XML_Parser parser, *nextPtr = next; return XML_ERROR_NONE; } + /* If we get this token, we have the start of what might be a + normal tag, but not a declaration (i.e. it doesn't begin with + "internalEventEndPtr = NULL; textStart = (char *)entity->textPtr; textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; #ifdef XML_DTD if (entity->is_param) { @@ -4916,6 +5217,8 @@ internalEntityProcessor(XML_Parser parser, entity = openEntity->entity; textStart = ((char *)entity->textPtr) + entity->processed; textEnd = (char *)(entity->textPtr + entity->textLen); + /* Set a safe default value in case 'next' does not get set */ + next = textStart; #ifdef XML_DTD if (entity->is_param) { @@ -5876,7 +6179,6 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd, const XML_Memory_H newE->defaultAtts = (DEFAULT_ATTRIBUTE *) ms->malloc_fcn(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (!newE->defaultAtts) { - ms->free_fcn(newE); return 0; } } @@ -6011,13 +6313,32 @@ keyeq(KEY s1, KEY s2) return XML_FALSE; } +static size_t +keylen(KEY s) +{ + size_t len = 0; + for (; *s; s++, len++); + return len; +} + +static void +copy_salt_to_sipkey(XML_Parser parser, struct sipkey * key) +{ + key->k[0] = 0; + key->k[1] = get_hash_secret_salt(parser); +} + static unsigned long FASTCALL hash(XML_Parser parser, KEY s) { - unsigned long h = hash_secret_salt; - while (*s) - h = CHAR_HASH(h, *s++); - return h; + struct siphash state; + struct sipkey key; + (void)sip_tobin; + (void)sip24_valid; + copy_salt_to_sipkey(parser, &key); + sip24_init(&state, &key); + sip24_update(&state, s, keylen(s) * sizeof(XML_Char)); + return (unsigned long)sip24_final(&state); } static NAMED * @@ -6260,6 +6581,35 @@ poolStoreString(STRING_POOL *pool, const ENCODING *enc, return pool->start; } +static size_t +poolBytesToAllocateFor(int blockSize) +{ + /* Unprotected math would be: + ** return offsetof(BLOCK, s) + blockSize * sizeof(XML_Char); + ** + ** Detect overflow, avoiding _signed_ overflow undefined behavior + ** For a + b * c we check b * c in isolation first, so that addition of a + ** on top has no chance of making us accept a small non-negative number + */ + const size_t stretch = sizeof(XML_Char); /* can be 4 bytes */ + + if (blockSize <= 0) + return 0; + + if (blockSize > (int)(INT_MAX / stretch)) + return 0; + + { + const int stretchedBlockSize = blockSize * (int)stretch; + const int bytesToAllocate = (int)( + offsetof(BLOCK, s) + (unsigned)stretchedBlockSize); + if (bytesToAllocate < 0) + return 0; + + return (size_t)bytesToAllocate; + } +} + static XML_Bool FASTCALL poolGrow(STRING_POOL *pool) { @@ -6289,14 +6639,17 @@ poolGrow(STRING_POOL *pool) if (pool->blocks && pool->start == pool->blocks->s) { BLOCK *temp; int blockSize = (int)((unsigned)(pool->end - pool->start)*2U); + size_t bytesToAllocate; if (blockSize < 0) return XML_FALSE; + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + temp = (BLOCK *) - pool->mem->realloc_fcn(pool->blocks, - (offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char))); + pool->mem->realloc_fcn(pool->blocks, (unsigned)bytesToAllocate); if (temp == NULL) return XML_FALSE; pool->blocks = temp; @@ -6308,16 +6661,26 @@ poolGrow(STRING_POOL *pool) else { BLOCK *tem; int blockSize = (int)(pool->end - pool->start); + size_t bytesToAllocate; if (blockSize < 0) return XML_FALSE; if (blockSize < INIT_BLOCK_SIZE) blockSize = INIT_BLOCK_SIZE; - else + else { + /* Detect overflow, avoiding _signed_ overflow undefined behavior */ + if ((int)((unsigned)blockSize * 2U) < 0) { + return XML_FALSE; + } blockSize *= 2; - tem = (BLOCK *)pool->mem->malloc_fcn(offsetof(BLOCK, s) - + blockSize * sizeof(XML_Char)); + } + + bytesToAllocate = poolBytesToAllocateFor(blockSize); + if (bytesToAllocate == 0) + return XML_FALSE; + + tem = (BLOCK *)pool->mem->malloc_fcn(bytesToAllocate); if (!tem) return XML_FALSE; tem->size = blockSize; diff --git a/Modules/expat/xmlrole.c b/Modules/expat/xmlrole.c index fcd0dc6948f442..a7c56302796957 100644 --- a/Modules/expat/xmlrole.c +++ b/Modules/expat/xmlrole.c @@ -4,19 +4,13 @@ #include -#ifdef WIN32 +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include #endif -#endif /* ndef WIN32 */ +#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" diff --git a/Modules/expat/xmltok.c b/Modules/expat/xmltok.c index a29d9e2f8ac386..cdf0720dd89689 100644 --- a/Modules/expat/xmltok.c +++ b/Modules/expat/xmltok.c @@ -4,19 +4,13 @@ #include -#ifdef WIN32 +#ifdef _WIN32 #include "winconfig.h" -#elif defined(MACOS_CLASSIC) -#include "macconfig.h" -#elif defined(__amigaos__) -#include "amigaconfig.h" -#elif defined(__WATCOMC__) -#include "watcomconfig.h" #else #ifdef HAVE_EXPAT_CONFIG_H #include #endif -#endif /* ndef WIN32 */ +#endif /* ndef _WIN32 */ #include "expat_external.h" #include "internal.h" @@ -369,24 +363,24 @@ utf8_toUtf8(const ENCODING *UNUSED_P(enc), const char **fromP, const char *fromLim, char **toP, const char *toLim) { - enum XML_Convert_Result res = XML_CONVERT_COMPLETED; char *to; const char *from; - if (fromLim - *fromP > toLim - *toP) { - /* Avoid copying partial characters. */ - res = XML_CONVERT_OUTPUT_EXHAUSTED; - fromLim = *fromP + (toLim - *toP); - align_limit_to_full_utf8_characters(*fromP, &fromLim); - } + const char *fromLimInitial = fromLim; + + /* Avoid copying partial characters. */ + align_limit_to_full_utf8_characters(*fromP, &fromLim); + for (to = *toP, from = *fromP; (from < fromLim) && (to < toLim); from++, to++) *to = *from; *fromP = from; *toP = to; - if ((to == toLim) && (from < fromLim)) + if (fromLim < fromLimInitial) + return XML_CONVERT_INPUT_INCOMPLETE; + else if ((to == toLim) && (from < fromLim)) return XML_CONVERT_OUTPUT_EXHAUSTED; else - return res; + return XML_CONVERT_COMPLETED; } static enum XML_Convert_Result PTRCALL @@ -402,7 +396,7 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD2: if (fromLim - from < 2) { res = XML_CONVERT_INPUT_INCOMPLETE; - break; + goto after; } *to++ = (unsigned short)(((from[0] & 0x1f) << 6) | (from[1] & 0x3f)); from += 2; @@ -410,7 +404,7 @@ utf8_toUtf16(const ENCODING *enc, case BT_LEAD3: if (fromLim - from < 3) { res = XML_CONVERT_INPUT_INCOMPLETE; - break; + goto after; } *to++ = (unsigned short)(((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f)); @@ -441,6 +435,8 @@ utf8_toUtf16(const ENCODING *enc, break; } } + if (from < fromLim) + res = XML_CONVERT_OUTPUT_EXHAUSTED; after: *fromP = from; *toP = to; From 491afb533e40ac2066e427bdce6a77ce8f20d73b Mon Sep 17 00:00:00 2001 From: larryhastings Date: Thu, 22 Jun 2017 16:01:00 -0700 Subject: [PATCH 302/340] Add "Misc/NEWS.d" directory tree for "blurb". GH-2330 CPython workflow is changing! We're going to start using "blurb" to manage Misc/NEWS entries: https://github.com/python/core-workflow (This will be a big win for release managers, honest.) This checkin simply populates the "Misc/NEWS.d" subdirectory tree so that people can start putting their news entries in there. No other changes (yet). --- Misc/NEWS.d/next/Build/README.rst | 1 + Misc/NEWS.d/next/C API/README.rst | 1 + Misc/NEWS.d/next/Core and Builtins/README.rst | 1 + Misc/NEWS.d/next/Documentation/README.rst | 1 + Misc/NEWS.d/next/IDLE/README.rst | 1 + Misc/NEWS.d/next/Library/README.rst | 1 + Misc/NEWS.d/next/Security/README.rst | 1 + Misc/NEWS.d/next/Tests/README.rst | 1 + Misc/NEWS.d/next/Tools-Demos/README.rst | 1 + Misc/NEWS.d/next/Windows/README.rst | 1 + Misc/NEWS.d/next/macOS/README.rst | 1 + 11 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Build/README.rst create mode 100644 Misc/NEWS.d/next/C API/README.rst create mode 100644 Misc/NEWS.d/next/Core and Builtins/README.rst create mode 100644 Misc/NEWS.d/next/Documentation/README.rst create mode 100644 Misc/NEWS.d/next/IDLE/README.rst create mode 100644 Misc/NEWS.d/next/Library/README.rst create mode 100644 Misc/NEWS.d/next/Security/README.rst create mode 100644 Misc/NEWS.d/next/Tests/README.rst create mode 100644 Misc/NEWS.d/next/Tools-Demos/README.rst create mode 100644 Misc/NEWS.d/next/Windows/README.rst create mode 100644 Misc/NEWS.d/next/macOS/README.rst diff --git a/Misc/NEWS.d/next/Build/README.rst b/Misc/NEWS.d/next/Build/README.rst new file mode 100644 index 00000000000000..0d2d2c1fc38be9 --- /dev/null +++ b/Misc/NEWS.d/next/Build/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Build* section in this directory. diff --git a/Misc/NEWS.d/next/C API/README.rst b/Misc/NEWS.d/next/C API/README.rst new file mode 100644 index 00000000000000..5a04f76f47b67e --- /dev/null +++ b/Misc/NEWS.d/next/C API/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *C API* section in this directory. diff --git a/Misc/NEWS.d/next/Core and Builtins/README.rst b/Misc/NEWS.d/next/Core and Builtins/README.rst new file mode 100644 index 00000000000000..52b8c3e6263163 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Core and Builtins* section in this directory. diff --git a/Misc/NEWS.d/next/Documentation/README.rst b/Misc/NEWS.d/next/Documentation/README.rst new file mode 100644 index 00000000000000..405f0ac01a7202 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Documentation* section in this directory. diff --git a/Misc/NEWS.d/next/IDLE/README.rst b/Misc/NEWS.d/next/IDLE/README.rst new file mode 100644 index 00000000000000..5475f7b42050cd --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *IDLE* section in this directory. diff --git a/Misc/NEWS.d/next/Library/README.rst b/Misc/NEWS.d/next/Library/README.rst new file mode 100644 index 00000000000000..6d2d30eca0fd05 --- /dev/null +++ b/Misc/NEWS.d/next/Library/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Library* section in this directory. diff --git a/Misc/NEWS.d/next/Security/README.rst b/Misc/NEWS.d/next/Security/README.rst new file mode 100644 index 00000000000000..84c1a3a6ed7a07 --- /dev/null +++ b/Misc/NEWS.d/next/Security/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Security* section in this directory. diff --git a/Misc/NEWS.d/next/Tests/README.rst b/Misc/NEWS.d/next/Tests/README.rst new file mode 100644 index 00000000000000..d2e50e43d84790 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Tests* section in this directory. diff --git a/Misc/NEWS.d/next/Tools-Demos/README.rst b/Misc/NEWS.d/next/Tools-Demos/README.rst new file mode 100644 index 00000000000000..357f82862cb51a --- /dev/null +++ b/Misc/NEWS.d/next/Tools-Demos/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Tools/Demos* section in this directory. diff --git a/Misc/NEWS.d/next/Windows/README.rst b/Misc/NEWS.d/next/Windows/README.rst new file mode 100644 index 00000000000000..1e65de35f0ad97 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *Windows* section in this directory. diff --git a/Misc/NEWS.d/next/macOS/README.rst b/Misc/NEWS.d/next/macOS/README.rst new file mode 100644 index 00000000000000..a3adb59b62631e --- /dev/null +++ b/Misc/NEWS.d/next/macOS/README.rst @@ -0,0 +1 @@ +Put news entry ``blurb`` files for the *macOS* section in this directory. From ce1bd6ac7ffaf396157a9ceb55b281a3b196323f Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 22 Jun 2017 19:18:05 -0700 Subject: [PATCH 303/340] [3.5] bpo-30619: Clarify typing.Union documentation (GH-2326) (GH-2338) When a class and its subclass are present, the latter is skipped. (cherry picked from commit 6580c19bbbe7bc9bc0884699afd69184f523b32e) --- Doc/library/typing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 2ca3bcd5a2cea7..adaad2909eafb1 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -861,7 +861,7 @@ The module defines the following classes, functions and decorators: Union[int, str] == Union[str, int] - * When a class and its subclass are present, the former is skipped, e.g.:: + * When a class and its subclass are present, the latter is skipped, e.g.:: Union[int, object] == object From 8aa15ba884b14c1cf65d4c1a4c5abc4253f5c9ed Mon Sep 17 00:00:00 2001 From: Mariatta Date: Thu, 22 Jun 2017 21:24:33 -0700 Subject: [PATCH 304/340] [3.5] bpo-30709: Improve code example in Descriptor HowTo doc (GH-2339) (GH-2341) (cherry picked from commit b066edfb1b268e90ea11f45dd1827f46d7ceec88) --- Doc/howto/descriptor.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst index 2dd6c34e2ced02..b34937585ea444 100644 --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -252,10 +252,10 @@ to wrap access to the value attribute in a property data descriptor:: class Cell(object): . . . - def getvalue(self, obj): - "Recalculate cell before returning value" + def getvalue(self): + "Recalculate the cell before returning value" self.recalc() - return obj._value + return self._value value = property(getvalue) From e2aec8e691d8acb08373889d9af48a5b1d03b689 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 23 Jun 2017 13:52:22 +0300 Subject: [PATCH 305/340] [3.5] bpo-30727: Fix a race condition in test_threading. (GH-2334) (#2352) (cherry picked from commit 32cb968) --- Lib/test/lock_tests.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/Lib/test/lock_tests.py b/Lib/test/lock_tests.py index a64aa18cd3aaae..6c03b5ad00fe06 100644 --- a/Lib/test/lock_tests.py +++ b/Lib/test/lock_tests.py @@ -449,21 +449,28 @@ def _check_notify(self, cond): # construct. In particular, it is possible that this can no longer # be conveniently guaranteed should their implementation ever change. N = 5 + ready = [] results1 = [] results2 = [] phase_num = 0 def f(): cond.acquire() + ready.append(phase_num) result = cond.wait() cond.release() results1.append((result, phase_num)) cond.acquire() + ready.append(phase_num) result = cond.wait() cond.release() results2.append((result, phase_num)) b = Bunch(f, N) b.wait_for_started() - _wait() + # first wait, to ensure all workers settle into cond.wait() before + # we continue. See issues #8799 and #30727. + while len(ready) < 5: + _wait() + ready.clear() self.assertEqual(results1, []) # Notify 3 threads at first cond.acquire() @@ -475,9 +482,9 @@ def f(): _wait() self.assertEqual(results1, [(True, 1)] * 3) self.assertEqual(results2, []) - # first wait, to ensure all workers settle into cond.wait() before - # we continue. See issue #8799 - _wait() + # make sure all awaken workers settle into cond.wait() + while len(ready) < 3: + _wait() # Notify 5 threads: they might be in their first or second wait cond.acquire() cond.notify(5) @@ -488,7 +495,9 @@ def f(): _wait() self.assertEqual(results1, [(True, 1)] * 3 + [(True, 2)] * 2) self.assertEqual(results2, [(True, 2)] * 3) - _wait() # make sure all workers settle into cond.wait() + # make sure all workers settle into cond.wait() + while len(ready) < 5: + _wait() # Notify all threads: they are all in their second wait cond.acquire() cond.notify_all() From f42ce179c8aaa7e211ac4123c58fa3dd9a452004 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 23 Jun 2017 15:14:18 +0200 Subject: [PATCH 306/340] [3.5] bpo-30726: PCbuild _elementtree: remove duplicate defines (#2348) (#2350) * bpo-30726: PCbuild _elementtree: remove duplicate defines (#2348) bpo-30726, bpo-29591: libexpat 2.2.1 of Modules/expat/ now uses a winconfig.h configuration file which already defines: * XML_NS * XML_DTD * BYTEORDER=1234 * XML_CONTEXT_BYTES=1024 * HAVE_MEMMOVE Remove these defines from PCbuild/_elementtree.vcxproj to prevent compiler warnings. Co-Authored-By: Jeremy Kloth (cherry picked from commit c8fb58bd7917151e63398587a7fc2126db7c26de) * bpo-30726: Fix elementtree warnings on Windows due to expat upgrade (#2319) * bpo-30726: Fix elementtree warnings on Windows Caused by usage of `getenv` which should be safe. And a few integer truncations which should also be ok. * bpo-30726: Don't ignore libexpat warnings which haypo intends to fix upstream (cherry picked from commit 87c65550730a8f85ce339ba197bce4fb7e836619) --- PCbuild/_elementtree.vcxproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 725b5a967bebc9..639ba479db5786 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -62,7 +62,7 @@ ..\Modules\expat;%(AdditionalIncludeDirectories) - XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;USE_PYEXPAT_CAPI;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) 0x1D100000 @@ -103,4 +103,4 @@ - \ No newline at end of file + From a7c0264735f46afab13771be4218d8eab0d7dc91 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 23 Jun 2017 20:27:02 +0300 Subject: [PATCH 307/340] [3.5] bpo-30730: Prevent environment variables injection in subprocess on Windows. (GH-2325) (#2361) Prevent passing other invalid environment variables and command arguments.. (cherry picked from commit d174d24a5d37d1516b885dc7c82f71ecd5930700) --- Lib/subprocess.py | 8 ++++++-- Lib/test/test_subprocess.py | 40 +++++++++++++++++++++++++++++++++++++ Misc/NEWS | 3 +++ Modules/_winapi.c | 26 +++++++++++++++++++----- Objects/abstract.c | 4 ++-- 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 614de40e5cae32..8e4499809baa22 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1200,8 +1200,12 @@ def _execute_child(self, args, executable, preexec_fn, close_fds, # and pass it to fork_exec() if env is not None: - env_list = [os.fsencode(k) + b'=' + os.fsencode(v) - for k, v in env.items()] + env_list = [] + for k, v in env.items(): + k = os.fsencode(k) + if b'=' in k: + raise ValueError("illegal environment variable name") + env_list.append(k + b'=' + os.fsencode(v)) else: env_list = None # Use execv instead of execve. executable = os.fsencode(executable) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 03a06e051bff2f..804c8f44e9a3d6 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -634,6 +634,46 @@ def test_empty_env(self): # environment b"['__CF_USER_TEXT_ENCODING']")) + def test_invalid_cmd(self): + # null character in the command name + cmd = sys.executable + '\0' + with self.assertRaises(ValueError): + subprocess.Popen([cmd, "-c", "pass"]) + + # null character in the command argument + with self.assertRaises(ValueError): + subprocess.Popen([sys.executable, "-c", "pass#\0"]) + + def test_invalid_env(self): + # null character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT\0VEGETABLE"] = "cabbage" + with self.assertRaises(ValueError): + subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + + # null character in the enviroment variable value + newenv = os.environ.copy() + newenv["FRUIT"] = "orange\0VEGETABLE=cabbage" + with self.assertRaises(ValueError): + subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + + # equal character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT=ORANGE"] = "lemon" + with self.assertRaises(ValueError): + subprocess.Popen([sys.executable, "-c", "pass"], env=newenv) + + # equal character in the enviroment variable value + newenv = os.environ.copy() + newenv["FRUIT"] = "orange=lemon" + with subprocess.Popen([sys.executable, "-c", + 'import sys, os;' + 'sys.stdout.write(os.getenv("FRUIT"))'], + stdout=subprocess.PIPE, + env=newenv) as p: + stdout, stderr = p.communicate() + self.assertEqual(stdout, b"orange=lemon") + def test_communicate_stdin(self): p = subprocess.Popen([sys.executable, "-c", 'import sys;' diff --git a/Misc/NEWS b/Misc/NEWS index d17e75e2911a9a..b2bbd5d359c264 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,9 @@ Extension Modules Library ------- +- [Security] bpo-30730: Prevent environment variables injection in subprocess on + Windows. Prevent passing other environment variables and command arguments. + - [Security] bpo-30694: Upgrade expat copy from 2.2.0 to 2.2.1 to get fixes of multiple security vulnerabilities including: CVE-2017-9233 (External entity infinite loop DoS), CVE-2016-9063 (Integer overflow, re-fix), diff --git a/Modules/_winapi.c b/Modules/_winapi.c index cc7b66360df6d4..28a9ac0cf4e42c 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -744,6 +744,20 @@ getenvironment(PyObject* environment) "environment can only contain strings"); goto error; } + if (PyUnicode_FindChar(key, '\0', 0, PyUnicode_GET_LENGTH(key), 1) != -1 || + PyUnicode_FindChar(value, '\0', 0, PyUnicode_GET_LENGTH(value), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + goto error; + } + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (PyUnicode_GET_LENGTH(key) == 0 || + PyUnicode_FindChar(key, '=', 1, PyUnicode_GET_LENGTH(key), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + goto error; + } if (totalsize > PY_SSIZE_T_MAX - PyUnicode_GET_LENGTH(key) - 1) { PyErr_SetString(PyExc_OverflowError, "environment too long"); goto error; @@ -830,7 +844,8 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, PROCESS_INFORMATION pi; STARTUPINFOW si; PyObject* environment; - wchar_t *wenvironment; + const wchar_t *wenvironment; + Py_ssize_t wenvironment_size; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); @@ -846,12 +861,13 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, if (env_mapping != Py_None) { environment = getenvironment(env_mapping); - if (! environment) + if (environment == NULL) { return NULL; + } + /* contains embedded null characters */ wenvironment = PyUnicode_AsUnicode(environment); - if (wenvironment == NULL) - { - Py_XDECREF(environment); + if (wenvironment == NULL) { + Py_DECREF(environment); return NULL; } } diff --git a/Objects/abstract.c b/Objects/abstract.c index 88205bd0ce73ca..952552eef9c75e 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2825,8 +2825,8 @@ _PySequence_BytesToCharpArray(PyObject* self) array[i] = NULL; goto fail; } - data = PyBytes_AsString(item); - if (data == NULL) { + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(item, &data, NULL) < 0) { /* NULL terminate before freeing. */ array[i] = NULL; goto fail; From 599ff020b308113f3709fd4e623d9f0d08511706 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 23 Jun 2017 11:39:53 -0700 Subject: [PATCH 308/340] [3.5] bpo-30645: don't append to an inner loop path in imp.load_package() (GH-2268) (GH-2365) Bug didn't manifest itself when importing a module with source as .py files are always the first on the search path. The issue only showed up in bytecode-only packages where the calculated file path would be ``__init__.py/__init__.pyc``. Patch by Alexandru Ardelean. (cherry picked from commit c38e32a10061a7c6d54e7e53ffabf7af7998f045) --- Lib/imp.py | 5 +++-- Misc/ACKS | 1 + Misc/NEWS | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Lib/imp.py b/Lib/imp.py index e2643918421714..af0790f9422de7 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -203,8 +203,9 @@ def load_package(name, path): extensions = (machinery.SOURCE_SUFFIXES[:] + machinery.BYTECODE_SUFFIXES[:]) for extension in extensions: - path = os.path.join(path, '__init__'+extension) - if os.path.exists(path): + init_path = os.path.join(path, '__init__' + extension) + if os.path.exists(init_path): + path = init_path break else: raise ValueError('{!r} is not a package'.format(path)) diff --git a/Misc/ACKS b/Misc/ACKS index 45358e7f9b8f2d..7f9044ac7cb6da 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -56,6 +56,7 @@ Ankur Ankan Heidi Annexstad Ramchandra Apte Éric Araujo +Alexandru Ardelean Alicia Arlen Jeffrey Armstrong Jason Asbahr diff --git a/Misc/NEWS b/Misc/NEWS index b2bbd5d359c264..b731792cde6206 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -79,6 +79,10 @@ Library correctly returns the ``127.0.0.1`` host, instead of treating ``@evil.com`` as the host in an authentification (``login@host``). +- bpo-30645: Fix path calculation in imp.load_package(), fixing it for + cases when a package is only shipped with bytecodes. Patch by + Alexandru Ardelean. + - bpo-23890: unittest.TestCase.assertRaises() now manually breaks a reference cycle to not keep objects alive longer than expected. From 3e8d6f564395b668bad7ff9bf55703eaa6d1b888 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Fri, 23 Jun 2017 22:50:31 -0700 Subject: [PATCH 309/340] [3.5] Fix a typo in a comment in coroutines.py (GH-2267) (GH-2371) defiend -> defined (cherry picked from commit cab469245d7635447c5e04fa6ed860b067dfc26b) --- Lib/asyncio/coroutines.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py index 5bdeceb9b117d7..488e4236724e7a 100644 --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -197,7 +197,7 @@ def coroutine(func): """ if _inspect_iscoroutinefunction(func): # In Python 3.5 that's all we need to do for coroutines - # defiend with "async def". + # defined with "async def". # Wrapping in CoroWrapper will happen via # 'sys.set_coroutine_wrapper' function. return func From e0d446e9caa38923e43818f78c94f95fe0aa995e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 24 Jun 2017 16:42:44 +0300 Subject: [PATCH 310/340] [3.5] bpo-30745: Fix compiler warnings introduced in bpo-30730. (GH-2376) (#2379) (cherry picked from commit 0ee32c1) --- Modules/_winapi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_winapi.c b/Modules/_winapi.c index 28a9ac0cf4e42c..a911a39722379a 100644 --- a/Modules/_winapi.c +++ b/Modules/_winapi.c @@ -844,8 +844,7 @@ _winapi_CreateProcess_impl(PyObject *module, Py_UNICODE *application_name, PROCESS_INFORMATION pi; STARTUPINFOW si; PyObject* environment; - const wchar_t *wenvironment; - Py_ssize_t wenvironment_size; + wchar_t *wenvironment; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); From 4b1468f723491a6afc0506128b843d3e82771912 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Sat, 24 Jun 2017 18:00:08 -0700 Subject: [PATCH 311/340] [3.5] Check the whitespace of pull requests on Travis (GH-2367) (GH-2387) (cherry picked from commit 70cb1875bb5343e31d7268f4b2d231a5fecdf989) --- .travis.yml | 5 +++++ Tools/scripts/patchcheck.py | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 65d555df749d4d..cf59d965a871d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -88,6 +88,11 @@ before_script: fi script: + # Using the built Python as patchcheck.py is built around the idea of using + # a checkout-build of CPython to know things like what base branch the changes + # should be compared against. + # Only run on Linux as the check only needs to be run once. + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./python Tools/scripts/patchcheck.py --travis $TRAVIS_PULL_REQUEST; fi # `-r -w` implicitly provided through `make buildbottest`. - make buildbottest TESTOPTS="-j4 -uall,-cpu" diff --git a/Tools/scripts/patchcheck.py b/Tools/scripts/patchcheck.py index 33a9fead879325..0aacd9e4f67298 100755 --- a/Tools/scripts/patchcheck.py +++ b/Tools/scripts/patchcheck.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +"""Check proposed changes for common issues.""" import re import sys import shutil @@ -135,7 +136,7 @@ def report_modified_files(file_paths): return "\n".join(lines) -@status("Fixing whitespace", info=report_modified_files) +@status("Fixing Python file whitespace", info=report_modified_files) def normalize_whitespace(file_paths): """Make sure that the whitespace for .py files have been normalized.""" reindent.makebackup = False # No need to create backups. @@ -212,6 +213,27 @@ def regenerated_pyconfig_h_in(file_paths): else: return "not needed" +def travis(pull_request): + if pull_request == 'false': + print('Not a pull request; skipping') + return + base_branch = get_base_branch() + file_paths = changed_files(base_branch) + python_files = [fn for fn in file_paths if fn.endswith('.py')] + c_files = [fn for fn in file_paths if fn.endswith(('.c', '.h'))] + doc_files = [fn for fn in file_paths if fn.startswith('Doc') and + fn.endswith(('.rst', '.inc'))] + fixed = [] + fixed.extend(normalize_whitespace(python_files)) + fixed.extend(normalize_c_whitespace(c_files)) + fixed.extend(normalize_docs_whitespace(doc_files)) + if not fixed: + print('No whitespace issues found') + else: + print('Please fix the file(s) with whitespace issues') + print('(on UNIX you can run `make patchcheck` to make the fixes)') + sys.exit(1) + def main(): base_branch = get_base_branch() file_paths = changed_files(base_branch) @@ -246,4 +268,12 @@ def main(): if __name__ == '__main__': - main() + import argparse + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--travis', + help='Perform pass/fail checks') + args = parser.parse_args() + if args.travis: + travis(args.travis) + else: + main() From 99e9eb6111ef6a11bfff358866c9f2b0c201ac08 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 25 Jun 2017 09:49:40 +0300 Subject: [PATCH 312/340] [3.5] bpo-30746: Prohibited the '=' character in environment variable names (GH-2382) (#2392) in `os.putenv()` and `os.spawn*()`.. (cherry picked from commit 77703942c5997dff00c48f10df1b29b11645624c) --- Lib/test/test_os.py | 77 ++++++++++++++++++++++++++++++++++++++++++ Lib/test/test_posix.py | 15 ++++++++ Misc/NEWS | 3 ++ Modules/posixmodule.c | 28 +++++++++++---- 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 5865783a43e9f2..e9c850793a5d9b 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1501,6 +1501,27 @@ def test_internal_execvpe_str(self): if os.name != "nt": self._test_internal_execvpe(bytes) + def test_execve_invalid_env(self): + args = [sys.executable, '-c', 'pass'] + + # null character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT\0VEGETABLE"] = "cabbage" + with self.assertRaises(ValueError): + os.execve(args[0], args, newenv) + + # null character in the enviroment variable value + newenv = os.environ.copy() + newenv["FRUIT"] = "orange\0VEGETABLE=cabbage" + with self.assertRaises(ValueError): + os.execve(args[0], args, newenv) + + # equal character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT=ORANGE"] = "lemon" + with self.assertRaises(ValueError): + os.execve(args[0], args, newenv) + @unittest.skipUnless(sys.platform == "win32", "Win32 specific tests") class Win32ErrorTests(unittest.TestCase): @@ -2184,6 +2205,62 @@ def test_waitpid(self): self.assertEqual(status, (pid, 0)) +class SpawnTests(unittest.TestCase): + def _test_invalid_env(self, spawn): + args = [sys.executable, '-c', 'pass'] + + # null character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT\0VEGETABLE"] = "cabbage" + try: + exitcode = spawn(os.P_WAIT, args[0], args, newenv) + except ValueError: + pass + else: + self.assertEqual(exitcode, 127) + + # null character in the enviroment variable value + newenv = os.environ.copy() + newenv["FRUIT"] = "orange\0VEGETABLE=cabbage" + try: + exitcode = spawn(os.P_WAIT, args[0], args, newenv) + except ValueError: + pass + else: + self.assertEqual(exitcode, 127) + + # equal character in the enviroment variable name + newenv = os.environ.copy() + newenv["FRUIT=ORANGE"] = "lemon" + try: + exitcode = spawn(os.P_WAIT, args[0], args, newenv) + except ValueError: + pass + else: + self.assertEqual(exitcode, 127) + + # equal character in the enviroment variable value + filename = support.TESTFN + self.addCleanup(support.unlink, filename) + with open(filename, "w") as fp: + fp.write('import sys, os\n' + 'if os.getenv("FRUIT") != "orange=lemon":\n' + ' raise AssertionError') + args = [sys.executable, filename] + newenv = os.environ.copy() + newenv["FRUIT"] = "orange=lemon" + exitcode = spawn(os.P_WAIT, args[0], args, newenv) + self.assertEqual(exitcode, 0) + + @unittest.skipUnless(hasattr(os, 'spawnve'), "test needs os.spawnve") + def test_spawnve_invalid_env(self): + self._test_invalid_env(os.spawnve) + + @unittest.skipUnless(hasattr(os, 'spawnvpe'), "test needs os.spawnvpe") + def test_spawnvpe_invalid_env(self): + self._test_invalid_env(os.spawnvpe) + + # The introduction of this TestCase caused at least two different errors on # *nix buildbots. Temporarily skip this to let the buildbots move along. @unittest.skip("Skip due to platform/environment differences on *NIX buildbots") diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 2a59c381749c80..57f793d1054d10 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -747,6 +747,21 @@ def test_environ(self): self.assertEqual(type(k), item_type) self.assertEqual(type(v), item_type) + @unittest.skipUnless(hasattr(os, "putenv"), "requires os.putenv()") + def test_putenv(self): + with self.assertRaises(ValueError): + os.putenv('FRUIT\0VEGETABLE', 'cabbage') + with self.assertRaises(ValueError): + os.putenv(b'FRUIT\0VEGETABLE', b'cabbage') + with self.assertRaises(ValueError): + os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage') + with self.assertRaises(ValueError): + os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage') + with self.assertRaises(ValueError): + os.putenv('FRUIT=ORANGE', 'lemon') + with self.assertRaises(ValueError): + os.putenv(b'FRUIT=ORANGE', b'lemon') + @unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()') def test_getcwd_long_pathnames(self): dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef' diff --git a/Misc/NEWS b/Misc/NEWS index b731792cde6206..4a8137f55f65ea 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,9 @@ Extension Modules Library ------- +- bpo-30746: Prohibited the '=' character in environment variable names in + ``os.putenv()`` and ``os.spawn*()``. + - [Security] bpo-30730: Prevent environment variables injection in subprocess on Windows. Prevent passing other environment variables and command arguments. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 9dd26f51ed33de..042deaca6f2bb5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4964,8 +4964,14 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) goto error; } - k = PyBytes_AsString(key2); - v = PyBytes_AsString(val2); + k = PyBytes_AS_STRING(key2); + v = PyBytes_AS_STRING(val2); + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (*k == '\0' || strchr(k + 1, '=') != NULL) { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + goto error; + } len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2; p = PyMem_NEW(char, len); @@ -9069,9 +9075,16 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) { wchar_t *env; + /* Search from index 1 because on Windows starting '=' is allowed for + defining hidden environment variables. */ + if (PyUnicode_GET_LENGTH(name) == 0 || + PyUnicode_FindChar(name, '=', 1, PyUnicode_GET_LENGTH(name), 1) != -1) + { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + return NULL; + } PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value); if (unicode == NULL) { - PyErr_NoMemory(); return NULL; } if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { @@ -9113,12 +9126,15 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) { PyObject *bytes = NULL; char *env; - char *name_string = PyBytes_AsString(name); - char *value_string = PyBytes_AsString(value); + const char *name_string = PyBytes_AS_STRING(name); + const char *value_string = PyBytes_AS_STRING(value); + if (strchr(name_string, '=') != NULL) { + PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); + return NULL; + } bytes = PyBytes_FromFormat("%s=%s", name_string, value_string); if (bytes == NULL) { - PyErr_NoMemory(); return NULL; } From 849b062a82ca2f09e33259d34067faba196c9e23 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 26 Jun 2017 18:05:21 +0200 Subject: [PATCH 313/340] bpo-30764: test_subprocess uses SuppressCrashReport (#2405) (#2411) bpo-30764, bpo-29335: test_child_terminated_in_stopped_state() of test_subprocess now uses support.SuppressCrashReport() to prevent the creation of a core dump on FreeBSD. (cherry picked from commit cdee3f14f7f4c995e7eedb0bf6a67e260c739f7d) --- Lib/test/test_subprocess.py | 51 ++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 804c8f44e9a3d6..45b7ce471f45b8 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -25,6 +25,8 @@ import ctypes except ImportError: ctypes = None +else: + import ctypes.util try: import threading @@ -2505,43 +2507,40 @@ def test_communicate_BrokenPipeError_stdin_close_with_timeout(self): proc.communicate(timeout=999) mock_proc_stdin.close.assert_called_once_with() - _libc_file_extensions = { - 'Linux': 'so.6', - 'Darwin': 'dylib', - } - @unittest.skipIf(not ctypes, 'ctypes module required.') - @unittest.skipIf(platform.uname()[0] not in _libc_file_extensions, - 'Test requires a libc this code can load with ctypes.') - @unittest.skipIf(not sys.executable, 'Test requires sys.executable.') + @unittest.skipIf(not ctypes, 'ctypes module required') + @unittest.skipIf(not sys.executable, 'Test requires sys.executable') def test_child_terminated_in_stopped_state(self): """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335.""" PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME). - libc_name = 'libc.' + self._libc_file_extensions[platform.uname()[0]] + libc_name = ctypes.util.find_library('c') libc = ctypes.CDLL(libc_name) if not hasattr(libc, 'ptrace'): - raise unittest.SkipTest('ptrace() required.') - test_ptrace = subprocess.Popen( - [sys.executable, '-c', """if True: - import ctypes - libc = ctypes.CDLL({libc_name!r}) - libc.ptrace({PTRACE_TRACEME}, 0, 0) - """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) - ]) - if test_ptrace.wait() != 0: - raise unittest.SkipTest('ptrace() failed - unable to test.') - child = subprocess.Popen( - [sys.executable, '-c', """if True: + raise unittest.SkipTest('ptrace() required') + + code = textwrap.dedent(""" import ctypes + import faulthandler + from test.support import SuppressCrashReport + libc = ctypes.CDLL({libc_name!r}) libc.ptrace({PTRACE_TRACEME}, 0, 0) - libc.printf(ctypes.c_char_p(0xdeadbeef)) # Crash the process. - """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME) - ]) + """.format(libc_name=libc_name, PTRACE_TRACEME=PTRACE_TRACEME)) + + child = subprocess.Popen([sys.executable, '-c', code]) + if child.wait() != 0: + raise unittest.SkipTest('ptrace() failed - unable to test') + + code += textwrap.dedent(""" + with SuppressCrashReport(): + # Crash the process + faulthandler._sigsegv() + """) + child = subprocess.Popen([sys.executable, '-c', code]) try: returncode = child.wait() - except Exception as e: + except: child.kill() # Clean up the hung stopped process. - raise e + raise self.assertNotEqual(0, returncode) self.assertLess(returncode, 0) # signal death, likely SIGSEGV. From 85b34edd8b575b918490afbcb0db6f791874dbdd Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 26 Jun 2017 22:07:20 +0200 Subject: [PATCH 314/340] [3.5] bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to (GH-2403) (#2419) * bpo-30765: Avoid blocking when PyThread_acquire_lock() is asked not to lock This is especially important if PyThread_acquire_lock() is called reentrantly (for example from a signal handler). * Update 2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst * Avoid core logic when taking the mutex failed. (cherry picked from commit f84ac420c2af98339678744953869cad3c253281) --- .../2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst | 2 + Python/thread_pthread.h | 95 ++++++++++--------- 2 files changed, 52 insertions(+), 45 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst b/Misc/NEWS.d/next/Core and Builtins/2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst new file mode 100644 index 00000000000000..08d76cb965e369 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-06-26-14-29-50.bpo-30765.Q5iBmf.rst @@ -0,0 +1,2 @@ +Avoid blocking in pthread_mutex_lock() when PyThread_acquire_lock() is asked +not to block. diff --git a/Python/thread_pthread.h b/Python/thread_pthread.h index 27e0dc84bcb52e..8e422624c3590f 100644 --- a/Python/thread_pthread.h +++ b/Python/thread_pthread.h @@ -464,61 +464,66 @@ PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, int intr_flag) { - PyLockStatus success; + PyLockStatus success = PY_LOCK_FAILURE; pthread_lock *thelock = (pthread_lock *)lock; int status, error = 0; dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) called\n", lock, microseconds, intr_flag)); - status = pthread_mutex_lock( &thelock->mut ); - CHECK_STATUS("pthread_mutex_lock[1]"); - - if (thelock->locked == 0) { - success = PY_LOCK_ACQUIRED; - } else if (microseconds == 0) { - success = PY_LOCK_FAILURE; - } else { - struct timespec ts; - if (microseconds > 0) - MICROSECONDS_TO_TIMESPEC(microseconds, ts); - /* continue trying until we get the lock */ - - /* mut must be locked by me -- part of the condition - * protocol */ - success = PY_LOCK_FAILURE; - while (success == PY_LOCK_FAILURE) { - if (microseconds > 0) { - status = pthread_cond_timedwait( - &thelock->lock_released, - &thelock->mut, &ts); - if (status == ETIMEDOUT) + if (microseconds == 0) { + status = pthread_mutex_trylock( &thelock->mut ); + if (status != EBUSY) + CHECK_STATUS("pthread_mutex_trylock[1]"); + } + else { + status = pthread_mutex_lock( &thelock->mut ); + CHECK_STATUS("pthread_mutex_lock[1]"); + } + if (status == 0) { + if (thelock->locked == 0) { + success = PY_LOCK_ACQUIRED; + } + else if (microseconds != 0) { + struct timespec ts; + if (microseconds > 0) + MICROSECONDS_TO_TIMESPEC(microseconds, ts); + /* continue trying until we get the lock */ + + /* mut must be locked by me -- part of the condition + * protocol */ + while (success == PY_LOCK_FAILURE) { + if (microseconds > 0) { + status = pthread_cond_timedwait( + &thelock->lock_released, + &thelock->mut, &ts); + if (status == ETIMEDOUT) + break; + CHECK_STATUS("pthread_cond_timed_wait"); + } + else { + status = pthread_cond_wait( + &thelock->lock_released, + &thelock->mut); + CHECK_STATUS("pthread_cond_wait"); + } + + if (intr_flag && status == 0 && thelock->locked) { + /* We were woken up, but didn't get the lock. We probably received + * a signal. Return PY_LOCK_INTR to allow the caller to handle + * it and retry. */ + success = PY_LOCK_INTR; break; - CHECK_STATUS("pthread_cond_timed_wait"); - } - else { - status = pthread_cond_wait( - &thelock->lock_released, - &thelock->mut); - CHECK_STATUS("pthread_cond_wait"); - } - - if (intr_flag && status == 0 && thelock->locked) { - /* We were woken up, but didn't get the lock. We probably received - * a signal. Return PY_LOCK_INTR to allow the caller to handle - * it and retry. */ - success = PY_LOCK_INTR; - break; - } else if (status == 0 && !thelock->locked) { - success = PY_LOCK_ACQUIRED; - } else { - success = PY_LOCK_FAILURE; + } + else if (status == 0 && !thelock->locked) { + success = PY_LOCK_ACQUIRED; + } } } + if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; + status = pthread_mutex_unlock( &thelock->mut ); + CHECK_STATUS("pthread_mutex_unlock[1]"); } - if (success == PY_LOCK_ACQUIRED) thelock->locked = 1; - status = pthread_mutex_unlock( &thelock->mut ); - CHECK_STATUS("pthread_mutex_unlock[1]"); if (error) success = PY_LOCK_FAILURE; dprintf(("PyThread_acquire_lock_timed(%p, %lld, %d) -> %d\n", From eef254d6c6b13db2f3d6a2f219bc76e84416f59c Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 27 Jun 2017 14:03:12 +0200 Subject: [PATCH 315/340] bpo-30383: Add NEWS entry for backported regrtest (#2438) --- .../Tests/2017-06-27-13-52-43.bpo-30383.rCmrv7.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2017-06-27-13-52-43.bpo-30383.rCmrv7.rst diff --git a/Misc/NEWS.d/next/Tests/2017-06-27-13-52-43.bpo-30383.rCmrv7.rst b/Misc/NEWS.d/next/Tests/2017-06-27-13-52-43.bpo-30383.rCmrv7.rst new file mode 100644 index 00000000000000..046e8c9cc03e45 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2017-06-27-13-52-43.bpo-30383.rCmrv7.rst @@ -0,0 +1,14 @@ +regrtest: Enhance regrtest and backport features from the master branch. + +Add options: --coverage, --testdir, --list-tests (list test files, don't run +them), --list-cases (list test identifiers, don't run them, :issue:`30523`), +--matchfile (load a list of test filters from a text file, :issue:`30540`), +--slowest (alias to --slow). + +Enhance output: add timestamp, test result, currently running tests, "Tests +result: xxx" summary with total duration, etc. + +Fix reference leak hunting in regrtest, --huntrleaks: regrtest now warms up +caches, create explicitly all internal singletons which are created on +demand to prevent false positives when checking for reference leaks. +(:issue:`30675`). From de1850bb03f8225cbff85f437b6e972bf9b68c2a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 27 Jun 2017 16:35:18 +0200 Subject: [PATCH 316/340] [3.5] bpo-30523, bpo-30764, bpo-30776: Sync regrtest from master (#2442) * bpo-30523: regrtest --list-cases --match (#2401) * regrtest --list-cases now supports --match and --match-file options. Example: ./python -m test --list-cases -m FileTests test_os * --list-cases now also sets support.verbose to False to prevent messages to stdout when loading test modules. * Add support._match_test() private function. (cherry picked from commit ace56d583664f855d89d1219ece7c21c2fddcf30) * bpo-30764: regrtest: add --fail-env-changed option (#2402) * bpo-30764: regrtest: change exit code on failure * Exit code 2 if failed tests ("bad") * Exit code 3 if interrupted * bpo-30764: regrtest: add --fail-env-changed option If the option is set, mark a test as failed if it alters the environment, for example if it creates a file without removing it. (cherry picked from commit 63f54c68936d648c70ca411661e4208329edcf26) * bpo-30776: reduce regrtest -R false positives (#2422) * Change the regrtest --huntrleaks checker to decide if a test file leaks or not. Require that each run leaks at least 1 reference. * Warmup runs are now completely ignored: ignored in the checker test and not used anymore to compute the sum. * Add an unit test for a reference leak. Example of reference differences previously considered a failure (leak) and now considered as success (success, no leak): [3, 0, 0] [0, 1, 0] [8, -8, 1] (cherry picked from commit 48b5c422ffb03affb00c184b9a99e5537be92732) --- Lib/test/regrtest.py | 40 +++++++++++++-- Lib/test/support/__init__.py | 32 ++++++------ Lib/test/test_regrtest.py | 94 +++++++++++++++++++++++++++++++----- 3 files changed, 135 insertions(+), 31 deletions(-) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 299416cf24c8d4..339beb1f854b5b 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -343,6 +343,9 @@ def _create_parser(): ' , don\'t execute them') group.add_argument('-P', '--pgo', dest='pgo', action='store_true', help='enable Profile Guided Optimization training') + group.add_argument('--fail-env-changed', action='store_true', + help='if a test file alters the environment, mark ' + 'the test as failed') return parser @@ -944,11 +947,19 @@ def runtest_accumulate(): result = "FAILURE" elif interrupted: result = "INTERRUPTED" + elif environment_changed and ns.fail_env_changed: + result = "ENV CHANGED" else: result = "SUCCESS" print("Tests result: %s" % result) - sys.exit(len(bad) > 0 or interrupted) + if bad: + sys.exit(2) + if interrupted: + sys.exit(130) + if ns.fail_env_changed and environment_changed: + sys.exit(3) + sys.exit(0) # small set of tests to determine if we have a basically functioning interpreter @@ -1510,9 +1521,21 @@ def dash_R(the_module, test, indirect_test, huntrleaks): alloc_deltas[i] = alloc_after - alloc_before alloc_before, rc_before = alloc_after, rc_after print(file=sys.stderr) + # These checkers return False on success, True on failure def check_rc_deltas(deltas): - return any(deltas) + # bpo-30776: Try to ignore false positives: + # + # [3, 0, 0] + # [0, 1, 0] + # [8, -8, 1] + # + # Expected leaks: + # + # [5, 5, 6] + # [10, 1, 1] + return all(delta >= 1 for delta in deltas) + def check_alloc_deltas(deltas): # At least 1/3rd of 0s if 3 * deltas.count(0) < len(deltas): @@ -1524,10 +1547,13 @@ def check_alloc_deltas(deltas): failed = False for deltas, item_name, checker in [ (rc_deltas, 'references', check_rc_deltas), - (alloc_deltas, 'memory blocks', check_alloc_deltas)]: + (alloc_deltas, 'memory blocks', check_alloc_deltas) + ]: + # ignore warmup runs + deltas = deltas[nwarmup:] if checker(deltas): msg = '%s leaked %s %s, sum=%s' % ( - test, deltas[nwarmup:], item_name, sum(deltas)) + test, deltas, item_name, sum(deltas)) print(msg, file=sys.stderr) sys.stderr.flush() with open(fname, "a") as refrep: @@ -1735,10 +1761,14 @@ def _list_cases(suite): if isinstance(test, unittest.TestSuite): _list_cases(test) elif isinstance(test, unittest.TestCase): - print(test.id()) + if support._match_test(test): + print(test.id()) def list_cases(ns, selected): + support.verbose = False + support.match_tests = ns.match_tests + skipped = [] for test in selected: abstest = get_abs_module(ns, test) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 92599b31e208fd..85878eb6ef2f20 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1866,6 +1866,23 @@ def _run_suite(suite): raise TestFailed(err) +def _match_test(test): + global match_tests + + if match_tests is None: + return True + test_id = test.id() + + for match_test in match_tests: + if fnmatch.fnmatchcase(test_id, match_test): + return True + + for name in test_id.split("."): + if fnmatch.fnmatchcase(name, match_test): + return True + return False + + def run_unittest(*classes): """Run tests from unittest.TestCase-derived classes.""" valid_types = (unittest.TestSuite, unittest.TestCase) @@ -1880,20 +1897,7 @@ def run_unittest(*classes): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) - def case_pred(test): - if match_tests is None: - return True - test_id = test.id() - - for match_test in match_tests: - if fnmatch.fnmatchcase(test_id, match_test): - return True - - for name in test_id.split("."): - if fnmatch.fnmatchcase(name, match_test): - return True - return False - _filter_suite(suite, case_pred) + _filter_suite(suite, _match_test) _run_suite(suite) #======================================================================= diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 3568004b176b17..0eb3f08fe7b21a 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -377,19 +377,19 @@ def parse_executed_tests(self, output): return list(match.group(1) for match in parser) def check_executed_tests(self, output, tests, skipped=(), failed=(), - omitted=(), randomize=False, interrupted=False): + env_changed=(), omitted=(), + randomize=False, interrupted=False, + fail_env_changed=False): if isinstance(tests, str): tests = [tests] if isinstance(skipped, str): skipped = [skipped] if isinstance(failed, str): failed = [failed] + if isinstance(env_changed, str): + env_changed = [env_changed] if isinstance(omitted, str): omitted = [omitted] - ntest = len(tests) - nskipped = len(skipped) - nfailed = len(failed) - nomitted = len(omitted) executed = self.parse_executed_tests(output) if randomize: @@ -415,11 +415,17 @@ def list_regex(line_format, tests): regex = list_regex('%s test%s failed', failed) self.check_line(output, regex) + if env_changed: + regex = list_regex('%s test%s altered the execution environment', + env_changed) + self.check_line(output, regex) + if omitted: regex = list_regex('%s test%s omitted', omitted) self.check_line(output, regex) - good = ntest - nskipped - nfailed - nomitted + good = (len(tests) - len(skipped) - len(failed) + - len(omitted) - len(env_changed)) if good: regex = r'%s test%s OK\.$' % (good, plural(good)) if not skipped and not failed and good > 1: @@ -429,10 +435,12 @@ def list_regex(line_format, tests): if interrupted: self.check_line(output, 'Test suite interrupted by signal SIGINT.') - if nfailed: + if failed: result = 'FAILURE' elif interrupted: result = 'INTERRUPTED' + elif fail_env_changed and env_changed: + result = 'ENV CHANGED' else: result = 'SUCCESS' self.check_line(output, 'Tests result: %s' % result) @@ -604,7 +612,7 @@ def test_failing(self): test_failing = self.create_test('failing', code=code) tests = [test_ok, test_failing] - output = self.run_tests(*tests, exitcode=1) + output = self.run_tests(*tests, exitcode=2) self.check_executed_tests(output, tests, failed=test_failing) def test_resources(self): @@ -703,7 +711,7 @@ def test_fromfile(self): def test_interrupted(self): code = TEST_INTERRUPTED test = self.create_test('sigint', code=code) - output = self.run_tests(test, exitcode=1) + output = self.run_tests(test, exitcode=130) self.check_executed_tests(output, test, omitted=test, interrupted=True) @@ -732,7 +740,7 @@ def test_slow_interrupted(self): args = ("--slowest", "-j2", test) else: args = ("--slowest", test) - output = self.run_tests(*args, exitcode=1) + output = self.run_tests(*args, exitcode=130) self.check_executed_tests(output, test, omitted=test, interrupted=True) @@ -772,9 +780,43 @@ def test_run(self): builtins.__dict__['RUN'] = 1 """) test = self.create_test('forever', code=code) - output = self.run_tests('--forever', test, exitcode=1) + output = self.run_tests('--forever', test, exitcode=2) self.check_executed_tests(output, [test]*3, failed=test) + def check_leak(self, code, what): + test = self.create_test('huntrleaks', code=code) + + filename = 'reflog.txt' + self.addCleanup(support.unlink, filename) + output = self.run_tests('--huntrleaks', '3:3:', test, + exitcode=2, + stderr=subprocess.STDOUT) + self.check_executed_tests(output, [test], failed=test) + + line = 'beginning 6 repetitions\n123456\n......\n' + self.check_line(output, re.escape(line)) + + line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what) + self.assertIn(line2, output) + + with open(filename) as fp: + reflog = fp.read() + self.assertIn(line2, reflog) + + @unittest.skipUnless(Py_DEBUG, 'need a debug build') + def test_huntrleaks(self): + # test --huntrleaks + code = textwrap.dedent(""" + import unittest + + GLOBAL_LIST = [] + + class RefLeakTest(unittest.TestCase): + def test_leak(self): + GLOBAL_LIST.append(object()) + """) + self.check_leak(code, 'references') + def test_list_tests(self): # test --list-tests tests = [self.create_test() for i in range(5)] @@ -794,11 +836,20 @@ def test_method2(self): pass """) testname = self.create_test(code=code) + + # Test --list-cases all_methods = ['%s.Tests.test_method1' % testname, '%s.Tests.test_method2' % testname] output = self.run_tests('--list-cases', testname) self.assertEqual(output.splitlines(), all_methods) + # Test --list-cases with --match + all_methods = ['%s.Tests.test_method1' % testname] + output = self.run_tests('--list-cases', + '-m', 'test_method1', + testname) + self.assertEqual(output.splitlines(), all_methods) + def test_crashed(self): # Any code which causes a crash code = 'import faulthandler; faulthandler._sigsegv()' @@ -806,7 +857,7 @@ def test_crashed(self): ok_test = self.create_test(name="ok") tests = [crash_test, ok_test] - output = self.run_tests("-j2", *tests, exitcode=1) + output = self.run_tests("-j2", *tests, exitcode=2) self.check_executed_tests(output, tests, failed=crash_test, randomize=True) @@ -855,6 +906,25 @@ def test_method4(self): subset = ['test_method1', 'test_method3'] self.assertEqual(methods, subset) + def test_env_changed(self): + code = textwrap.dedent(""" + import unittest + + class Tests(unittest.TestCase): + def test_env_changed(self): + open("env_changed", "w").close() + """) + testname = self.create_test(code=code) + + # don't fail by default + output = self.run_tests(testname) + self.check_executed_tests(output, [testname], env_changed=testname) + + # fail with --fail-env-changed + output = self.run_tests("--fail-env-changed", testname, exitcode=3) + self.check_executed_tests(output, [testname], env_changed=testname, + fail_env_changed=True) + if __name__ == '__main__': unittest.main() From eb3c52a0d273491e745e0cbff2b73900bb96aa45 Mon Sep 17 00:00:00 2001 From: Emily Morehouse Date: Tue, 27 Jun 2017 10:08:47 -0600 Subject: [PATCH 317/340] [3.5] bpo-30769: Fix reference leak introduced in 7770394 (GH-2416) (#2447) --- Modules/posixmodule.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 042deaca6f2bb5..8d32ddf131ce72 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -4969,6 +4969,8 @@ parse_envlist(PyObject* env, Py_ssize_t *envc_ptr) /* Search from index 1 because on Windows starting '=' is allowed for defining hidden environment variables. */ if (*k == '\0' || strchr(k + 1, '=') != NULL) { + Py_DECREF(key2); + Py_DECREF(val2); PyErr_SetString(PyExc_ValueError, "illegal environment variable name"); goto error; } From 94b169fe48bc7ea76b926823885d1b12c2c381fa Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 27 Jun 2017 21:52:10 +0300 Subject: [PATCH 318/340] [3.5] bpo-30708: Add private C API function _PyUnicode_AsWideCharString(). (GH-2285) (GH-2443) (#2448) And use it instead of PyUnicode_AsWideCharString() if appropriate. _PyUnicode_AsWideCharString(unicode) is like PyUnicode_AsWideCharString(unicode, NULL), but raises a ValueError if the wchar_t* string contains null characters. (cherry picked from commit e613e6add5f07ff6aad5802924596b631b707d2a). (cherry picked from commit 0edffa3073b551ffeca34952529e7b292f1bd350) --- Include/unicodeobject.h | 6 ++++++ Lib/ctypes/test/test_slicing.py | 4 ++-- Modules/_ctypes/callproc.c | 2 +- Modules/_ctypes/cfield.c | 2 +- Modules/_cursesmodule.c | 2 +- Modules/_localemodule.c | 4 ++-- Modules/_tkinter.c | 2 +- Modules/overlapped.c | 2 +- Modules/timemodule.c | 2 +- Objects/unicodeobject.c | 31 +++++++++++++++++++++++++++++++ 10 files changed, 47 insertions(+), 10 deletions(-) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 59dcf736b1b2b3..0e44808050220f 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1054,6 +1054,12 @@ PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( ); #ifndef Py_LIMITED_API +/* Similar to PyUnicode_AsWideCharString(unicode, NULL), but check if + the string contains null characters. */ +PyAPI_FUNC(wchar_t*) _PyUnicode_AsWideCharString( + PyObject *unicode /* Unicode object */ + ); + PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind); #endif diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py index 240dc0cdda2462..a3932f176728af 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/ctypes/test/test_slicing.py @@ -134,7 +134,7 @@ def test_wchar_ptr(self): dll.my_wcsdup.restype = POINTER(c_wchar) dll.my_wcsdup.argtypes = POINTER(c_wchar), dll.my_free.restype = None - res = dll.my_wcsdup(s) + res = dll.my_wcsdup(s[:-1]) self.assertEqual(res[:len(s)], s) self.assertEqual(res[:len(s):], s) self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) @@ -153,7 +153,7 @@ def test_wchar_ptr(self): dll.my_wcsdup.restype = POINTER(c_long) else: self.skipTest('Pointers to c_wchar are not supported') - res = dll.my_wcsdup(s) + res = dll.my_wcsdup(s[:-1]) tmpl = list(range(ord("a"), ord("z")+1)) self.assertEqual(res[:len(s)-1], tmpl) self.assertEqual(res[:len(s)-1:], tmpl) diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index abd3bc995d3e93..873df8b7bdb88c 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -672,7 +672,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) #ifdef CTYPES_UNICODE if (PyUnicode_Check(obj)) { pa->ffi_type = &ffi_type_pointer; - pa->value.p = PyUnicode_AsWideCharString(obj, NULL); + pa->value.p = _PyUnicode_AsWideCharString(obj); if (pa->value.p == NULL) return -1; pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index d666be5d925fe2..cb5c3ce8ea995c 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1386,7 +1386,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) /* We must create a wchar_t* buffer from the unicode object, and keep it alive */ - buffer = PyUnicode_AsWideCharString(value, NULL); + buffer = _PyUnicode_AsWideCharString(value); if (!buffer) return NULL; keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 896d40d38e40af..26d27317d03f2c 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -345,7 +345,7 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, if (PyUnicode_Check(obj)) { #ifdef HAVE_NCURSESW assert (wstr != NULL); - *wstr = PyUnicode_AsWideCharString(obj, NULL); + *wstr = _PyUnicode_AsWideCharString(obj); if (*wstr == NULL) return 0; return 2; diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index b1307ef26b2a8e..4ce71debcf8e4a 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -215,10 +215,10 @@ PyLocale_strcoll(PyObject* self, PyObject* args) if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) return NULL; /* Convert the unicode strings to wchar[]. */ - ws1 = PyUnicode_AsWideCharString(os1, NULL); + ws1 = _PyUnicode_AsWideCharString(os1); if (ws1 == NULL) goto done; - ws2 = PyUnicode_AsWideCharString(os2, NULL); + ws2 = _PyUnicode_AsWideCharString(os2); if (ws2 == NULL) goto done; /* Collate the strings. */ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 163c87f8b98360..34f2d096b27415 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3620,7 +3620,7 @@ PyInit__tkinter(void) return NULL; } if (str_path != NULL) { - wcs_path = PyUnicode_AsWideCharString(str_path, NULL); + wcs_path = _PyUnicode_AsWideCharString(str_path); if (wcs_path == NULL) { return NULL; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index f85e5bc73641fb..3b31d11a7b151a 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1151,7 +1151,7 @@ ConnectPipe(OverlappedObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U", &AddressObj)) return NULL; - Address = PyUnicode_AsWideCharString(AddressObj, NULL); + Address = _PyUnicode_AsWideCharString(AddressObj); if (Address == NULL) return NULL; diff --git a/Modules/timemodule.c b/Modules/timemodule.c index d2caacdc6dd8dd..252fdcfb2c9300 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -596,7 +596,7 @@ time_strftime(PyObject *self, PyObject *args) buf.tm_isdst = 1; #ifdef HAVE_WCSFTIME - format = PyUnicode_AsWideCharString(format_arg, NULL); + format = _PyUnicode_AsWideCharString(format_arg); if (format == NULL) return NULL; fmt = format; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index d037d80b3d222e..64375da602d11f 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -2839,6 +2839,37 @@ PyUnicode_AsWideCharString(PyObject *unicode, return buffer; } +wchar_t* +_PyUnicode_AsWideCharString(PyObject *unicode) +{ + const wchar_t *wstr; + wchar_t *buffer; + Py_ssize_t buflen; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + wstr = PyUnicode_AsUnicodeAndSize(unicode, &buflen); + if (wstr == NULL) { + return NULL; + } + if (wcslen(wstr) != (size_t)buflen) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + return NULL; + } + + buffer = PyMem_NEW(wchar_t, buflen + 1); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(buffer, wstr, (buflen + 1) * sizeof(wchar_t)); + return buffer; +} + #endif /* HAVE_WCHAR_H */ PyObject * From 9dff523e42a5f8eca8e88151785be54468e57969 Mon Sep 17 00:00:00 2001 From: regexaurus Date: Tue, 27 Jun 2017 22:37:05 -0400 Subject: [PATCH 319/340] Clarification to the `break` statement (GH-2453) (GH-2458) Clarify that the break statement breaks out of the innermost enclosing for or while loop. (cherry picked from commit 36fc896740319d2c03aa2054a90a999c162517ef) --- Doc/tutorial/controlflow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial/controlflow.rst b/Doc/tutorial/controlflow.rst index fbe4e924f0c5b9..6af72822fcd72b 100644 --- a/Doc/tutorial/controlflow.rst +++ b/Doc/tutorial/controlflow.rst @@ -154,7 +154,7 @@ Later we will see more functions that return iterables and take iterables as arg :keyword:`break` and :keyword:`continue` Statements, and :keyword:`else` Clauses on Loops ========================================================================================= -The :keyword:`break` statement, like in C, breaks out of the smallest enclosing +The :keyword:`break` statement, like in C, breaks out of the innermost enclosing :keyword:`for` or :keyword:`while` loop. Loop statements may have an ``else`` clause; it is executed when the loop From 54ba940abc2fabb94fede46dfad80f8ac15632a3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 28 Jun 2017 10:31:00 +0300 Subject: [PATCH 320/340] [3.5] bpo-13617: Reject embedded null characters in wchar* strings. (GH-2302) (#2463) Based on patch by Victor Stinner. Add private C API function _PyUnicode_AsUnicode() which is similar to PyUnicode_AsUnicode(), but checks for null characters.. (cherry picked from commit f7eae0adfcd4c50034281b2c69f461b43b68db84) --- Include/unicodeobject.h | 10 +++++++--- Lib/ctypes/test/test_loading.py | 2 ++ Lib/test/test_builtin.py | 6 ++++++ Lib/test/test_curses.py | 11 ++++++++++- Lib/test/test_grp.py | 2 ++ Lib/test/test_imp.py | 4 ++++ Lib/test/test_locale.py | 5 +++++ Lib/test/test_time.py | 4 ++++ Lib/test/test_winsound.py | 4 ++++ Modules/_ctypes/callproc.c | 7 ++++--- Modules/_cursesmodule.c | 9 +++++++++ Modules/_localemodule.c | 5 +++++ Modules/grpmodule.c | 1 + Modules/nismodule.c | 1 + Modules/posixmodule.c | 24 +++++++++++++++--------- Modules/pwdmodule.c | 1 + Modules/spwdmodule.c | 1 + Objects/unicodeobject.c | 14 ++++++++++++++ PC/_msi.c | 6 +++++- Python/dynload_win.c | 4 ++-- Python/fileutils.c | 23 +++++++++++++++++------ 21 files changed, 119 insertions(+), 25 deletions(-) diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 0e44808050220f..f0ececc6a4a87a 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -764,23 +764,27 @@ PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4( exception set. */ PyAPI_FUNC(Py_UCS4*) PyUnicode_AsUCS4Copy(PyObject *unicode); +#ifndef Py_LIMITED_API /* Return a read-only pointer to the Unicode object's internal Py_UNICODE buffer. If the wchar_t/Py_UNICODE representation is not yet available, this function will calculate it. */ -#ifndef Py_LIMITED_API PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicode( PyObject *unicode /* Unicode object */ ); -#endif + +/* Similar to PyUnicode_AsUnicode(), but raises a ValueError if the string + contains null characters. */ +PyAPI_FUNC(const Py_UNICODE *) _PyUnicode_AsUnicode( + PyObject *unicode /* Unicode object */ + ); /* Return a read-only pointer to the Unicode object's internal Py_UNICODE buffer and save the length at size. If the wchar_t/Py_UNICODE representation is not yet available, this function will calculate it. */ -#ifndef Py_LIMITED_API PyAPI_FUNC(Py_UNICODE *) PyUnicode_AsUnicodeAndSize( PyObject *unicode, /* Unicode object */ Py_ssize_t *size /* location where to save the length */ diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 28468c1cd3d57b..3de457f4c3223e 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -64,6 +64,8 @@ def test_load_library(self): windll["kernel32"].GetModuleHandleW windll.LoadLibrary("kernel32").GetModuleHandleW WinDLL("kernel32").GetModuleHandleW + # embedded null character + self.assertRaises(ValueError, windll.LoadLibrary, "kernel32\0") elif os.name == "ce": windll.coredll.GetModuleHandleW windll["coredll"].GetModuleHandleW diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py index 0b033408a8c4a2..18e80c72918114 100644 --- a/Lib/test/test_builtin.py +++ b/Lib/test/test_builtin.py @@ -151,6 +151,8 @@ def test_import(self): self.assertRaises(TypeError, __import__, 1, 2, 3, 4) self.assertRaises(ValueError, __import__, '') self.assertRaises(TypeError, __import__, 'sys', name='sys') + # embedded null character + self.assertRaises((ImportError, ValueError), __import__, 'string\x00') def test_abs(self): # int @@ -1002,6 +1004,10 @@ def test_open(self): self.assertEqual(fp.read(300), 'XXX'*100) self.assertEqual(fp.read(1000), 'YYY'*100) + # embedded null bytes and characters + self.assertRaises(ValueError, open, 'a\x00b') + self.assertRaises(ValueError, open, b'a\x00b') + def test_open_default_encoding(self): old_environ = dict(os.environ) try: diff --git a/Lib/test/test_curses.py b/Lib/test/test_curses.py index 3d8c50bcb6c6ae..0d0b160d7645a5 100644 --- a/Lib/test/test_curses.py +++ b/Lib/test/test_curses.py @@ -81,7 +81,7 @@ def test_window_funcs(self): win2 = curses.newwin(15,15, 5,5) for meth in [stdscr.addch, stdscr.addstr]: - for args in [('a'), ('a', curses.A_BOLD), + for args in [('a',), ('a', curses.A_BOLD), (4,4, 'a'), (5,5, 'a', curses.A_BOLD)]: with self.subTest(meth=meth.__qualname__, args=args): meth(*args) @@ -194,6 +194,15 @@ def test_window_funcs(self): self.assertRaises(ValueError, stdscr.instr, -2) self.assertRaises(ValueError, stdscr.instr, 2, 3, -2) + def test_embedded_null_chars(self): + # reject embedded null bytes and characters + stdscr = self.stdscr + for arg in ['a', b'a']: + with self.subTest(arg=arg): + self.assertRaises(ValueError, stdscr.addstr, 'a\0') + self.assertRaises(ValueError, stdscr.addnstr, 'a\0', 1) + self.assertRaises(ValueError, stdscr.insstr, 'a\0') + self.assertRaises(ValueError, stdscr.insnstr, 'a\0', 1) def test_module_funcs(self): "Test module-level functions" diff --git a/Lib/test/test_grp.py b/Lib/test/test_grp.py index 272b08615dcc22..c218ea32551e56 100644 --- a/Lib/test/test_grp.py +++ b/Lib/test/test_grp.py @@ -50,6 +50,8 @@ def test_errors(self): self.assertRaises(TypeError, grp.getgrgid) self.assertRaises(TypeError, grp.getgrnam) self.assertRaises(TypeError, grp.getgrall, 42) + # embedded null character + self.assertRaises(ValueError, grp.getgrnam, 'a\x00b') # try to get some errors bynames = {} diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index ee9ee1ad8c3bcc..433de34c264551 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -315,6 +315,10 @@ def test_multiple_calls_to_get_data(self): loader.get_data(imp.__file__) # File should be closed loader.get_data(imp.__file__) # Will need to create a newly opened file + def test_load_source(self): + with self.assertRaisesRegex(ValueError, 'embedded null'): + imp.load_source(__name__, __file__ + "\0") + class ReloadTests(unittest.TestCase): diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py index fae2c3dabb370d..8d40a94e3eb178 100644 --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -339,9 +339,14 @@ def test_strcoll(self): self.assertLess(locale.strcoll('a', 'b'), 0) self.assertEqual(locale.strcoll('a', 'a'), 0) self.assertGreater(locale.strcoll('b', 'a'), 0) + # embedded null character + self.assertRaises(ValueError, locale.strcoll, 'a\0', 'a') + self.assertRaises(ValueError, locale.strcoll, 'a', 'a\0') def test_strxfrm(self): self.assertLess(locale.strxfrm('a'), locale.strxfrm('b')) + # embedded null character + self.assertRaises(ValueError, locale.strxfrm, 'a\0') class TestEnUSCollation(BaseLocalizedTest, TestCollation): diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py index 76b894eece46e0..04962b223e88a4 100644 --- a/Lib/test/test_time.py +++ b/Lib/test/test_time.py @@ -114,6 +114,10 @@ def test_strftime(self): except ValueError: self.fail('conversion specifier: %r failed.' % format) + self.assertRaises(TypeError, time.strftime, b'%S', tt) + # embedded null character + self.assertRaises(ValueError, time.strftime, '%S\0', tt) + def _bounds_checking(self, func): # Make sure that strftime() checks the bounds of the various parts # of the time tuple (0 is valid for *all* values). diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 4a8ab7de582c10..caac3c3c18c922 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -87,6 +87,10 @@ def test_errors(self): winsound.PlaySound, "none", winsound.SND_ASYNC | winsound.SND_MEMORY ) + self.assertRaises(TypeError, winsound.PlaySound, b"bad", 0) + self.assertRaises(TypeError, winsound.PlaySound, 1, 0) + # embedded null character + self.assertRaises(ValueError, winsound.PlaySound, 'bad\0', 0) def test_aliases(self): aliases = [ diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 873df8b7bdb88c..70e416b950b0ec 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1235,14 +1235,15 @@ The handle may be used to locate exported functions in this\n\ module.\n"; static PyObject *load_library(PyObject *self, PyObject *args) { - WCHAR *name; + const WCHAR *name; PyObject *nameobj; PyObject *ignored; HMODULE hMod; - if (!PyArg_ParseTuple(args, "O|O:LoadLibrary", &nameobj, &ignored)) + + if (!PyArg_ParseTuple(args, "U|O:LoadLibrary", &nameobj, &ignored)) return NULL; - name = PyUnicode_AsUnicode(nameobj); + name = _PyUnicode_AsUnicode(nameobj); if (!name) return NULL; diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 26d27317d03f2c..0cf17dec76cf16 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -342,6 +342,7 @@ static int PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, PyObject **bytes, wchar_t **wstr) { + char *str; if (PyUnicode_Check(obj)) { #ifdef HAVE_NCURSESW assert (wstr != NULL); @@ -354,12 +355,20 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, *bytes = PyUnicode_AsEncodedString(obj, win->encoding, NULL); if (*bytes == NULL) return 0; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { + return 0; + } return 1; #endif } else if (PyBytes_Check(obj)) { Py_INCREF(obj); *bytes = obj; + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(*bytes, &str, NULL) < 0) { + return 0; + } return 1; } diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index 4ce71debcf8e4a..39e0c54463bef8 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -252,6 +252,11 @@ PyLocale_strxfrm(PyObject* self, PyObject* args) s = PyUnicode_AsWideCharString(str, &n1); if (s == NULL) goto exit; + if (wcslen(s) != (size_t)n1) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + goto exit; + } /* assume no change in size, first */ n1 = n1 + 1; diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c index 3a134a0333e71a..277fce4d286b0a 100644 --- a/Modules/grpmodule.c +++ b/Modules/grpmodule.c @@ -140,6 +140,7 @@ grp_getgrnam_impl(PyObject *module, PyObject *name) if ((bytes = PyUnicode_EncodeFSDefault(name)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name_chars, NULL) == -1) goto out; diff --git a/Modules/nismodule.c b/Modules/nismodule.c index 64eb5dbc3d0299..3942acb2c7170c 100644 --- a/Modules/nismodule.c +++ b/Modules/nismodule.c @@ -173,6 +173,7 @@ nis_match (PyObject *self, PyObject *args, PyObject *kwdict) return NULL; if ((bkey = PyUnicode_EncodeFSDefault(ukey)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bkey, &key, &keylen) == -1) { Py_DECREF(bkey); return NULL; diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8d32ddf131ce72..3dcebf496f3e0b 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3821,9 +3821,9 @@ os__getfinalpathname_impl(PyObject *module, PyObject *path) wchar_t *target_path; int result_length; PyObject *result; - wchar_t *path_wchar; + const wchar_t *path_wchar; - path_wchar = PyUnicode_AsUnicode(path); + path_wchar = _PyUnicode_AsUnicode(path); if (path_wchar == NULL) return NULL; @@ -7164,7 +7164,7 @@ posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs) static PyObject * win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) { - wchar_t *path; + const wchar_t *path; DWORD n_bytes_returned; DWORD io_result; PyObject *po, *result; @@ -7183,7 +7183,7 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs) )) return NULL; - path = PyUnicode_AsUnicode(po); + path = _PyUnicode_AsUnicode(po); if (path == NULL) return NULL; @@ -9075,7 +9075,8 @@ static PyObject * os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) /*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/ { - wchar_t *env; + const wchar_t *env; + Py_ssize_t size; /* Search from index 1 because on Windows starting '=' is allowed for defining hidden environment variables. */ @@ -9089,16 +9090,21 @@ os_putenv_impl(PyObject *module, PyObject *name, PyObject *value) if (unicode == NULL) { return NULL; } - if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) { + + env = PyUnicode_AsUnicodeAndSize(unicode, &size); + if (env == NULL) + goto error; + if (size > _MAX_ENV) { PyErr_Format(PyExc_ValueError, "the environment variable is longer than %u characters", _MAX_ENV); goto error; } - - env = PyUnicode_AsUnicode(unicode); - if (env == NULL) + if (wcslen(env) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); goto error; + } + if (_wputenv(env)) { posix_error(); goto error; diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 7416cf71d59a6f..1b0d499a4ba62f 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -150,6 +150,7 @@ pwd_getpwnam_impl(PyObject *module, PyObject *arg) if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) goto out; if ((p = getpwnam(name)) == NULL) { diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c index 4b9f3cd9b711e1..065f79cbf2008e 100644 --- a/Modules/spwdmodule.c +++ b/Modules/spwdmodule.c @@ -134,6 +134,7 @@ spwd_getspnam_impl(PyObject *module, PyObject *arg) if ((bytes = PyUnicode_EncodeFSDefault(arg)) == NULL) return NULL; + /* check for embedded null bytes */ if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) goto out; if ((p = getspnam(name)) == NULL) { diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 64375da602d11f..66cb4afbe0d374 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3894,6 +3894,20 @@ PyUnicode_AsUnicode(PyObject *unicode) return PyUnicode_AsUnicodeAndSize(unicode, NULL); } +const Py_UNICODE * +_PyUnicode_AsUnicode(PyObject *unicode) +{ + Py_ssize_t size; + const Py_UNICODE *wstr; + + wstr = PyUnicode_AsUnicodeAndSize(unicode, &size); + if (wstr && wcslen(wstr) != (size_t)size) { + PyErr_SetString(PyExc_ValueError, "embedded null character"); + return NULL; + } + return wstr; +} + Py_ssize_t PyUnicode_GetSize(PyObject *unicode) diff --git a/PC/_msi.c b/PC/_msi.c index 9e7e36da7164df..967b7fa2ee3731 100644 --- a/PC/_msi.c +++ b/PC/_msi.c @@ -600,8 +600,12 @@ summary_setproperty(msiobj* si, PyObject *args) return NULL; if (PyUnicode_Check(data)) { + const WCHAR *value = _PyUnicode_AsUnicode(data); + if (value == NULL) { + return NULL; + } status = MsiSummaryInfoSetPropertyW(si->h, field, VT_LPSTR, - 0, NULL, PyUnicode_AsUnicode(data)); + 0, NULL, value); } else if (PyLong_CheckExact(data)) { long value = PyLong_AsLong(data); if (value == -1 && PyErr_Occurred()) { diff --git a/Python/dynload_win.c b/Python/dynload_win.c index f2c796e94d2e61..3f533d1756cf20 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -192,13 +192,13 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, { dl_funcptr p; char funcname[258], *import_python; - wchar_t *wpathname; + const wchar_t *wpathname; #ifndef _DEBUG _Py_CheckPython3(); #endif - wpathname = PyUnicode_AsUnicode(pathname); + wpathname = _PyUnicode_AsUnicode(pathname); if (wpathname == NULL) return NULL; diff --git a/Python/fileutils.c b/Python/fileutils.c index 23eed71321853d..5072118c9c9e65 100644 --- a/Python/fileutils.c +++ b/Python/fileutils.c @@ -710,21 +710,32 @@ _Py_stat(PyObject *path, struct stat *statbuf) #ifdef MS_WINDOWS int err; struct _stat wstatbuf; - wchar_t *wpath; + const wchar_t *wpath; - wpath = PyUnicode_AsUnicode(path); + wpath = _PyUnicode_AsUnicode(path); if (wpath == NULL) return -2; + err = _wstat(wpath, &wstatbuf); if (!err) statbuf->st_mode = wstatbuf.st_mode; return err; #else int ret; - PyObject *bytes = PyUnicode_EncodeFSDefault(path); + PyObject *bytes; + char *cpath; + + bytes = PyUnicode_EncodeFSDefault(path); if (bytes == NULL) return -2; - ret = stat(PyBytes_AS_STRING(bytes), statbuf); + + /* check for embedded null bytes */ + if (PyBytes_AsStringAndSize(bytes, &cpath, NULL) == -1) { + Py_DECREF(bytes); + return -2; + } + + ret = stat(cpath, statbuf); Py_DECREF(bytes); return ret; #endif @@ -1083,7 +1094,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) FILE *f; int async_err = 0; #ifdef MS_WINDOWS - wchar_t *wpath; + const wchar_t *wpath; wchar_t wmode[10]; int usize; @@ -1097,7 +1108,7 @@ _Py_fopen_obj(PyObject *path, const char *mode) Py_TYPE(path)); return NULL; } - wpath = PyUnicode_AsUnicode(path); + wpath = _PyUnicode_AsUnicode(path); if (wpath == NULL) return NULL; From f15bf1f3f3104f6ab2229e4b359984489a74685b Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 28 Jun 2017 11:50:44 +0200 Subject: [PATCH 321/340] [3.5] bpo-30775: Fix refleaks in test_multiprocessing (GH-2467) (#2469) Forgetting to call Process.join() can keep some resources alive. (cherry picked from commit a79f8faccf5e26f55e8b9496ad49d2071b5e299c) --- Lib/test/_test_multiprocessing.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 01459dc81d86df..76209f134330a1 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1181,10 +1181,19 @@ def __init__(self, namespace, f, args, n, wait_before_exit=False): self._can_exit = namespace.Event() if not wait_before_exit: self._can_exit.set() + + threads = [] for i in range(n): p = namespace.Process(target=self.task) p.daemon = True p.start() + threads.append(p) + + def finalize(threads): + for p in threads: + p.join() + + self._finalizer = weakref.finalize(self, finalize, threads) def task(self): pid = os.getpid() @@ -1207,6 +1216,9 @@ def wait_for_finished(self): def do_finish(self): self._can_exit.set() + def close(self): + self._finalizer() + class AppendTrue(object): def __init__(self, obj): @@ -1239,8 +1251,11 @@ def DummyList(self): def run_threads(self, f, args): b = Bunch(self, f, args, self.N-1) - f(*args) - b.wait_for_finished() + try: + f(*args) + b.wait_for_finished() + finally: + b.close() @classmethod def multipass(cls, barrier, results, n): From a9705b777859f555d50eb5dcd5fc4260c42a0188 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 28 Jun 2017 13:15:58 +0200 Subject: [PATCH 322/340] [3.5] Clear potential ref cycle between Process and Process target (GH-2470) (#2472) * Clear potential ref cycle between Process and Process target Besides Process.join() not being called, this was an indirect cause of bpo-30775. The threading module already does this. * Add issue reference. (cherry picked from commit 79d37ae979a65ada0b2ac820279ccc3b1cd41ba6) --- Lib/multiprocessing/process.py | 3 +++ Lib/test/_test_multiprocessing.py | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/Lib/multiprocessing/process.py b/Lib/multiprocessing/process.py index bca8b7a0047070..f9c22703df29cb 100644 --- a/Lib/multiprocessing/process.py +++ b/Lib/multiprocessing/process.py @@ -104,6 +104,9 @@ def start(self): _cleanup() self._popen = self._Popen(self) self._sentinel = self._popen.sentinel + # Avoid a refcycle if the target function holds an indirect + # reference to the process object (see bpo-30775) + del self._target, self._args, self._kwargs _children.add(self) def terminate(self): diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 76209f134330a1..b9cd86e984e701 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -191,6 +191,12 @@ def get_value(self): # Testcases # +class DummyCallable: + def __call__(self, q, c): + assert isinstance(c, DummyCallable) + q.put(5) + + class _TestProcess(BaseTestCase): ALLOWED_TYPES = ('processes', 'threads') @@ -398,6 +404,18 @@ def test_sentinel(self): p.join() self.assertTrue(wait_for_handle(sentinel, timeout=1)) + def test_lose_target_ref(self): + c = DummyCallable() + wr = weakref.ref(c) + q = self.Queue() + p = self.Process(target=c, args=(q, c)) + del c + p.start() + p.join() + self.assertIs(wr(), None) + self.assertEqual(q.get(), 5) + + # # # From 5741b70acf88846a0d3b2d348535f250577b2df6 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 30 Jun 2017 10:54:32 +0200 Subject: [PATCH 323/340] [3.5] bpo-30807: signal.setitimer() may disable the timer by mistake (GH-2493) (#2498) * bpo-30807: signal.setitimer() may disable the timer by mistake * Add NEWS blurb (cherry picked from commit 729780a810bbcb12b245a1b652302a601fc9f6fd) --- Lib/test/test_signal.py | 9 +++++++++ .../Library/2017-06-29-22-04-44.bpo-30807.sLtjY-.rst | 6 ++++++ Modules/signalmodule.c | 4 ++++ 3 files changed, 19 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-06-29-22-04-44.bpo-30807.sLtjY-.rst diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index 1b80ff0963b8d7..5c7b31d0763d6c 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -764,6 +764,15 @@ def test_itimer_prof(self): # and the handler should have been called self.assertEqual(self.hndl_called, True) + def test_setitimer_tiny(self): + # bpo-30807: C setitimer() takes a microsecond-resolution interval. + # Check that float -> timeval conversion doesn't round + # the interval down to zero, which would disable the timer. + self.itimer = signal.ITIMER_REAL + signal.setitimer(self.itimer, 1e-6) + time.sleep(1) + self.assertEqual(self.hndl_called, True) + class PendingSignalsTests(unittest.TestCase): """ diff --git a/Misc/NEWS.d/next/Library/2017-06-29-22-04-44.bpo-30807.sLtjY-.rst b/Misc/NEWS.d/next/Library/2017-06-29-22-04-44.bpo-30807.sLtjY-.rst new file mode 100644 index 00000000000000..ce6f48a61f6554 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-06-29-22-04-44.bpo-30807.sLtjY-.rst @@ -0,0 +1,6 @@ +signal.setitimer() may disable the timer when passed a tiny value. + +Tiny values (such as 1e-6) are valid non-zero values for setitimer(), which +is specified as taking microsecond-resolution intervals. However, on some +platform, our conversion routine could convert 1e-6 into a zero interval, +therefore disabling the timer instead of (re-)scheduling it. diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 753d9873433091..e0d06b434d5a24 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -139,6 +139,10 @@ timeval_from_double(double d, struct timeval *tv) { tv->tv_sec = floor(d); tv->tv_usec = fmod(d, 1.0) * 1000000.0; + /* Don't disable the timer if the computation above rounds down to zero. */ + if (d > 0.0 && tv->tv_sec == 0 && tv->tv_usec == 0) { + tv->tv_usec = 1; + } } Py_LOCAL_INLINE(double) From 714afccf6e7644d21ce1a39e90bf83cb0c9a74f1 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Jun 2017 13:12:15 +0200 Subject: [PATCH 324/340] bpo-30813: Fix unittest when hunting refleaks (#2502) (#2506) bpo-11798, bpo-16662, bpo-16935, bpo-30813: Skip test_discover_with_module_that_raises_SkipTest_on_import() and test_discover_with_init_module_that_raises_SkipTest_on_import() of test_unittest when hunting reference leaks using regrtest. (cherry picked from commit e4f9a2d2be42d5a2cdd624f8ed7cdf5028c5fbc3) --- Lib/unittest/test/test_discovery.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py index 1996a8ee5d3680..48d8fe95bce261 100644 --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -528,6 +528,9 @@ def _get_module_from_name(name): pickle.loads(pickle.dumps(test, proto)) def test_discover_with_module_that_raises_SkipTest_on_import(self): + if not unittest.BaseTestSuite._cleanup: + raise unittest.SkipTest("Suite cleanup is disabled") + loader = unittest.TestLoader() def _get_module_from_name(name): @@ -548,6 +551,9 @@ def _get_module_from_name(name): pickle.loads(pickle.dumps(suite, proto)) def test_discover_with_init_module_that_raises_SkipTest_on_import(self): + if not unittest.BaseTestSuite._cleanup: + raise unittest.SkipTest("Suite cleanup is disabled") + vfs = {abspath('/foo'): ['my_package'], abspath('/foo/my_package'): ['__init__.py', 'test_module.py']} self.setup_import_issue_package_tests(vfs) From 0e0bc8762570277147a09278c829e4a85a331596 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 30 Jun 2017 17:20:31 +0200 Subject: [PATCH 325/340] bpo-30280: Cleanup threads in ayncio tests (#2501) (#2512) * bpo-30280: asyncio now cleans up threads asyncio base TestCase now uses threading_setup() and threading_cleanup() of test.support to cleanup threads. * asyncio: Fix TestBaseSelectorEventLoop cleanup bpo-30280: TestBaseSelectorEventLoop of test.test_asyncio.test_selector_events now correctly closes the event loop: cleanup its executor to not leak threads. Don't override the close() method of the event loop, only override the_close_self_pipe() method. (cherry picked from commit b9030674624c181d6e9047cdb14ad65bb6c84c66) --- Lib/asyncio/test_utils.py | 6 ++++++ Lib/test/test_asyncio/test_selector_events.py | 8 +++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py index fe90b9c29897f4..a1686c58493534 100644 --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -33,6 +33,7 @@ from . import tasks from .coroutines import coroutine from .log import logger +from test import support if sys.platform == 'win32': # pragma: no cover @@ -455,6 +456,7 @@ def unpatch_get_running_loop(self): def setUp(self): self._get_running_loop = events._get_running_loop events._get_running_loop = lambda: None + self._thread_cleanup = support.threading_setup() def tearDown(self): self.unpatch_get_running_loop() @@ -465,6 +467,10 @@ def tearDown(self): # in an except block of a generator self.assertEqual(sys.exc_info(), (None, None, None)) + self.doCleanups() + support.threading_cleanup(*self._thread_cleanup) + support.reap_children() + if not compat.PY34: # Python 3.3 compatibility def subTest(self, *args, **kwargs): diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py index 6bf7862ecf9c0a..c50b3e49565c92 100644 --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -24,16 +24,14 @@ class TestBaseSelectorEventLoop(BaseSelectorEventLoop): - def close(self): - # Don't call the close() method of the parent class, because the - # selector is mocked - self._closed = True - def _make_self_pipe(self): self._ssock = mock.Mock() self._csock = mock.Mock() self._internal_fds += 1 + def _close_self_pipe(self): + pass + def list_to_buffer(l=()): return bytearray().join(l) From 4685e56596f9f332e402c79c913a73b19f4411e1 Mon Sep 17 00:00:00 2001 From: Kojo Idrissa Date: Sun, 2 Jul 2017 11:47:56 +0900 Subject: [PATCH 326/340] [3.5] bpo-29933: Improve set_write_buffer_limits description (GH-2262) (GH-2533) Improve the description of the high and low parameters for set_write_buffer_limits. Also fixed a small grammatical issue. (cherry picked from commit 5200a7c7f9ea65a96330c5f276f4acc6ec70854e) --- Doc/library/asyncio-protocol.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst index 2e1a11bed7503b..435eb3b37ad2fa 100644 --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -160,11 +160,17 @@ WriteTransport Set the *high*- and *low*-water limits for write flow control. - These two values control when call the protocol's + These two values (measured in number of + bytes) control when the protocol's :meth:`pause_writing` and :meth:`resume_writing` methods are called. If specified, the low-water limit must be less than or equal to the high-water limit. Neither *high* nor *low* can be negative. + :meth:`pause_writing` is called when the buffer size becomes greater + than or equal to the *high* value. If writing has been paused, + :meth:`resume_writing` is called when the buffer size becomes less + than or equal to the *low* value. + The defaults are implementation-specific. If only the high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the From 0b1210739d12c26e4a161ffd494bd572d49b2483 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 3 Jul 2017 13:16:57 +0200 Subject: [PATCH 327/340] [3.5] bpo-29512, bpo-30764, bpo-30776: Backport regrtest enhancements from 3.6 to 3.5 (#2540) * [3.6] bpo-29512, bpo-30776: Backport regrtest enhancements from master to 3.6 (#2513) * bpo-29512: Add test.bisect, bisect failing tests (#2452) Add a new "python3 -m test.bisect" tool to bisect failing tests. It can be used to find which test method(s) leak references, leak files, etc. (cherry picked from commit 84d9d14a1fa395fbd21262ba195490be25a7b3bc) * bpo-30776: regrtest: reduce memleak false positive (#2484) Only report a leak if each run leaks at least one memory block. (cherry picked from commit beeca6e1e5fd01531b1db7059498b13d07dca525) (cherry picked from commit a3ca94d0504157a112a1f89bfe8be1307116fc73) * bpo-30764: Fix regrtest --fail-env-changed --forever (#2536) (#2539) --forever now stops if a fail changes the environment. (cherry picked from commit 5e87592fd12e0b7c41edc11d4885ed7298d5063b) (cherry picked from commit 4132adb4b8f90893d8f19ff46edff56f189faca0) --- Lib/test/bisect.py | 167 +++++++++++++++++++++++++++++++++++++++++++ Lib/test/regrtest.py | 16 ++--- 2 files changed, 173 insertions(+), 10 deletions(-) create mode 100755 Lib/test/bisect.py diff --git a/Lib/test/bisect.py b/Lib/test/bisect.py new file mode 100755 index 00000000000000..0fd577d4e5619f --- /dev/null +++ b/Lib/test/bisect.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python3 +""" +Command line tool to bisect failing CPython tests. + +Find the test_os test method which alters the environment: + + ./python -m test.bisect --fail-env-changed test_os + +Find a reference leak in "test_os", write the list of failing tests into the +"bisect" file: + + ./python -m test.bisect -o bisect -R 3:3 test_os + +Load an existing list of tests from a file using -i option: + + ./python -m test --list-cases -m FileTests test_os > tests + ./python -m test.bisect -i tests test_os +""" + +import argparse +import datetime +import os.path +import math +import random +import subprocess +import sys +import tempfile +import time + + +def write_tests(filename, tests): + with open(filename, "w") as fp: + for name in tests: + print(name, file=fp) + fp.flush() + + +def write_output(filename, tests): + if not filename: + return + print("Write %s tests into %s" % (len(tests), filename)) + write_tests(filename, tests) + return filename + + +def format_shell_args(args): + return ' '.join(args) + + +def list_cases(args): + cmd = [sys.executable, '-m', 'test', '--list-cases'] + cmd.extend(args.test_args) + proc = subprocess.run(cmd, + stdout=subprocess.PIPE, + universal_newlines=True) + exitcode = proc.returncode + if exitcode: + cmd = format_shell_args(cmd) + print("Failed to list tests: %s failed with exit code %s" + % (cmd, exitcode)) + sys.exit(exitcode) + tests = proc.stdout.splitlines() + return tests + + +def run_tests(args, tests, huntrleaks=None): + tmp = tempfile.mktemp() + try: + write_tests(tmp, tests) + + cmd = [sys.executable, '-m', 'test', '--matchfile', tmp] + cmd.extend(args.test_args) + print("+ %s" % format_shell_args(cmd)) + proc = subprocess.run(cmd) + return proc.returncode + finally: + if os.path.exists(tmp): + os.unlink(tmp) + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-i', '--input', + help='Test names produced by --list-tests written ' + 'into a file. If not set, run --list-tests') + parser.add_argument('-o', '--output', + help='Result of the bisection') + parser.add_argument('-n', '--max-tests', type=int, default=1, + help='Maximum number of tests to stop the bisection ' + '(default: 1)') + parser.add_argument('-N', '--max-iter', type=int, default=100, + help='Maximum number of bisection iterations ' + '(default: 100)') + # FIXME: document that following arguments are test arguments + + args, test_args = parser.parse_known_args() + args.test_args = test_args + return args + + +def main(): + args = parse_args() + + if args.input: + with open(args.input) as fp: + tests = [line.strip() for line in fp] + else: + tests = list_cases(args) + + print("Start bisection with %s tests" % len(tests)) + print("Test arguments: %s" % format_shell_args(args.test_args)) + print("Bisection will stop when getting %s or less tests " + "(-n/--max-tests option), or after %s iterations " + "(-N/--max-iter option)" + % (args.max_tests, args.max_iter)) + output = write_output(args.output, tests) + print() + + start_time = time.monotonic() + iteration = 1 + try: + while len(tests) > args.max_tests and iteration <= args.max_iter: + ntest = len(tests) + ntest = max(ntest // 2, 1) + subtests = random.sample(tests, ntest) + + print("[+] Iteration %s: run %s tests/%s" + % (iteration, len(subtests), len(tests))) + print() + + exitcode = run_tests(args, subtests) + + print("ran %s tests/%s" % (ntest, len(tests))) + print("exit", exitcode) + if exitcode: + print("Tests failed: use this new subtest") + tests = subtests + output = write_output(args.output, tests) + else: + print("Tests succeeded: skip this subtest, try a new subbset") + print() + iteration += 1 + except KeyboardInterrupt: + print() + print("Bisection interrupted!") + print() + + print("Tests (%s):" % len(tests)) + for test in tests: + print("* %s" % test) + print() + + if output: + print("Output written into %s" % output) + + dt = math.ceil(time.monotonic() - start_time) + if len(tests) <= args.max_tests: + print("Bisection completed in %s iterations and %s" + % (iteration, datetime.timedelta(seconds=dt))) + sys.exit(1) + else: + print("Bisection failed after %s iterations and %s" + % (iteration, datetime.timedelta(seconds=dt))) + + +if __name__ == "__main__": + main() diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index 339beb1f854b5b..f9457203c9d695 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -739,6 +739,8 @@ def test_forever(tests=list(selected)): yield test if bad: return + if ns.fail_env_changed and environment_changed: + return tests = test_forever() test_count = '' test_count_width = 3 @@ -947,7 +949,7 @@ def runtest_accumulate(): result = "FAILURE" elif interrupted: result = "INTERRUPTED" - elif environment_changed and ns.fail_env_changed: + elif ns.fail_env_changed and environment_changed: result = "ENV CHANGED" else: result = "SUCCESS" @@ -1524,6 +1526,8 @@ def dash_R(the_module, test, indirect_test, huntrleaks): # These checkers return False on success, True on failure def check_rc_deltas(deltas): + # Checker for reference counters and memomry blocks. + # # bpo-30776: Try to ignore false positives: # # [3, 0, 0] @@ -1536,18 +1540,10 @@ def check_rc_deltas(deltas): # [10, 1, 1] return all(delta >= 1 for delta in deltas) - def check_alloc_deltas(deltas): - # At least 1/3rd of 0s - if 3 * deltas.count(0) < len(deltas): - return True - # Nothing else than 1s, 0s and -1s - if not set(deltas) <= {1,0,-1}: - return True - return False failed = False for deltas, item_name, checker in [ (rc_deltas, 'references', check_rc_deltas), - (alloc_deltas, 'memory blocks', check_alloc_deltas) + (alloc_deltas, 'memory blocks', check_rc_deltas) ]: # ignore warmup runs deltas = deltas[nwarmup:] From 1a3bc5546aa27f01426ad76618a9b2c3b698ae68 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 4 Jul 2017 07:55:45 +0300 Subject: [PATCH 328/340] [3.5] bpo-30441: Fix bug when modifying os.environ while iterating over it (GH-2409). (#2557) (cherry picked from commit 8a8d28501fc8ce25926d168f1c657656c809fd4c) --- Lib/os.py | 4 +++- Lib/test/test_os.py | 24 +++++++++++++++++++ Misc/ACKS | 1 + .../2017-06-29-14-25-14.bpo-30441.3Wh9kc.rst | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2017-06-29-14-25-14.bpo-30441.3Wh9kc.rst diff --git a/Lib/os.py b/Lib/os.py index 011285e74bd92b..b1add54cf2f9c0 100644 --- a/Lib/os.py +++ b/Lib/os.py @@ -741,7 +741,9 @@ def __delitem__(self, key): raise KeyError(key) from None def __iter__(self): - for key in self._data: + # list() from dict object is an atomic operation + keys = list(self._data) + for key in keys: yield self.decodekey(key) def __len__(self): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index e9c850793a5d9b..6dc05eb7fde044 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -809,6 +809,30 @@ def test_key_type(self): self.assertIs(cm.exception.args[0], missing) self.assertTrue(cm.exception.__suppress_context__) + def _test_environ_iteration(self, collection): + iterator = iter(collection) + new_key = "__new_key__" + + next(iterator) # start iteration over os.environ.items + + # add a new key in os.environ mapping + os.environ[new_key] = "test_environ_iteration" + + try: + next(iterator) # force iteration over modified mapping + self.assertEqual(os.environ[new_key], "test_environ_iteration") + finally: + del os.environ[new_key] + + def test_iter_error_when_changing_os_environ(self): + self._test_environ_iteration(os.environ) + + def test_iter_error_when_changing_os_environ_items(self): + self._test_environ_iteration(os.environ.items()) + + def test_iter_error_when_changing_os_environ_values(self): + self._test_environ_iteration(os.environ.values()) + class WalkTests(unittest.TestCase): """Tests for os.walk().""" diff --git a/Misc/ACKS b/Misc/ACKS index 7f9044ac7cb6da..5440326ac3346a 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1056,6 +1056,7 @@ Vilmos Nebehaj Fredrik Nehr Tony Nelson Trent Nelson +Osvaldo Santana Neto Chad Netzer Max Neunhöffer Anthon van der Neut diff --git a/Misc/NEWS.d/next/Library/2017-06-29-14-25-14.bpo-30441.3Wh9kc.rst b/Misc/NEWS.d/next/Library/2017-06-29-14-25-14.bpo-30441.3Wh9kc.rst new file mode 100644 index 00000000000000..55dd6136c8d708 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-06-29-14-25-14.bpo-30441.3Wh9kc.rst @@ -0,0 +1 @@ +Fix bug when modifying os.environ while iterating over it From ebf7d21129300aaee71f9a295ab15d09fe027e4e Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Tue, 4 Jul 2017 09:28:02 +0300 Subject: [PATCH 329/340] Remove outdated FOX from GUI FAQ (GH-2538) FXpy doesn't have a Python 3 port and it only supports Python 2.2 and older versions. Reported by Alex Walters on docs@p.o. (cherry picked from commit d3ed2877a798d07df75422afe136b4727e500c99) --- Doc/faq/gui.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 477d8c633438d1..38e1796267ff3a 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -94,15 +94,6 @@ Python bindings for `the FLTK toolkit `_, a simple yet powerful and mature cross-platform windowing system, are available from `the PyFLTK project `_. - -FOX ----- - -A wrapper for `the FOX toolkit `_ called `FXpy -`_ is available. FOX supports both Unix variants -and Windows. - - OpenGL ------ From 320ee67f981f766ff55c55ef87d5ef17ce297824 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Tue, 4 Jul 2017 21:39:28 +0300 Subject: [PATCH 330/340] [3.5] bpo-30726: Also fix pyexpat.vcxproj (GH-2375) (#2571) (cherry picked from commit 7526cadd64566725ffc56071a7208828a46ddbd8) --- PCbuild/pyexpat.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PCbuild/pyexpat.vcxproj b/PCbuild/pyexpat.vcxproj index 99c7286b2bdfde..a2763f02063cd5 100644 --- a/PCbuild/pyexpat.vcxproj +++ b/PCbuild/pyexpat.vcxproj @@ -59,7 +59,7 @@ $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) - PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_NS;XML_DTD;BYTEORDER=1234;XML_CONTEXT_BYTES=1024;XML_STATIC;HAVE_MEMMOVE;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_STATIC;%(PreprocessorDefinitions) From c48a000c74b48586742c4b7eb42bba93f15953a9 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 5 Jul 2017 15:58:24 +0200 Subject: [PATCH 331/340] [3.5] bpo-30855: Trying to fix test_use on Windows. (#2585) * bpo-30855: Trying to fix test_use on Windows. Avoid possible weird behavior of WideInt convertion. "winfo id" always returns string hexadecimal representation. (cherry picked from commit b9d672491d5082c541bf267eb7bb99fdc6529324) * bpo-30855: Trying to fix test_use on Windows. (cherry picked from commit 29a2f7c6b38e5a6ed891aa72af38974a1ff2d372) --- Lib/tkinter/__init__.py | 3 +-- Lib/tkinter/test/test_tkinter/test_widgets.py | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 1a3bf889677807..5eeefbbec88f88 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -854,8 +854,7 @@ def winfo_height(self): self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" - return self.tk.getint( - self.tk.call('winfo', 'id', self._w)) + return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py index c924d559372ae0..81b52eafea9a83 100644 --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -91,9 +91,10 @@ def test_use(self): widget = self.create() self.assertEqual(widget['use'], '') parent = self.create(container=True) - wid = parent.winfo_id() - widget2 = self.create(use=wid) - self.assertEqual(int(widget2['use']), wid) + wid = hex(parent.winfo_id()) + with self.subTest(wid=wid): + widget2 = self.create(use=wid) + self.assertEqual(widget2['use'], wid) @add_standard_options(StandardOptionsTests) From 10df96affd0f3e21a7750db98038f8419b91db95 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 5 Jul 2017 20:55:18 -0700 Subject: [PATCH 332/340] Fix trivial typo in json module docstring (GH-2274) (GH-2431) (cherry picked from commit 76c567ee27342d76f631a35c8291b715b2a61f3e) --- Lib/json/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/json/__init__.py b/Lib/json/__init__.py index 1118b0eb9903ba..ca2c611bd0e48c 100644 --- a/Lib/json/__init__.py +++ b/Lib/json/__init__.py @@ -76,7 +76,7 @@ >>> def encode_complex(obj): ... if isinstance(obj, complex): ... return [obj.real, obj.imag] - ... raise TypeError(repr(o) + " is not JSON serializable") + ... raise TypeError(repr(obj) + " is not JSON serializable") ... >>> json.dumps(2 + 1j, default=encode_complex) '[2.0, 1.0]' From 710cc7667c27955272725729775cb39c40cca113 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Fri, 7 Jul 2017 00:08:41 +0300 Subject: [PATCH 333/340] [3.5] Fix case in .gitignore (GH-2607) (GH-2609) (cherry picked from commit be5ebe58776a02d53bcf5e43ab946b555c0e025f) --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b324b920984265..254d572a358285 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,7 @@ PCbuild/*.VC.opendb PCbuild/.vs/ PCbuild/amd64/ PCbuild/obj/ -PCBuild/win32/ +PCbuild/win32/ .purify Parser/pgen __pycache__ From 3bbdf990a2c1b0b303b950058e3177a1bd5f697a Mon Sep 17 00:00:00 2001 From: Joel Hillacre Date: Thu, 6 Jul 2017 15:29:09 -0600 Subject: [PATCH 334/340] bpo-30532: Fix whitespace folding in certain cases (#2592) Leading whitespace was incorrectly dropped during folding of certain lines in the _header_value_parser's folding algorithm. This makes the whitespace handling code consistent. --- Lib/email/_header_value_parser.py | 4 +--- Lib/test/test_email/test__header_value_parser.py | 12 ++++++++++++ Misc/ACKS | 1 + .../Library/2017-06-26-11-01-59.bpo-30532.qTeL1o.rst | 1 + 4 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-06-26-11-01-59.bpo-30532.qTeL1o.rst diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 5df9511e8d9064..37a9fbcbb67d7c 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -341,9 +341,7 @@ def _fold(self, folded): # avoid infinite recursion. ws = part.pop_leading_fws() if ws is not None: - # Peel off the leading whitespace and make it sticky, to - # avoid infinite recursion. - folded.stickyspace = str(part.pop(0)) + folded.stickyspace = str(ws) if folded.append_if_fits(part): continue if part.has_fws: diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py index f7ac0e3dedcc24..b1e7dff2405d88 100644 --- a/Lib/test/test_email/test__header_value_parser.py +++ b/Lib/test/test_email/test__header_value_parser.py @@ -2711,5 +2711,17 @@ def test_whitespace_splitting(self): self._test(parser.get_unstructured('xxx ' + 'y'*77), 'xxx \n ' + 'y'*77 + '\n') + def test_long_filename_attachment(self): + folded = self.policy.fold('Content-Disposition', 'attachment; filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TES.txt"') + self.assertEqual( + 'Content-Disposition: attachment;\n filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TES.txt"\n', + folded + ) + folded = self.policy.fold('Content-Disposition', 'attachment; filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_T.txt"') + self.assertEqual( + 'Content-Disposition: attachment;\n filename="TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_TEST_T.txt"\n', + folded + ) + if __name__ == '__main__': unittest.main() diff --git a/Misc/ACKS b/Misc/ACKS index 5440326ac3346a..fbf110d801b5aa 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -612,6 +612,7 @@ Wouter van Heyst Kelsey Hightower Jason Hildebrand Aaron Hill +Joel Hillacre Richie Hindle Konrad Hinsen David Hobley diff --git a/Misc/NEWS.d/next/Library/2017-06-26-11-01-59.bpo-30532.qTeL1o.rst b/Misc/NEWS.d/next/Library/2017-06-26-11-01-59.bpo-30532.qTeL1o.rst new file mode 100644 index 00000000000000..adce85fbc2b4c6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-06-26-11-01-59.bpo-30532.qTeL1o.rst @@ -0,0 +1 @@ +Fix email header value parser dropping folding white space in certain cases. From 68c3724651776f4ae90ed24d70cef6fd45bc7db5 Mon Sep 17 00:00:00 2001 From: Nir Soffer Date: Sun, 9 Jul 2017 13:42:35 +0300 Subject: [PATCH 335/340] [3.5] bpo-29854: Fix segfault in call_readline() (GH-728) If history-length is set in .inputrc, and the history file is double the history size (or more), history_get(N) returns NULL, and python segfaults. Fix that by checking for NULL return value. It seems that the root cause is incorrect handling of bigger history in readline, but Python should not segfault even if readline returns unexpected value. This issue affects only GNU readline. When using libedit emulation system history size option does not work. --- Lib/test/test_readline.py | 50 +++++++++++++++++-- .../2017-07-07-02-18-57.bpo-29854.J8wKb_.rst | 2 + Modules/readline.c | 10 ++-- 3 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py index 2c73df291f0c5a..931c855b66ca3c 100644 --- a/Lib/test/test_readline.py +++ b/Lib/test/test_readline.py @@ -9,7 +9,7 @@ import sys import tempfile import unittest -from test.support import import_module, unlink, TESTFN +from test.support import import_module, unlink, temp_dir, TESTFN from test.support.script_helper import assert_python_ok # Skip tests if there is no readline module @@ -195,13 +195,57 @@ def display(substitution, matches, longest_match_length): self.assertIn(b"result " + expected + b"\r\n", output) self.assertIn(b"history " + expected + b"\r\n", output) + # We have 2 reasons to skip this test: + # - readline: history size was added in 6.0 + # See https://cnswww.cns.cwru.edu/php/chet/readline/CHANGES + # - editline: history size is broken on OS X 10.11.6. + # Newer versions were not tested yet. + @unittest.skipIf(readline._READLINE_VERSION < 0x600, + "this readline version does not support history-size") + @unittest.skipIf(is_editline, + "editline history size configuration is broken") + def test_history_size(self): + history_size = 10 + with temp_dir() as test_dir: + inputrc = os.path.join(test_dir, "inputrc") + with open(inputrc, "wb") as f: + f.write(b"set history-size %d\n" % history_size) + + history_file = os.path.join(test_dir, "history") + with open(history_file, "wb") as f: + # history_size * 2 items crashes readline + data = b"".join(b"item %d\n" % i + for i in range(history_size * 2)) + f.write(data) + + script = """ +import os +import readline + +history_file = os.environ["HISTORY_FILE"] +readline.read_history_file(history_file) +input() +readline.write_history_file(history_file) +""" + + env = dict(os.environ) + env["INPUTRC"] = inputrc + env["HISTORY_FILE"] = history_file + + run_pty(script, input=b"last input\r", env=env) + + with open(history_file, "rb") as f: + lines = f.readlines() + self.assertEqual(len(lines), history_size) + self.assertEqual(lines[-1].strip(), b"last input") + -def run_pty(script, input=b"dummy input\r"): +def run_pty(script, input=b"dummy input\r", env=None): pty = import_module('pty') output = bytearray() [master, slave] = pty.openpty() args = (sys.executable, '-c', script) - proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave) + proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env) os.close(slave) with ExitStack() as cleanup: cleanup.enter_context(proc) diff --git a/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst b/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst new file mode 100644 index 00000000000000..5c439087dcb344 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-07-07-02-18-57.bpo-29854.J8wKb_.rst @@ -0,0 +1,2 @@ +Fix segfault in readline when using readline's history-size option. Patch +by Nir Soffer. diff --git a/Modules/readline.c b/Modules/readline.c index 54f15bc1c934de..c6035e2f3663ab 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1330,15 +1330,17 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) if (n > 0) { const char *line; int length = _py_get_history_length(); - if (length > 0) + if (length > 0) { + HIST_ENTRY *hist_ent; #ifdef __APPLE__ if (using_libedit_emulation) { /* handle older 0-based or newer 1-based indexing */ - line = (const char *)history_get(length + libedit_history_start - 1)->line; + hist_ent = history_get(length + libedit_history_start - 1); } else #endif /* __APPLE__ */ - line = (const char *)history_get(length)->line; - else + hist_ent = history_get(length); + line = hist_ent ? hist_ent->line : ""; + } else line = ""; if (strcmp(p, line)) add_history(p); From 69e41807f0851ff1107f949dcdc94dbb0af32acd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 10 Jul 2017 13:43:17 +0200 Subject: [PATCH 336/340] bpo-30886: Fix multiprocessing.Queue.join_thread() (#2642) (#2644) multiprocessing.Queue.join_thread() now waits until the thread completes, even if the thread was started by the same process which created the queue. Fix the following warning which occurs randomly when running test_handle_called_with_mp_queue of test_logging.QueueListenerTest: Warning -- threading_cleanup() failed to cleanup -1 threads after 4 sec (count: 0, dangling: 1) (cherry picked from commit 3b69d911c57ef591ac0c0f47a66dbcad8337f33a) --- Lib/multiprocessing/queues.py | 9 +-------- .../Library/2017-07-10-12-14-22.bpo-30886.nqQj34.rst | 3 +++ 2 files changed, 4 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2017-07-10-12-14-22.bpo-30886.nqQj34.rst diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index 2c888c00e7c298..e6fe5be7fe5ff7 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -169,14 +169,7 @@ def _start_thread(self): self._thread.start() debug('... done self._thread.start()') - # On process exit we will wait for data to be flushed to pipe. - # - # However, if this process created the queue then all - # processes which use the queue will be descendants of this - # process. Therefore waiting for the queue to be flushed - # is pointless once all the child processes have been joined. - created_by_this_process = (self._opid == os.getpid()) - if not self._joincancelled and not created_by_this_process: + if not self._joincancelled: self._jointhread = Finalize( self._thread, Queue._finalize_join, [weakref.ref(self._thread)], diff --git a/Misc/NEWS.d/next/Library/2017-07-10-12-14-22.bpo-30886.nqQj34.rst b/Misc/NEWS.d/next/Library/2017-07-10-12-14-22.bpo-30886.nqQj34.rst new file mode 100644 index 00000000000000..fedd6cd04741fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-07-10-12-14-22.bpo-30886.nqQj34.rst @@ -0,0 +1,3 @@ +Fix multiprocessing.Queue.join_thread(): it now waits until the thread +completes, even if the thread was started by the same process which created +the queue. From 7f567e7472dd6c3d066eec1c204301df251484b5 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 10 Jul 2017 23:13:49 +0200 Subject: [PATCH 337/340] bpo-30892: Fix _elementtree module initialization (#2647) (#2650) Handle getattr(copy, 'deepcopy') error in _elementtree module initialization. (cherry picked from commit b136f11f3a51f9282ae992bac68f170ca5563b55) --- Modules/_elementtree.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index 0276452db4c337..fedef100cec7bf 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -3952,6 +3952,11 @@ PyInit__elementtree(void) st->deepcopy_obj = PyObject_GetAttrString(temp, "deepcopy"); Py_XDECREF(temp); + if (st->deepcopy_obj == NULL) { + return NULL; + } + + assert(!PyErr_Occurred()); if (!(st->elementpath_obj = PyImport_ImportModule("xml.etree.ElementPath"))) return NULL; From 7527c32f5fedc3260d767900f1014495c0a1b7a5 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 11 Jul 2017 07:43:14 +0300 Subject: [PATCH 338/340] [3.5] bpo-30879: os.listdir() and os.scandir() now emit bytes names when (GH-2634) (#2657) called with bytes-like argument. (cherry picked from commit 1180e5a51871fa53ca6892e83fd2e69dc2600447) --- Lib/test/test_os.py | 22 ++++++++++++++++++++++ Lib/test/test_posix.py | 14 +++++++++++--- Misc/NEWS | 3 +++ Modules/posixmodule.c | 6 +++--- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index 6dc05eb7fde044..8ad6d8e31179e1 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3185,6 +3185,28 @@ def test_bytes(self): self.assertEqual(entry.path, os.fsencode(os.path.join(self.path, 'file.txt'))) + def test_bytes_like(self): + if os.name == "nt": + # On Windows, os.scandir(bytes) must raise an exception + for cls in bytearray, memoryview: + self.assertRaises(TypeError, os.scandir, cls(b'.')) + return + + # Deprecated in 3.6. + self.create_file("file.txt") + + for cls in bytearray, memoryview: + path_bytes = cls(os.fsencode(self.path)) + entries = list(os.scandir(path_bytes)) + self.assertEqual(len(entries), 1, entries) + entry = entries[0] + + self.assertEqual(entry.name, b'file.txt') + self.assertEqual(entry.path, + os.fsencode(os.path.join(self.path, 'file.txt'))) + self.assertIs(type(entry.name), bytes) + self.assertIs(type(entry.path), bytes) + def test_empty_path(self): self.assertRaises(FileNotFoundError, os.scandir, '') diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py index 57f793d1054d10..b229cd340566ae 100644 --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -577,17 +577,25 @@ def test_chdir(self): self.assertRaises(OSError, posix.chdir, support.TESTFN) def test_listdir(self): - self.assertTrue(support.TESTFN in posix.listdir(os.curdir)) + self.assertIn(support.TESTFN, posix.listdir(os.curdir)) def test_listdir_default(self): # When listdir is called without argument, # it's the same as listdir(os.curdir). - self.assertTrue(support.TESTFN in posix.listdir()) + self.assertIn(support.TESTFN, posix.listdir()) def test_listdir_bytes(self): # When listdir is called with a bytes object, # the returned strings are of type bytes. - self.assertTrue(os.fsencode(support.TESTFN) in posix.listdir(b'.')) + self.assertIn(os.fsencode(support.TESTFN), posix.listdir(b'.')) + + def test_listdir_bytes_like(self): + # Deprecated in 3.6. + for cls in bytearray, memoryview: + names = posix.listdir(cls(b'.')) + self.assertIn(os.fsencode(support.TESTFN), names) + for name in names: + self.assertIs(type(name), bytes) @unittest.skipUnless(posix.listdir in os.supports_fd, "test needs fd support for posix.listdir()") diff --git a/Misc/NEWS b/Misc/NEWS index 4a8137f55f65ea..966a011579f02d 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -59,6 +59,9 @@ Extension Modules Library ------- +- bpo-30879: os.listdir() and os.scandir() now emit bytes names when called + with bytes-like argument. + - bpo-30746: Prohibited the '=' character in environment variable names in ``os.putenv()`` and ``os.spawn*()``. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 3dcebf496f3e0b..d42416b0270ebb 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -3642,8 +3642,8 @@ _posix_listdir(path_t *path, PyObject *list) char *name; if (path->narrow) { name = path->narrow; - /* only return bytes if they specified a bytes object */ - return_str = !(PyBytes_Check(path->object)); + /* only return bytes if they specified a bytes-like object */ + return_str = !PyObject_CheckBuffer(path->object); } else { name = "."; @@ -11960,7 +11960,7 @@ DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len, if (!joined_path) goto error; - if (!path->narrow || !PyBytes_Check(path->object)) { + if (!path->narrow || !PyObject_CheckBuffer(path->object)) { entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len); entry->path = PyUnicode_DecodeFSDefault(joined_path); } From 44eb51e6fcf45f3c2bf21c16e18c4da48a23d2d3 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 11 Jul 2017 07:43:36 +0300 Subject: [PATCH 339/340] [3.5] bpo-22207: Add checks for possible integer overflows in unicodeobject.c. (GH-2623) (#2659) Based on patch by Victor Stinner. (cherry picked from commit 64e461be09e23705ecbab43a8b01722186641f71) --- Objects/unicodeobject.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 66cb4afbe0d374..571cd772b15d51 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -5209,13 +5209,12 @@ _PyUnicode_EncodeUTF32(PyObject *str, /* four bytes are reserved for each surrogate */ if (moreunits > 1) { Py_ssize_t outpos = out - (PY_UINT32_T*) PyBytes_AS_STRING(v); - Py_ssize_t morebytes = 4 * (moreunits - 1); - if (PyBytes_GET_SIZE(v) > PY_SSIZE_T_MAX - morebytes) { + if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 4) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + morebytes) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * (moreunits - 1)) < 0) goto error; out = (PY_UINT32_T*) PyBytes_AS_STRING(v) + outpos; } @@ -5552,13 +5551,12 @@ _PyUnicode_EncodeUTF16(PyObject *str, /* two bytes are reserved for each surrogate */ if (moreunits > 1) { Py_ssize_t outpos = out - (unsigned short*) PyBytes_AS_STRING(v); - Py_ssize_t morebytes = 2 * (moreunits - 1); - if (PyBytes_GET_SIZE(v) > PY_SSIZE_T_MAX - morebytes) { + if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 2) { /* integer overflow */ PyErr_NoMemory(); goto error; } - if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + morebytes) < 0) + if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * (moreunits - 1)) < 0) goto error; out = (unsigned short*) PyBytes_AS_STRING(v) + outpos; } @@ -6250,6 +6248,10 @@ _PyUnicode_DecodeUnicodeInternal(const char *s, 1)) return NULL; + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } if (size == 0) _Py_RETURN_UNICODE_EMPTY(); @@ -7052,6 +7054,10 @@ decode_code_page_stateful(int code_page, PyErr_SetString(PyExc_ValueError, "invalid code page number"); return NULL; } + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } if (consumed) *consumed = 0; From 31d8c0da60f07f5eea430ce2f471a67c3d60f394 Mon Sep 17 00:00:00 2001 From: Segev Finer Date: Wed, 12 Jul 2017 01:16:31 +0300 Subject: [PATCH 340/340] [3.5] Avoid _GNU_SOURCE redefined warning in xmlparse.c (GH-2670) (#2671) (cherry picked from commit f52325598e7a9683787d76a42009fc16790a0089) --- Modules/expat/xmlparse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/expat/xmlparse.c b/Modules/expat/xmlparse.c index 76f078e2505f90..daec151e232f1c 100644 --- a/Modules/expat/xmlparse.c +++ b/Modules/expat/xmlparse.c @@ -4,7 +4,7 @@ 77fea421d361dca90041d0040ecf1dca651167fadf2af79e990e35168d70d933 (2.2.1+) */ -#define _GNU_SOURCE /* syscall prototype */ +#define _GNU_SOURCE 1 /* syscall prototype */ #include #include /* memset(), memcpy() */