From e09cf818c459214ed2b133088e2fd595675e8de4 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 17:40:34 -0800 Subject: [PATCH 0001/1727] Make Posixmodule use PyType_FromSpec --- Modules/posixmodule.c | 133 ++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 90 deletions(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7571385ae51da3..d3e03fa574b712 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11997,7 +11997,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] -class os.DirEntry "DirEntry *" "&DirEntryType" +class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ @@ -12327,39 +12327,24 @@ static PyMethodDef DirEntry_methods[] = { {NULL} }; -static PyTypeObject DirEntryType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".DirEntry", /* tp_name */ - sizeof(DirEntry), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)DirEntry_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)DirEntry_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - DirEntry_methods, /* tp_methods */ - DirEntry_members, /* tp_members */ +static PyType_Slot DirEntryType_slots[] = { + {Py_tp_dealloc, DirEntry_dealloc}, + {Py_tp_repr, DirEntry_repr}, + {Py_tp_methods, DirEntry_methods}, + {Py_tp_members, DirEntry_members}, + {0, 0}, }; +static PyType_Spec DirEntryType_spec = { + MODNAME ".DirEntry", + sizeof(DirEntry), + 0, + Py_TPFLAGS_DEFAULT, + DirEntryType_slots +}; + +static PyTypeObject* DirEntryType; + #ifdef MS_WINDOWS static wchar_t * @@ -12403,7 +12388,7 @@ DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW) ULONG reparse_tag; wchar_t *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12490,7 +12475,7 @@ DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len, DirEntry *entry; char *joined_path; - entry = PyObject_New(DirEntry, &DirEntryType); + entry = PyObject_New(DirEntry, DirEntryType); if (!entry) return NULL; entry->name = NULL; @@ -12765,59 +12750,25 @@ static PyMethodDef ScandirIterator_methods[] = { {NULL} }; -static PyTypeObject ScandirIteratorType = { - PyVarObject_HEAD_INIT(NULL, 0) - MODNAME ".ScandirIterator", /* tp_name */ - sizeof(ScandirIterator), /* tp_basicsize */ - 0, /* tp_itemsize */ - /* methods */ - (destructor)ScandirIterator_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - PyObject_SelfIter, /* tp_iter */ - (iternextfunc)ScandirIterator_iternext, /* tp_iternext */ - ScandirIterator_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ - 0, /* tp_del */ - 0, /* tp_version_tag */ - (destructor)ScandirIterator_finalize, /* tp_finalize */ +static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_dealloc, ScandirIterator_dealloc}, + {Py_tp_finalize, ScandirIterator_finalize}, + {Py_tp_iter, PyObject_SelfIter}, + {Py_tp_iternext, ScandirIterator_iternext}, + {Py_tp_methods, ScandirIterator_methods}, + {0, 0}, }; +static PyType_Spec ScandirIteratorType_spec = { + MODNAME ".ScandirIterator", + sizeof(ScandirIterator), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_FINALIZE, + ScandirIteratorType_slots +}; + +static PyTypeObject* ScandirIteratorType; + /*[clinic input] os.scandir @@ -12846,7 +12797,7 @@ os_scandir_impl(PyObject *module, path_t *path) #endif #endif - iterator = PyObject_New(ScandirIterator, &ScandirIteratorType); + iterator = PyObject_New(ScandirIterator, ScandirIteratorType); if (!iterator) return NULL; @@ -13949,9 +13900,11 @@ INITFUNC(void) } /* initialize scandir types */ - if (PyType_Ready(&ScandirIteratorType) < 0) + ScandirIteratorType = (PyTypeObject *)PyType_FromSpec(&ScandirIteratorType_spec); + if (ScandirIteratorType == NULL) return NULL; - if (PyType_Ready(&DirEntryType) < 0) + DirEntryType = (PyTypeObject *)PyType_FromSpec(&DirEntryType_spec); + if (DirEntryType == NULL) return NULL; } #if defined(HAVE_WAITID) && !defined(__APPLE__) @@ -14055,8 +14008,8 @@ INITFUNC(void) } PyModule_AddObject(m, "_have_functions", list); - Py_INCREF((PyObject *) &DirEntryType); - PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType); + Py_INCREF((PyObject *) DirEntryType); + PyModule_AddObject(m, "DirEntry", (PyObject *)DirEntryType); initialized = 1; From 40f0ff45f1baee07f416d496c7ddf31b2b706dce Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:39:59 -0800 Subject: [PATCH 0002/1727] Added NEWS --- Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst new file mode 100644 index 00000000000000..760af024df1b87 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst @@ -0,0 +1 @@ +Move the remaining posixmodule types to be Heap-allocated. From 5be18a1550de63d2d8b5e1a51e35f7f0b2301eb1 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Sun, 2 Dec 2018 22:42:22 -0800 Subject: [PATCH 0003/1727] Updated hash --- Modules/posixmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d3e03fa574b712..d2019d9a3b2ffe 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -11999,7 +11999,7 @@ os_set_blocking_impl(PyObject *module, int fd, int blocking) /*[clinic input] class os.DirEntry "DirEntry *" "DirEntryType" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3138f09f7c683f1d]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=3c18c7a448247980]*/ typedef struct { PyObject_HEAD From 9479848307c2ab7c97f94405f7978bb42d02f7d8 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:44:31 -0800 Subject: [PATCH 0004/1727] Addressed PR Issues --- Include/objimpl.h | 3 + Lib/test/test_os.py | 30 ++++++++ .../2018-12-02-22-39-41.bpo-35381.HjI3j_.rst | 1 - Modules/clinic/posixmodule.c.h | 47 ++++++++++++- Modules/posixmodule.c | 69 +++++++++++++++++++ Objects/object.c | 8 ++- 6 files changed, 153 insertions(+), 5 deletions(-) delete mode 100644 Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst diff --git a/Include/objimpl.h b/Include/objimpl.h index f475ed001d02f8..2337d8a56c774e 100644 --- a/Include/objimpl.h +++ b/Include/objimpl.h @@ -138,6 +138,9 @@ _PyObject_INIT(PyObject *op, PyTypeObject *typeobj) { assert(op != NULL); Py_TYPE(op) = typeobj; + if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(typeobj); + } _Py_NewReference(op); return op; } diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index aca445f9162004..6332a14c941f72 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -3324,6 +3324,24 @@ def test_os_all(self): self.assertIn('walk', os.__all__) +class TestDirEntry(unittest.TestCase): + def setUp(self): + self.path = os.path.realpath(support.TESTFN) + self.addCleanup(support.rmtree, self.path) + os.mkdir(self.path) + + def test_uninstantiable(self): + self.assertRaises(TypeError, os.DirEntry) + + def test_unpickable(self): + filename = create_file(os.path.join(self.path, "file.txt"), b'python') + entry = [entry for entry in os.scandir(self.path)].pop() + self.assertIsInstance(entry, os.DirEntry) + self.assertEqual(entry.name, "file.txt") + import pickle + self.assertRaises(TypeError, pickle.dumps, entry, filename) + + class TestScandir(unittest.TestCase): check_no_resource_warning = support.check_no_resource_warning @@ -3358,6 +3376,18 @@ def assert_stat_equal(self, stat1, stat2, skip_fields): else: self.assertEqual(stat1, stat2) + def test_uninstantiable(self): + scandir_iter = os.scandir(self.path) + self.assertRaises(TypeError, type(scandir_iter)) + scandir_iter.close() + + def test_unpickable(self): + filename = self.create_file("file.txt") + scandir_iter = os.scandir(self.path) + import pickle + self.assertRaises(TypeError, pickle.dumps, scandir_iter, filename) + scandir_iter.close() + def check_entry(self, entry, name, is_dir, is_file, is_symlink): self.assertIsInstance(entry, os.DirEntry) self.assertEqual(entry.name, name) diff --git a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst b/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst deleted file mode 100644 index 760af024df1b87..00000000000000 --- a/Misc/NEWS.d/next/C API/2018-12-02-22-39-41.bpo-35381.HjI3j_.rst +++ /dev/null @@ -1 +0,0 @@ -Move the remaining posixmodule types to be Heap-allocated. diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index 80690703ee2c65..28f06b93f4b145 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -6116,6 +6116,51 @@ os_DirEntry_inode(DirEntry *self, PyObject *Py_UNUSED(ignored)) return os_DirEntry_inode_impl(self); } +PyDoc_STRVAR(os_DirEntry___reduce____doc__, +"__reduce__($self, /)\n" +"--\n" +"\n" +"returns null and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE___METHODDEF \ + {"__reduce__", (PyCFunction)os_DirEntry___reduce__, METH_NOARGS, os_DirEntry___reduce____doc__}, + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self); + +static PyObject * +os_DirEntry___reduce__(DirEntry *self, PyObject *Py_UNUSED(ignored)) +{ + return os_DirEntry___reduce___impl(self); +} + +PyDoc_STRVAR(os_DirEntry___reduce_ex____doc__, +"__reduce_ex__($self, protocol, /)\n" +"--\n" +"\n" +"Returns NULL and raises an exception to avoid pickling"); + +#define OS_DIRENTRY___REDUCE_EX___METHODDEF \ + {"__reduce_ex__", (PyCFunction)os_DirEntry___reduce_ex__, METH_O, os_DirEntry___reduce_ex____doc__}, + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol); + +static PyObject * +os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) +{ + PyObject *return_value = NULL; + int protocol; + + if (!PyArg_Parse(arg, "i:__reduce_ex__", &protocol)) { + goto exit; + } + return_value = os_DirEntry___reduce_ex___impl(self, protocol); + +exit: + return return_value; +} + PyDoc_STRVAR(os_DirEntry___fspath____doc__, "__fspath__($self, /)\n" "--\n" @@ -6757,4 +6802,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=d62c0bb988141e70 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=e061751fda697cda input=a9049054013a1b77]*/ diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index d2019d9a3b2ffe..ea7a00183fbd10 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12020,6 +12020,14 @@ typedef struct { #endif } DirEntry; +static PyObject * +DirEntry_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + static void DirEntry_dealloc(DirEntry *entry) { @@ -12027,6 +12035,7 @@ DirEntry_dealloc(DirEntry *entry) Py_XDECREF(entry->path); Py_XDECREF(entry->stat); Py_XDECREF(entry->lstat); + Py_DECREF(Py_TYPE(entry)); Py_TYPE(entry)->tp_free((PyObject *)entry); } @@ -12287,6 +12296,37 @@ os_DirEntry_inode_impl(DirEntry *self) #endif } +/*[clinic input] +os.DirEntry.__reduce__ + +returns null and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce___impl(DirEntry *self) +/*[clinic end generated code: output=45167543e30c210c input=c1689a589f9c38f2]*/ +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +/*[clinic input] +os.DirEntry.__reduce_ex__ + + protocol: int + / + +Returns NULL and raises an exception to avoid pickling +[clinic start generated code]*/ + +static PyObject * +os_DirEntry___reduce_ex___impl(DirEntry *self, int protocol) +/*[clinic end generated code: output=a81881dfe241a631 input=1afbee3b136a7ece]*/ +{ + return os_DirEntry___reduce___impl(self); +} + static PyObject * DirEntry_repr(DirEntry *self) { @@ -12318,6 +12358,8 @@ static PyMemberDef DirEntry_members[] = { #include "clinic/posixmodule.c.h" static PyMethodDef DirEntry_methods[] = { + OS_DIRENTRY___REDUCE___METHODDEF + OS_DIRENTRY___REDUCE_EX___METHODDEF OS_DIRENTRY_IS_DIR_METHODDEF OS_DIRENTRY_IS_FILE_METHODDEF OS_DIRENTRY_IS_SYMLINK_METHODDEF @@ -12328,6 +12370,7 @@ static PyMethodDef DirEntry_methods[] = { }; static PyType_Slot DirEntryType_slots[] = { + {Py_tp_new, DirEntry_new}, {Py_tp_dealloc, DirEntry_dealloc}, {Py_tp_repr, DirEntry_repr}, {Py_tp_methods, DirEntry_methods}, @@ -12734,16 +12777,41 @@ ScandirIterator_finalize(ScandirIterator *iterator) PyErr_Restore(error_type, error_value, error_traceback); } +static PyObject * +ScandirIterator_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", type->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce(PyObject *self, PyObject *args, PyObject *kwargs) +{ + PyErr_Format(PyExc_TypeError, + "cannot pickle '%.100s' instances", Py_TYPE(self)->tp_name); + return NULL; +} + +static PyObject * +ScandirIterator_reduce_ex(PyObject *self, PyObject *arg) +{ + return ScandirIterator_reduce(self, NULL, NULL); +} + static void ScandirIterator_dealloc(ScandirIterator *iterator) { if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0) return; + Py_DECREF(Py_TYPE(iterator)); Py_TYPE(iterator)->tp_free((PyObject *)iterator); } static PyMethodDef ScandirIterator_methods[] = { + {"__reduce__", (PyCFunction)ScandirIterator_reduce, METH_NOARGS}, + {"__reduce_ex__", (PyCFunction)ScandirIterator_reduce_ex, METH_O}, {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS}, {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS}, {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS}, @@ -12751,6 +12819,7 @@ static PyMethodDef ScandirIterator_methods[] = { }; static PyType_Slot ScandirIteratorType_slots[] = { + {Py_tp_new, ScandirIterator_new}, {Py_tp_dealloc, ScandirIterator_dealloc}, {Py_tp_finalize, ScandirIterator_finalize}, {Py_tp_iter, PyObject_SelfIter}, diff --git a/Objects/object.c b/Objects/object.c index c2d78aa47e65c5..39dfc1587cb437 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -230,6 +230,9 @@ PyObject_Init(PyObject *op, PyTypeObject *tp) return PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT (objimpl.h) */ Py_TYPE(op) = tp; + if (PyType_GetFlags(tp) & Py_TPFLAGS_HEAPTYPE) { + Py_INCREF(tp); + } _Py_NewReference(op); return op; } @@ -240,9 +243,8 @@ PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size) if (op == NULL) return (PyVarObject *) PyErr_NoMemory(); /* Any changes should be reflected in PyObject_INIT_VAR */ - op->ob_size = size; - Py_TYPE(op) = tp; - _Py_NewReference((PyObject *)op); + Py_SIZE(op) = size; + PyObject_Init((PyObject *)op, tp); return op; } From c84689c5ef6949107f645153c3b11ee35f826135 Mon Sep 17 00:00:00 2001 From: Eddie Elizondo Date: Fri, 18 Jan 2019 16:59:52 -0800 Subject: [PATCH 0005/1727] Ran argument clinic --- Modules/clinic/posixmodule.c.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h index d6bf9ad8548fec..d6b76d6a7021ca 100644 --- a/Modules/clinic/posixmodule.c.h +++ b/Modules/clinic/posixmodule.c.h @@ -6722,7 +6722,13 @@ os_DirEntry___reduce_ex__(DirEntry *self, PyObject *arg) PyObject *return_value = NULL; int protocol; - if (!PyArg_Parse(arg, "i:__reduce_ex__", &protocol)) { + if (PyFloat_Check(arg)) { + PyErr_SetString(PyExc_TypeError, + "integer argument expected, got float" ); + goto exit; + } + protocol = _PyLong_AsInt(arg); + if (protocol == -1 && PyErr_Occurred()) { goto exit; } return_value = os_DirEntry___reduce_ex___impl(self, protocol); @@ -7376,4 +7382,4 @@ os_getrandom(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject #ifndef OS_GETRANDOM_METHODDEF #define OS_GETRANDOM_METHODDEF #endif /* !defined(OS_GETRANDOM_METHODDEF) */ -/*[clinic end generated code: output=dabd0fa27bf87044 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=8c980838ccf517c3 input=a9049054013a1b77]*/ From 796a8d7b601a9cdf0f22cf4ecb28199f57535b19 Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Fri, 18 Jan 2019 17:05:33 -0800 Subject: [PATCH 0006/1727] Added NEWS --- .../next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst diff --git a/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst new file mode 100644 index 00000000000000..b64644659e78fa --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-01-18-17-05-26.bpo-35381.9CbeW3.rst @@ -0,0 +1,4 @@ +Convert posixmodule.c statically allocated types ``DirEntryType`` and +``ScandirIteratorType`` to heap-allocated types. This also modified +`PyObject_New` and `PyObject_NewVar` to increase the type refcount for heap- +allocated types. From b7cae5b7ab330465b468d489cfbf0eeb52f05d5d Mon Sep 17 00:00:00 2001 From: eduardo-elizondo Date: Fri, 18 Jan 2019 17:47:08 -0800 Subject: [PATCH 0007/1727] Remove INCREF from GenericAlloc --- Objects/typeobject.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ace45ba5794ba4..abe92a4fb6e760 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -981,9 +981,6 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems) memset(obj, '\0', size); - if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) - Py_INCREF(type); - if (type->tp_itemsize == 0) (void)PyObject_INIT(obj, type); else From ca7d2933a388677cc3bbc621913b479452c0f25a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Langa?= Date: Mon, 4 Feb 2019 09:39:24 +0100 Subject: [PATCH 0008/1727] Post 3.8.0a1 --- Include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 611dea8af4aa0e..91efd275af528c 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.8.0a1" +#define PY_VERSION "3.8.0a1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From 89427cd0feae25bbc8693abdccfa6a8c81a2689c Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Mon, 4 Feb 2019 14:42:04 -0500 Subject: [PATCH 0009/1727] bpo-32417: Make timedelta arithmetic respect subclasses (#10902) * Make timedelta return subclass types Previously timedelta would always return the `date` and `datetime` types, regardless of what it is added to. This makes it return an object of the type it was added to. * Add tests for timedelta arithmetic on subclasses * Make pure python timedelta return subclass types * Add test for fromtimestamp with tz argument * Add tests for subclass behavior in now * Add news entry. Fixes: bpo-32417 bpo-35364 * More descriptive variable names in tests Addresses Victor's comments --- Lib/datetime.py | 10 +-- Lib/test/datetimetester.py | 83 ++++++++++++++++--- .../2018-12-04-13-35-36.bpo-32417._Y9SKM.rst | 6 ++ Modules/_datetimemodule.c | 10 ++- 4 files changed, 90 insertions(+), 19 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-04-13-35-36.bpo-32417._Y9SKM.rst diff --git a/Lib/datetime.py b/Lib/datetime.py index 4780b6df8f9bcd..89c32c0b0a6301 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1014,7 +1014,7 @@ def __add__(self, other): if isinstance(other, timedelta): o = self.toordinal() + other.days if 0 < o <= _MAXORDINAL: - return date.fromordinal(o) + return type(self).fromordinal(o) raise OverflowError("result out of range") return NotImplemented @@ -2024,10 +2024,10 @@ def __add__(self, other): hour, rem = divmod(delta.seconds, 3600) minute, second = divmod(rem, 60) if 0 < delta.days <= _MAXORDINAL: - return datetime.combine(date.fromordinal(delta.days), - time(hour, minute, second, - delta.microseconds, - tzinfo=self._tzinfo)) + return type(self).combine(date.fromordinal(delta.days), + time(hour, minute, second, + delta.microseconds, + tzinfo=self._tzinfo)) raise OverflowError("result out of range") __radd__ = __add__ diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index d729c7efd52fde..958b33675c37b3 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -820,6 +820,44 @@ def as_hours(self): self.assertEqual(str(t3), str(t4)) self.assertEqual(t4.as_hours(), -1) + def test_subclass_date(self): + class DateSubclass(date): + pass + + d1 = DateSubclass(2018, 1, 5) + td = timedelta(days=1) + + tests = [ + ('add', lambda d, t: d + t, DateSubclass(2018, 1, 6)), + ('radd', lambda d, t: t + d, DateSubclass(2018, 1, 6)), + ('sub', lambda d, t: d - t, DateSubclass(2018, 1, 4)), + ] + + for name, func, expected in tests: + with self.subTest(name): + act = func(d1, td) + self.assertEqual(act, expected) + self.assertIsInstance(act, DateSubclass) + + def test_subclass_datetime(self): + class DateTimeSubclass(datetime): + pass + + d1 = DateTimeSubclass(2018, 1, 5, 12, 30) + td = timedelta(days=1, minutes=30) + + tests = [ + ('add', lambda d, t: d + t, DateTimeSubclass(2018, 1, 6, 13)), + ('radd', lambda d, t: t + d, DateTimeSubclass(2018, 1, 6, 13)), + ('sub', lambda d, t: d - t, DateTimeSubclass(2018, 1, 4, 12)), + ] + + for name, func, expected in tests: + with self.subTest(name): + act = func(d1, td) + self.assertEqual(act, expected) + self.assertIsInstance(act, DateTimeSubclass) + def test_division(self): t = timedelta(hours=1, minutes=24, seconds=19) second = timedelta(seconds=1) @@ -2604,33 +2642,58 @@ def __new__(cls, *args, **kwargs): ts = base_d.timestamp() test_cases = [ - ('fromtimestamp', (ts,)), + ('fromtimestamp', (ts,), base_d), # See https://bugs.python.org/issue32417 - # ('fromtimestamp', (ts, timezone.utc)), - ('utcfromtimestamp', (utc_ts,)), - ('fromisoformat', (d_isoformat,)), - ('strptime', (d_isoformat, '%Y-%m-%dT%H:%M:%S.%f')), - ('combine', (date(*args[0:3]), time(*args[3:]))), + ('fromtimestamp', (ts, timezone.utc), + base_d.astimezone(timezone.utc)), + ('utcfromtimestamp', (utc_ts,), base_d), + ('fromisoformat', (d_isoformat,), base_d), + ('strptime', (d_isoformat, '%Y-%m-%dT%H:%M:%S.%f'), base_d), + ('combine', (date(*args[0:3]), time(*args[3:])), base_d), ] - for constr_name, constr_args in test_cases: + for constr_name, constr_args, expected in test_cases: for base_obj in (DateTimeSubclass, base_d): # Test both the classmethod and method with self.subTest(base_obj_type=type(base_obj), constr_name=constr_name): - constr = getattr(base_obj, constr_name) + constructor = getattr(base_obj, constr_name) - dt = constr(*constr_args) + dt = constructor(*constr_args) # Test that it creates the right subclass self.assertIsInstance(dt, DateTimeSubclass) # Test that it's equal to the base object - self.assertEqual(dt, base_d.replace(tzinfo=None)) + self.assertEqual(dt, expected) # Test that it called the constructor self.assertEqual(dt.extra, 7) + def test_subclass_now(self): + # Test that alternate constructors call the constructor + class DateTimeSubclass(self.theclass): + def __new__(cls, *args, **kwargs): + result = self.theclass.__new__(cls, *args, **kwargs) + result.extra = 7 + + return result + + test_cases = [ + ('now', 'now', {}), + ('utcnow', 'utcnow', {}), + ('now_utc', 'now', {'tz': timezone.utc}), + ('now_fixed', 'now', {'tz': timezone(timedelta(hours=-5), "EST")}), + ] + + for name, meth_name, kwargs in test_cases: + with self.subTest(name): + constr = getattr(DateTimeSubclass, meth_name) + dt = constr(**kwargs) + + self.assertIsInstance(dt, DateTimeSubclass) + self.assertEqual(dt.extra, 7) + def test_fromisoformat_datetime(self): # Test that isoformat() is reversible base_dates = [ diff --git a/Misc/NEWS.d/next/Library/2018-12-04-13-35-36.bpo-32417._Y9SKM.rst b/Misc/NEWS.d/next/Library/2018-12-04-13-35-36.bpo-32417._Y9SKM.rst new file mode 100644 index 00000000000000..cfc4fbe2e68677 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-04-13-35-36.bpo-32417._Y9SKM.rst @@ -0,0 +1,6 @@ +Performing arithmetic between :class:`datetime.datetime` subclasses and +:class:`datetime.timedelta` now returns an object of the same type as the +:class:`datetime.datetime` subclass. As a result, +:meth:`datetime.datetime.astimezone` and alternate constructors like +:meth:`datetime.datetime.now` and :meth:`datetime.fromtimestamp` called with +a ``tz`` argument now *also* retain their subclass. diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c index 7997758908bb4d..c1557b5e6f491d 100644 --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -3004,7 +3004,8 @@ add_date_timedelta(PyDateTime_Date *date, PyDateTime_Delta *delta, int negate) int day = GET_DAY(date) + (negate ? -deltadays : deltadays); if (normalize_date(&year, &month, &day) >= 0) - result = new_date(year, month, day); + result = new_date_subclass_ex(year, month, day, + (PyObject* )Py_TYPE(date)); return result; } @@ -5166,9 +5167,10 @@ add_datetime_timedelta(PyDateTime_DateTime *date, PyDateTime_Delta *delta, return NULL; } - return new_datetime(year, month, day, - hour, minute, second, microsecond, - HASTZINFO(date) ? date->tzinfo : Py_None, 0); + return new_datetime_subclass_ex(year, month, day, + hour, minute, second, microsecond, + HASTZINFO(date) ? date->tzinfo : Py_None, + (PyObject *)Py_TYPE(date)); } static PyObject * From 69091cb497b2f0fe7e2789b30b43cf78caf9de9b Mon Sep 17 00:00:00 2001 From: Nina Zakharenko Date: Mon, 4 Feb 2019 16:56:26 -0800 Subject: [PATCH 0010/1727] bpo-35321: Set the spec origin to frozen in frozen modules (#11732) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bpo-35321: Set the spec origin to frozen in frozen modules This fix correctly sets the spec origin to "frozen" for the _frozen_importlib module. Note that the origin was already correctly set in _frozen_importlib_external. * 📜🤖 Added by blurb_it. --- Lib/importlib/_bootstrap.py | 6 +- Lib/test/test_imp.py | 11 + .../2019-02-02-01-53-36.bpo-35321.1Y4DU4.rst | 1 + Python/importlib.h | 1313 +++++++++-------- 4 files changed, 673 insertions(+), 658 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-02-02-01-53-36.bpo-35321.1Y4DU4.rst diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 857583afde2677..70b706a36ea866 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -786,6 +786,8 @@ class FrozenImporter: """ + _ORIGIN = "frozen" + @staticmethod def module_repr(m): """Return repr for the module. @@ -793,12 +795,12 @@ def module_repr(m): The method is deprecated. The import machinery does the job itself. """ - return ''.format(m.__name__) + return ''.format(m.__name__, FrozenImporter._ORIGIN) @classmethod def find_spec(cls, fullname, path=None, target=None): if _imp.is_frozen(fullname): - return spec_from_loader(fullname, cls, origin='frozen') + return spec_from_loader(fullname, cls, origin=cls._ORIGIN) else: return None diff --git a/Lib/test/test_imp.py b/Lib/test/test_imp.py index bb0144b12d4107..fe394dc50c56b1 100644 --- a/Lib/test/test_imp.py +++ b/Lib/test/test_imp.py @@ -332,6 +332,17 @@ class BadSpec: with self.assertRaises(TypeError): create_dynamic(BadSpec()) + def test_issue_35321(self): + # Both _frozen_importlib and _frozen_importlib_external + # should have a spec origin of "frozen" and + # no need to clean up imports in this case. + + import _frozen_importlib_external + self.assertEqual(_frozen_importlib_external.__spec__.origin, "frozen") + + import _frozen_importlib + self.assertEqual(_frozen_importlib.__spec__.origin, "frozen") + def test_source_hash(self): self.assertEqual(_imp.source_hash(42, b'hi'), b'\xc6\xe7Z\r\x03:}\xab') self.assertEqual(_imp.source_hash(43, b'hi'), b'\x85\x9765\xf8\x9a\x8b9') diff --git a/Misc/NEWS.d/next/Library/2019-02-02-01-53-36.bpo-35321.1Y4DU4.rst b/Misc/NEWS.d/next/Library/2019-02-02-01-53-36.bpo-35321.1Y4DU4.rst new file mode 100644 index 00000000000000..aa22384d102508 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-02-01-53-36.bpo-35321.1Y4DU4.rst @@ -0,0 +1 @@ +Set ``__spec__.origin`` of ``_frozen_importlib`` to frozen so that it matches the behavior of ``_frozen_importlib_external``. Patch by Nina Zakharenko. \ No newline at end of file diff --git a/Python/importlib.h b/Python/importlib.h index dd78c0b9d2b925..b5774f83de607b 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -784,7 +784,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 110,2,100,3,124,3,95,10,124,6,124,3,95,11,124,7, 124,3,95,12,124,3,83,0,41,4,78,169,1,114,113,0, 0,0,70,84,41,13,114,105,0,0,0,114,106,0,0,0, - 114,1,0,0,0,114,98,0,0,0,114,108,0,0,0,90, + 114,1,0,0,0,114,98,0,0,0,114,108,0,0,0,218, 7,95,79,82,73,71,73,78,218,10,95,95,99,97,99,104, 101,100,95,95,218,4,108,105,115,116,218,8,95,95,112,97, 116,104,95,95,114,112,0,0,0,114,118,0,0,0,114,123, @@ -798,7 +798,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 6,1,8,1,2,1,10,1,14,2,6,1,2,1,10,1, 14,1,10,1,8,1,8,1,2,1,10,1,14,1,12,2, 4,1,2,1,10,1,14,1,10,1,2,1,14,1,16,1, - 10,2,14,1,20,1,6,1,6,1,114,141,0,0,0,70, + 10,2,14,1,20,1,6,1,6,1,114,142,0,0,0,70, 169,1,218,8,111,118,101,114,114,105,100,101,99,2,0,0, 0,1,0,0,0,5,0,0,0,8,0,0,0,67,0,0, 0,115,226,1,0,0,124,2,115,20,116,0,124,1,100,1, @@ -833,17 +833,17 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,3,107,10,144,1,114,220,1,0,1,0,1,0,89,0, 110,2,88,0,124,1,83,0,41,7,78,114,1,0,0,0, 114,98,0,0,0,218,11,95,95,112,97,99,107,97,103,101, - 95,95,114,140,0,0,0,114,108,0,0,0,114,138,0,0, + 95,95,114,141,0,0,0,114,108,0,0,0,114,139,0,0, 0,41,21,114,6,0,0,0,114,17,0,0,0,114,1,0, 0,0,114,106,0,0,0,114,109,0,0,0,114,117,0,0, 0,114,126,0,0,0,114,127,0,0,0,218,16,95,78,97, 109,101,115,112,97,99,101,76,111,97,100,101,114,218,7,95, 95,110,101,119,95,95,90,5,95,112,97,116,104,114,108,0, - 0,0,114,98,0,0,0,114,130,0,0,0,114,144,0,0, - 0,114,105,0,0,0,114,140,0,0,0,114,124,0,0,0, - 114,113,0,0,0,114,123,0,0,0,114,138,0,0,0,41, - 5,114,95,0,0,0,114,96,0,0,0,114,143,0,0,0, - 114,109,0,0,0,114,145,0,0,0,114,10,0,0,0,114, + 0,0,114,98,0,0,0,114,130,0,0,0,114,145,0,0, + 0,114,105,0,0,0,114,141,0,0,0,114,124,0,0,0, + 114,113,0,0,0,114,123,0,0,0,114,139,0,0,0,41, + 5,114,95,0,0,0,114,96,0,0,0,114,144,0,0,0, + 114,109,0,0,0,114,146,0,0,0,114,10,0,0,0,114, 10,0,0,0,114,11,0,0,0,218,18,95,105,110,105,116, 95,109,111,100,117,108,101,95,97,116,116,114,115,221,1,0, 0,115,96,0,0,0,0,4,20,1,2,1,12,1,14,1, @@ -852,7 +852,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 20,1,2,1,12,1,14,1,6,2,2,1,10,1,16,1, 6,2,24,1,12,1,2,1,12,1,16,1,6,2,8,1, 24,1,2,1,12,1,16,1,6,2,24,1,12,1,2,1, - 12,1,16,1,6,1,114,147,0,0,0,99,1,0,0,0, + 12,1,16,1,6,1,114,148,0,0,0,99,1,0,0,0, 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, 115,82,0,0,0,100,1,125,1,116,0,124,0,106,1,100, 2,131,2,114,30,124,0,106,1,160,2,124,0,161,1,125, @@ -869,13 +869,13 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 100,117,108,101,40,41,32,109,117,115,116,32,97,108,115,111, 32,100,101,102,105,110,101,32,99,114,101,97,116,101,95,109, 111,100,117,108,101,40,41,41,7,114,4,0,0,0,114,109, - 0,0,0,114,148,0,0,0,114,79,0,0,0,114,18,0, - 0,0,114,17,0,0,0,114,147,0,0,0,169,2,114,95, + 0,0,0,114,149,0,0,0,114,79,0,0,0,114,18,0, + 0,0,114,17,0,0,0,114,148,0,0,0,169,2,114,95, 0,0,0,114,96,0,0,0,114,10,0,0,0,114,10,0, 0,0,114,11,0,0,0,218,16,109,111,100,117,108,101,95, 102,114,111,109,95,115,112,101,99,37,2,0,0,115,18,0, 0,0,0,3,4,1,12,3,14,1,12,1,8,2,8,1, - 10,1,10,1,114,151,0,0,0,99,1,0,0,0,0,0, + 10,1,10,1,114,152,0,0,0,99,1,0,0,0,0,0, 0,0,2,0,0,0,4,0,0,0,67,0,0,0,115,106, 0,0,0,124,0,106,0,100,1,107,8,114,14,100,2,110, 4,124,0,106,0,125,1,124,0,106,1,100,1,107,8,114, @@ -887,7 +887,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 38,82,101,116,117,114,110,32,116,104,101,32,114,101,112,114, 32,116,111,32,117,115,101,32,102,111,114,32,116,104,101,32, 109,111,100,117,108,101,46,78,114,100,0,0,0,114,101,0, - 0,0,114,102,0,0,0,114,103,0,0,0,122,18,60,109, + 0,0,114,102,0,0,0,114,103,0,0,0,250,18,60,109, 111,100,117,108,101,32,123,33,114,125,32,40,123,125,41,62, 41,5,114,17,0,0,0,114,113,0,0,0,114,109,0,0, 0,114,45,0,0,0,114,124,0,0,0,41,2,114,95,0, @@ -917,12 +917,12 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 101,32,123,33,114,125,32,110,111,116,32,105,110,32,115,121, 115,46,109,111,100,117,108,101,115,114,16,0,0,0,78,250, 14,109,105,115,115,105,110,103,32,108,111,97,100,101,114,84, - 114,142,0,0,0,114,149,0,0,0,41,14,114,17,0,0, + 114,143,0,0,0,114,150,0,0,0,41,14,114,17,0,0, 0,114,50,0,0,0,114,15,0,0,0,114,92,0,0,0, 114,34,0,0,0,114,45,0,0,0,114,79,0,0,0,114, - 109,0,0,0,114,117,0,0,0,114,147,0,0,0,114,4, + 109,0,0,0,114,117,0,0,0,114,148,0,0,0,114,4, 0,0,0,218,11,108,111,97,100,95,109,111,100,117,108,101, - 114,149,0,0,0,218,3,112,111,112,41,4,114,95,0,0, + 114,150,0,0,0,218,3,112,111,112,41,4,114,95,0,0, 0,114,96,0,0,0,114,17,0,0,0,218,3,109,115,103, 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, 93,0,0,0,71,2,0,0,115,34,0,0,0,0,2,6, @@ -948,20 +948,20 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,22,122,10,124,0,124,1,95,13,87,0,110,22,4,0, 116,8,107,10,144,1,114,20,1,0,1,0,1,0,89,0, 110,2,88,0,124,1,83,0,41,7,78,114,98,0,0,0, - 114,144,0,0,0,114,140,0,0,0,114,128,0,0,0,114, + 114,145,0,0,0,114,141,0,0,0,114,128,0,0,0,114, 22,0,0,0,114,105,0,0,0,41,14,114,109,0,0,0, - 114,153,0,0,0,114,17,0,0,0,114,15,0,0,0,114, - 92,0,0,0,114,154,0,0,0,114,6,0,0,0,114,98, - 0,0,0,114,106,0,0,0,114,1,0,0,0,114,144,0, + 114,155,0,0,0,114,17,0,0,0,114,15,0,0,0,114, + 92,0,0,0,114,156,0,0,0,114,6,0,0,0,114,98, + 0,0,0,114,106,0,0,0,114,1,0,0,0,114,145,0, 0,0,114,4,0,0,0,114,129,0,0,0,114,105,0,0, - 0,114,150,0,0,0,114,10,0,0,0,114,10,0,0,0, + 0,114,151,0,0,0,114,10,0,0,0,114,10,0,0,0, 114,11,0,0,0,218,25,95,108,111,97,100,95,98,97,99, 107,119,97,114,100,95,99,111,109,112,97,116,105,98,108,101, 101,2,0,0,115,54,0,0,0,0,4,2,1,18,1,6, 1,12,1,14,1,12,1,8,3,14,1,12,1,16,1,2, 1,12,1,14,1,6,1,16,1,2,4,8,1,10,1,22, 1,14,1,6,1,18,1,2,1,10,1,16,1,6,1,114, - 156,0,0,0,99,1,0,0,0,0,0,0,0,2,0,0, + 158,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,220,0,0,0,124,0, 106,0,100,0,107,9,114,30,116,1,124,0,106,0,100,1, 131,2,115,30,116,2,124,0,131,1,83,0,116,3,124,0, @@ -976,21 +976,21 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,5,106,6,160,12,124,0,106,7,161,1,125,1,124,1, 116,5,106,6,124,0,106,7,60,0,116,13,100,5,124,0, 106,7,124,0,106,0,131,3,1,0,87,0,53,0,100,6, - 124,0,95,4,88,0,124,1,83,0,41,7,78,114,149,0, - 0,0,84,114,152,0,0,0,114,16,0,0,0,122,18,105, + 124,0,95,4,88,0,124,1,83,0,41,7,78,114,150,0, + 0,0,84,114,154,0,0,0,114,16,0,0,0,122,18,105, 109,112,111,114,116,32,123,33,114,125,32,35,32,123,33,114, - 125,70,41,14,114,109,0,0,0,114,4,0,0,0,114,156, - 0,0,0,114,151,0,0,0,90,13,95,105,110,105,116,105, + 125,70,41,14,114,109,0,0,0,114,4,0,0,0,114,158, + 0,0,0,114,152,0,0,0,90,13,95,105,110,105,116,105, 97,108,105,122,105,110,103,114,15,0,0,0,114,92,0,0, 0,114,17,0,0,0,114,117,0,0,0,114,79,0,0,0, - 114,149,0,0,0,114,63,0,0,0,114,154,0,0,0,114, - 76,0,0,0,114,150,0,0,0,114,10,0,0,0,114,10, + 114,150,0,0,0,114,63,0,0,0,114,156,0,0,0,114, + 76,0,0,0,114,151,0,0,0,114,10,0,0,0,114,10, 0,0,0,114,11,0,0,0,218,14,95,108,111,97,100,95, 117,110,108,111,99,107,101,100,138,2,0,0,115,46,0,0, 0,0,2,10,2,12,1,8,2,8,5,6,1,2,1,12, 1,2,1,10,1,10,1,16,3,16,1,6,1,2,1,14, 1,14,1,6,1,8,5,14,1,12,1,20,2,8,2,114, - 157,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, + 159,0,0,0,99,1,0,0,0,0,0,0,0,1,0,0, 0,10,0,0,0,67,0,0,0,115,42,0,0,0,116,0, 124,0,106,1,131,1,143,22,1,0,116,2,124,0,131,1, 87,0,2,0,53,0,81,0,82,0,163,0,83,0,81,0, @@ -1007,7 +1007,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,32,101,120,105,115,116,105,110,103,32,109,111,100,117,108, 101,32,103,101,116,115,10,32,32,32,32,99,108,111,98,98, 101,114,101,100,46,10,10,32,32,32,32,78,41,3,114,50, - 0,0,0,114,17,0,0,0,114,157,0,0,0,41,1,114, + 0,0,0,114,17,0,0,0,114,159,0,0,0,41,1,114, 95,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, 0,0,0,114,94,0,0,0,180,2,0,0,115,4,0,0, 0,0,9,12,1,114,94,0,0,0,99,0,0,0,0,0, @@ -1042,7 +1042,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,24, 60,109,111,100,117,108,101,32,123,33,114,125,32,40,98,117, - 105,108,116,45,105,110,41,62,169,2,114,45,0,0,0,114, + 105,108,116,45,105,110,41,62,41,2,114,45,0,0,0,114, 1,0,0,0,41,1,114,96,0,0,0,114,10,0,0,0, 114,10,0,0,0,114,11,0,0,0,114,99,0,0,0,204, 2,0,0,115,2,0,0,0,0,7,122,27,66,117,105,108, @@ -1075,8 +1075,8 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 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,165,0,0,0,114,109,0, - 0,0,41,4,114,162,0,0,0,114,81,0,0,0,114,163, + 32,32,32,32,32,78,41,2,114,166,0,0,0,114,109,0, + 0,0,41,4,114,163,0,0,0,114,81,0,0,0,114,164, 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, 0,0,114,11,0,0,0,218,11,102,105,110,100,95,109,111, 100,117,108,101,222,2,0,0,115,4,0,0,0,0,9,12, @@ -1093,7 +1093,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,0,114,45,0,0,0,114,67,0,0,0,114,57,0,0, 0,90,14,99,114,101,97,116,101,95,98,117,105,108,116,105, 110,41,2,114,30,0,0,0,114,95,0,0,0,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,148,0,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,149,0,0, 0,234,2,0,0,115,10,0,0,0,0,3,12,1,12,1, 4,255,6,2,122,29,66,117,105,108,116,105,110,73,109,112, 111,114,116,101,114,46,99,114,101,97,116,101,95,109,111,100, @@ -1104,7 +1104,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 32,109,111,100,117,108,101,78,41,3,114,67,0,0,0,114, 57,0,0,0,90,12,101,120,101,99,95,98,117,105,108,116, 105,110,41,2,114,30,0,0,0,114,96,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,149,0, + 0,0,0,114,10,0,0,0,114,11,0,0,0,114,150,0, 0,0,242,2,0,0,115,2,0,0,0,0,3,122,27,66, 117,105,108,116,105,110,73,109,112,111,114,116,101,114,46,101, 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, @@ -1113,7 +1113,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 114,110,32,78,111,110,101,32,97,115,32,98,117,105,108,116, 45,105,110,32,109,111,100,117,108,101,115,32,100,111,32,110, 111,116,32,104,97,118,101,32,99,111,100,101,32,111,98,106, - 101,99,116,115,46,78,114,10,0,0,0,169,2,114,162,0, + 101,99,116,115,46,78,114,10,0,0,0,169,2,114,163,0, 0,0,114,81,0,0,0,114,10,0,0,0,114,10,0,0, 0,114,11,0,0,0,218,8,103,101,116,95,99,111,100,101, 247,2,0,0,115,2,0,0,0,0,4,122,24,66,117,105, @@ -1124,7 +1124,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 110,101,32,97,115,32,98,117,105,108,116,45,105,110,32,109, 111,100,117,108,101,115,32,100,111,32,110,111,116,32,104,97, 118,101,32,115,111,117,114,99,101,32,99,111,100,101,46,78, - 114,10,0,0,0,114,167,0,0,0,114,10,0,0,0,114, + 114,10,0,0,0,114,168,0,0,0,114,10,0,0,0,114, 10,0,0,0,114,11,0,0,0,218,10,103,101,116,95,115, 111,117,114,99,101,253,2,0,0,115,2,0,0,0,0,4, 122,26,66,117,105,108,116,105,110,73,109,112,111,114,116,101, @@ -1134,7 +1134,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 116,117,114,110,32,70,97,108,115,101,32,97,115,32,98,117, 105,108,116,45,105,110,32,109,111,100,117,108,101,115,32,97, 114,101,32,110,101,118,101,114,32,112,97,99,107,97,103,101, - 115,46,70,114,10,0,0,0,114,167,0,0,0,114,10,0, + 115,46,70,114,10,0,0,0,114,168,0,0,0,114,10,0, 0,0,114,10,0,0,0,114,11,0,0,0,114,115,0,0, 0,3,3,0,0,115,2,0,0,0,0,4,122,26,66,117, 105,108,116,105,110,73,109,112,111,114,116,101,114,46,105,115, @@ -1142,627 +1142,628 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 17,114,1,0,0,0,114,0,0,0,0,114,2,0,0,0, 114,3,0,0,0,218,12,115,116,97,116,105,99,109,101,116, 104,111,100,114,99,0,0,0,218,11,99,108,97,115,115,109, - 101,116,104,111,100,114,165,0,0,0,114,166,0,0,0,114, - 148,0,0,0,114,149,0,0,0,114,86,0,0,0,114,168, - 0,0,0,114,169,0,0,0,114,115,0,0,0,114,97,0, - 0,0,114,153,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,158,0,0,0, + 101,116,104,111,100,114,166,0,0,0,114,167,0,0,0,114, + 149,0,0,0,114,150,0,0,0,114,86,0,0,0,114,169, + 0,0,0,114,170,0,0,0,114,115,0,0,0,114,97,0, + 0,0,114,155,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,160,0,0,0, 195,2,0,0,115,42,0,0,0,8,2,4,7,2,1,10, 8,2,1,12,8,2,1,12,11,2,1,10,7,2,1,10, 4,2,1,2,1,12,4,2,1,2,1,12,4,2,1,2, - 1,12,4,114,158,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,140,0, - 0,0,101,0,90,1,100,0,90,2,100,1,90,3,101,4, - 100,2,100,3,132,0,131,1,90,5,101,6,100,21,100,5, - 100,6,132,1,131,1,90,7,101,6,100,22,100,7,100,8, - 132,1,131,1,90,8,101,6,100,9,100,10,132,0,131,1, - 90,9,101,4,100,11,100,12,132,0,131,1,90,10,101,6, - 100,13,100,14,132,0,131,1,90,11,101,6,101,12,100,15, - 100,16,132,0,131,1,131,1,90,13,101,6,101,12,100,17, - 100,18,132,0,131,1,131,1,90,14,101,6,101,12,100,19, - 100,20,132,0,131,1,131,1,90,15,100,4,83,0,41,23, - 218,14,70,114,111,122,101,110,73,109,112,111,114,116,101,114, - 122,142,77,101,116,97,32,112,97,116,104,32,105,109,112,111, - 114,116,32,102,111,114,32,102,114,111,122,101,110,32,109,111, - 100,117,108,101,115,46,10,10,32,32,32,32,65,108,108,32, - 109,101,116,104,111,100,115,32,97,114,101,32,101,105,116,104, - 101,114,32,99,108,97,115,115,32,111,114,32,115,116,97,116, - 105,99,32,109,101,116,104,111,100,115,32,116,111,32,97,118, - 111,105,100,32,116,104,101,32,110,101,101,100,32,116,111,10, - 32,32,32,32,105,110,115,116,97,110,116,105,97,116,101,32, - 116,104,101,32,99,108,97,115,115,46,10,10,32,32,32,32, - 99,1,0,0,0,0,0,0,0,1,0,0,0,3,0,0, - 0,67,0,0,0,115,12,0,0,0,100,1,160,0,124,0, - 106,1,161,1,83,0,41,2,114,159,0,0,0,122,22,60, - 109,111,100,117,108,101,32,123,33,114,125,32,40,102,114,111, - 122,101,110,41,62,114,160,0,0,0,41,1,218,1,109,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,99, - 0,0,0,21,3,0,0,115,2,0,0,0,0,7,122,26, - 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,109, - 111,100,117,108,101,95,114,101,112,114,78,99,4,0,0,0, - 0,0,0,0,4,0,0,0,5,0,0,0,67,0,0,0, - 115,32,0,0,0,116,0,160,1,124,1,161,1,114,24,116, - 2,124,1,124,0,100,1,100,2,141,3,83,0,100,0,83, - 0,100,0,83,0,41,3,78,90,6,102,114,111,122,101,110, - 114,137,0,0,0,41,3,114,57,0,0,0,114,88,0,0, - 0,114,91,0,0,0,114,161,0,0,0,114,10,0,0,0, - 114,10,0,0,0,114,11,0,0,0,114,165,0,0,0,30, - 3,0,0,115,6,0,0,0,0,2,10,1,14,2,122,24, - 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,102, - 105,110,100,95,115,112,101,99,99,3,0,0,0,0,0,0, - 0,3,0,0,0,3,0,0,0,67,0,0,0,115,18,0, - 0,0,116,0,160,1,124,1,161,1,114,14,124,0,83,0, - 100,1,83,0,41,2,122,93,70,105,110,100,32,97,32,102, - 114,111,122,101,110,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,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,57,0,0,0,114,88,0, - 0,0,41,3,114,162,0,0,0,114,81,0,0,0,114,163, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,166,0,0,0,37,3,0,0,115,2,0,0,0, - 0,7,122,26,70,114,111,122,101,110,73,109,112,111,114,116, - 101,114,46,102,105,110,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,4,0,0,0,100,1,83,0,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,10,0,0,0, - 41,2,114,162,0,0,0,114,95,0,0,0,114,10,0,0, - 0,114,10,0,0,0,114,11,0,0,0,114,148,0,0,0, - 46,3,0,0,115,2,0,0,0,0,2,122,28,70,114,111, - 122,101,110,73,109,112,111,114,116,101,114,46,99,114,101,97, - 116,101,95,109,111,100,117,108,101,99,1,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,64, - 0,0,0,124,0,106,0,106,1,125,1,116,2,160,3,124, - 1,161,1,115,36,116,4,100,1,160,5,124,1,161,1,124, - 1,100,2,141,2,130,1,116,6,116,2,106,7,124,1,131, - 2,125,2,116,8,124,2,124,0,106,9,131,2,1,0,100, - 0,83,0,114,87,0,0,0,41,10,114,105,0,0,0,114, - 17,0,0,0,114,57,0,0,0,114,88,0,0,0,114,79, - 0,0,0,114,45,0,0,0,114,67,0,0,0,218,17,103, - 101,116,95,102,114,111,122,101,110,95,111,98,106,101,99,116, - 218,4,101,120,101,99,114,7,0,0,0,41,3,114,96,0, - 0,0,114,17,0,0,0,218,4,99,111,100,101,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,149,0,0, - 0,50,3,0,0,115,14,0,0,0,0,2,8,1,10,1, - 10,1,2,255,6,2,12,1,122,26,70,114,111,122,101,110, - 73,109,112,111,114,116,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,10,0,0,0,116,0, - 124,0,124,1,131,2,83,0,41,1,122,95,76,111,97,100, - 32,97,32,102,114,111,122,101,110,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,41,1,114,97,0, - 0,0,114,167,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,114,153,0,0,0,59,3,0,0,115, - 2,0,0,0,0,7,122,26,70,114,111,122,101,110,73,109, - 112,111,114,116,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,3, - 0,0,0,67,0,0,0,115,10,0,0,0,116,0,160,1, - 124,1,161,1,83,0,41,1,122,45,82,101,116,117,114,110, - 32,116,104,101,32,99,111,100,101,32,111,98,106,101,99,116, - 32,102,111,114,32,116,104,101,32,102,114,111,122,101,110,32, - 109,111,100,117,108,101,46,41,2,114,57,0,0,0,114,174, - 0,0,0,114,167,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,114,168,0,0,0,68,3,0,0, - 115,2,0,0,0,0,4,122,23,70,114,111,122,101,110,73, - 109,112,111,114,116,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,83,0,41,2, - 122,54,82,101,116,117,114,110,32,78,111,110,101,32,97,115, - 32,102,114,111,122,101,110,32,109,111,100,117,108,101,115,32, - 100,111,32,110,111,116,32,104,97,118,101,32,115,111,117,114, - 99,101,32,99,111,100,101,46,78,114,10,0,0,0,114,167, - 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, - 0,0,114,169,0,0,0,74,3,0,0,115,2,0,0,0, - 0,4,122,25,70,114,111,122,101,110,73,109,112,111,114,116, - 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,3,0,0,0,67,0, - 0,0,115,10,0,0,0,116,0,160,1,124,1,161,1,83, - 0,41,1,122,46,82,101,116,117,114,110,32,84,114,117,101, - 32,105,102,32,116,104,101,32,102,114,111,122,101,110,32,109, - 111,100,117,108,101,32,105,115,32,97,32,112,97,99,107,97, - 103,101,46,41,2,114,57,0,0,0,90,17,105,115,95,102, - 114,111,122,101,110,95,112,97,99,107,97,103,101,114,167,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,115,0,0,0,80,3,0,0,115,2,0,0,0,0, - 4,122,25,70,114,111,122,101,110,73,109,112,111,114,116,101, - 114,46,105,115,95,112,97,99,107,97,103,101,41,2,78,78, - 41,1,78,41,16,114,1,0,0,0,114,0,0,0,0,114, - 2,0,0,0,114,3,0,0,0,114,170,0,0,0,114,99, - 0,0,0,114,171,0,0,0,114,165,0,0,0,114,166,0, - 0,0,114,148,0,0,0,114,149,0,0,0,114,153,0,0, - 0,114,90,0,0,0,114,168,0,0,0,114,169,0,0,0, - 114,115,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,11,0,0,0,114,172,0,0,0,12,3, - 0,0,115,44,0,0,0,8,2,4,7,2,1,10,8,2, - 1,12,6,2,1,12,8,2,1,10,3,2,1,10,8,2, - 1,10,8,2,1,2,1,12,4,2,1,2,1,12,4,2, - 1,2,1,114,172,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,32,0, + 1,12,4,114,160,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,144,0, 0,0,101,0,90,1,100,0,90,2,100,1,90,3,100,2, - 100,3,132,0,90,4,100,4,100,5,132,0,90,5,100,6, - 83,0,41,7,218,18,95,73,109,112,111,114,116,76,111,99, - 107,67,111,110,116,101,120,116,122,36,67,111,110,116,101,120, - 116,32,109,97,110,97,103,101,114,32,102,111,114,32,116,104, - 101,32,105,109,112,111,114,116,32,108,111,99,107,46,99,1, - 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, - 0,0,0,115,12,0,0,0,116,0,160,1,161,0,1,0, - 100,1,83,0,41,2,122,24,65,99,113,117,105,114,101,32, - 116,104,101,32,105,109,112,111,114,116,32,108,111,99,107,46, - 78,41,2,114,57,0,0,0,114,58,0,0,0,114,47,0, - 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, - 0,114,54,0,0,0,93,3,0,0,115,2,0,0,0,0, - 2,122,28,95,73,109,112,111,114,116,76,111,99,107,67,111, - 110,116,101,120,116,46,95,95,101,110,116,101,114,95,95,99, - 4,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0, - 67,0,0,0,115,12,0,0,0,116,0,160,1,161,0,1, - 0,100,1,83,0,41,2,122,60,82,101,108,101,97,115,101, - 32,116,104,101,32,105,109,112,111,114,116,32,108,111,99,107, - 32,114,101,103,97,114,100,108,101,115,115,32,111,102,32,97, - 110,121,32,114,97,105,115,101,100,32,101,120,99,101,112,116, - 105,111,110,115,46,78,41,2,114,57,0,0,0,114,60,0, - 0,0,41,4,114,30,0,0,0,90,8,101,120,99,95,116, - 121,112,101,90,9,101,120,99,95,118,97,108,117,101,90,13, - 101,120,99,95,116,114,97,99,101,98,97,99,107,114,10,0, - 0,0,114,10,0,0,0,114,11,0,0,0,114,56,0,0, - 0,97,3,0,0,115,2,0,0,0,0,2,122,27,95,73, - 109,112,111,114,116,76,111,99,107,67,111,110,116,101,120,116, - 46,95,95,101,120,105,116,95,95,78,41,6,114,1,0,0, - 0,114,0,0,0,0,114,2,0,0,0,114,3,0,0,0, - 114,54,0,0,0,114,56,0,0,0,114,10,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,177, - 0,0,0,89,3,0,0,115,6,0,0,0,8,2,4,2, - 8,4,114,177,0,0,0,99,3,0,0,0,0,0,0,0, - 5,0,0,0,5,0,0,0,67,0,0,0,115,64,0,0, - 0,124,1,160,0,100,1,124,2,100,2,24,0,161,2,125, - 3,116,1,124,3,131,1,124,2,107,0,114,36,116,2,100, - 3,131,1,130,1,124,3,100,4,25,0,125,4,124,0,114, - 60,100,5,160,3,124,4,124,0,161,2,83,0,124,4,83, - 0,41,6,122,50,82,101,115,111,108,118,101,32,97,32,114, - 101,108,97,116,105,118,101,32,109,111,100,117,108,101,32,110, - 97,109,101,32,116,111,32,97,110,32,97,98,115,111,108,117, - 116,101,32,111,110,101,46,114,128,0,0,0,114,37,0,0, - 0,122,50,97,116,116,101,109,112,116,101,100,32,114,101,108, - 97,116,105,118,101,32,105,109,112,111,114,116,32,98,101,121, - 111,110,100,32,116,111,112,45,108,101,118,101,108,32,112,97, - 99,107,97,103,101,114,22,0,0,0,250,5,123,125,46,123, - 125,41,4,218,6,114,115,112,108,105,116,218,3,108,101,110, - 218,10,86,97,108,117,101,69,114,114,111,114,114,45,0,0, - 0,41,5,114,17,0,0,0,218,7,112,97,99,107,97,103, - 101,218,5,108,101,118,101,108,90,4,98,105,116,115,90,4, - 98,97,115,101,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,13,95,114,101,115,111,108,118,101,95,110,97, - 109,101,102,3,0,0,115,10,0,0,0,0,2,16,1,12, - 1,8,1,8,1,114,184,0,0,0,99,3,0,0,0,0, - 0,0,0,4,0,0,0,4,0,0,0,67,0,0,0,115, - 34,0,0,0,124,0,160,0,124,1,124,2,161,2,125,3, - 124,3,100,0,107,8,114,24,100,0,83,0,116,1,124,1, - 124,3,131,2,83,0,114,13,0,0,0,41,2,114,166,0, - 0,0,114,91,0,0,0,41,4,218,6,102,105,110,100,101, - 114,114,17,0,0,0,114,163,0,0,0,114,109,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 17,95,102,105,110,100,95,115,112,101,99,95,108,101,103,97, - 99,121,111,3,0,0,115,8,0,0,0,0,3,12,1,8, - 1,4,1,114,186,0,0,0,99,3,0,0,0,0,0,0, - 0,10,0,0,0,10,0,0,0,67,0,0,0,115,12,1, - 0,0,116,0,106,1,125,3,124,3,100,1,107,8,114,22, - 116,2,100,2,131,1,130,1,124,3,115,38,116,3,160,4, - 100,3,116,5,161,2,1,0,124,0,116,0,106,6,107,6, - 125,4,124,3,68,0,93,210,125,5,116,7,131,0,143,84, - 1,0,122,10,124,5,106,8,125,6,87,0,110,54,4,0, - 116,9,107,10,114,128,1,0,1,0,1,0,116,10,124,5, - 124,0,124,1,131,3,125,7,124,7,100,1,107,8,114,124, - 89,0,87,0,53,0,81,0,82,0,163,0,113,52,89,0, - 110,14,88,0,124,6,124,0,124,1,124,2,131,3,125,7, - 87,0,53,0,81,0,82,0,88,0,124,7,100,1,107,9, - 114,52,124,4,144,0,115,254,124,0,116,0,106,6,107,6, - 144,0,114,254,116,0,106,6,124,0,25,0,125,8,122,10, - 124,8,106,11,125,9,87,0,110,28,4,0,116,9,107,10, - 114,226,1,0,1,0,1,0,124,7,6,0,89,0,2,0, - 1,0,83,0,88,0,124,9,100,1,107,8,114,244,124,7, - 2,0,1,0,83,0,124,9,2,0,1,0,83,0,113,52, - 124,7,2,0,1,0,83,0,113,52,100,1,83,0,41,4, - 122,21,70,105,110,100,32,97,32,109,111,100,117,108,101,39, - 115,32,115,112,101,99,46,78,122,53,115,121,115,46,109,101, - 116,97,95,112,97,116,104,32,105,115,32,78,111,110,101,44, - 32,80,121,116,104,111,110,32,105,115,32,108,105,107,101,108, - 121,32,115,104,117,116,116,105,110,103,32,100,111,119,110,122, - 22,115,121,115,46,109,101,116,97,95,112,97,116,104,32,105, - 115,32,101,109,112,116,121,41,12,114,15,0,0,0,218,9, - 109,101,116,97,95,112,97,116,104,114,79,0,0,0,218,9, - 95,119,97,114,110,105,110,103,115,218,4,119,97,114,110,218, - 13,73,109,112,111,114,116,87,97,114,110,105,110,103,114,92, - 0,0,0,114,177,0,0,0,114,165,0,0,0,114,106,0, - 0,0,114,186,0,0,0,114,105,0,0,0,41,10,114,17, - 0,0,0,114,163,0,0,0,114,164,0,0,0,114,187,0, - 0,0,90,9,105,115,95,114,101,108,111,97,100,114,185,0, - 0,0,114,165,0,0,0,114,95,0,0,0,114,96,0,0, - 0,114,105,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,10,95,102,105,110,100,95,115,112,101, - 99,120,3,0,0,115,54,0,0,0,0,2,6,1,8,2, - 8,3,4,1,12,5,10,1,8,1,8,1,2,1,10,1, - 14,1,12,1,8,1,20,2,22,1,8,2,18,1,10,1, - 2,1,10,1,14,4,14,2,8,1,8,2,10,2,10,2, - 114,191,0,0,0,99,3,0,0,0,0,0,0,0,3,0, - 0,0,5,0,0,0,67,0,0,0,115,108,0,0,0,116, - 0,124,0,116,1,131,2,115,28,116,2,100,1,160,3,116, - 4,124,0,131,1,161,1,131,1,130,1,124,2,100,2,107, - 0,114,44,116,5,100,3,131,1,130,1,124,2,100,2,107, - 4,114,84,116,0,124,1,116,1,131,2,115,72,116,2,100, - 4,131,1,130,1,110,12,124,1,115,84,116,6,100,5,131, - 1,130,1,124,0,115,104,124,2,100,2,107,2,114,104,116, - 5,100,6,131,1,130,1,100,7,83,0,41,8,122,28,86, - 101,114,105,102,121,32,97,114,103,117,109,101,110,116,115,32, - 97,114,101,32,34,115,97,110,101,34,46,122,31,109,111,100, - 117,108,101,32,110,97,109,101,32,109,117,115,116,32,98,101, - 32,115,116,114,44,32,110,111,116,32,123,125,114,22,0,0, - 0,122,18,108,101,118,101,108,32,109,117,115,116,32,98,101, - 32,62,61,32,48,122,31,95,95,112,97,99,107,97,103,101, - 95,95,32,110,111,116,32,115,101,116,32,116,111,32,97,32, - 115,116,114,105,110,103,122,54,97,116,116,101,109,112,116,101, - 100,32,114,101,108,97,116,105,118,101,32,105,109,112,111,114, - 116,32,119,105,116,104,32,110,111,32,107,110,111,119,110,32, - 112,97,114,101,110,116,32,112,97,99,107,97,103,101,122,17, - 69,109,112,116,121,32,109,111,100,117,108,101,32,110,97,109, - 101,78,41,7,218,10,105,115,105,110,115,116,97,110,99,101, - 218,3,115,116,114,218,9,84,121,112,101,69,114,114,111,114, - 114,45,0,0,0,114,14,0,0,0,114,181,0,0,0,114, - 79,0,0,0,169,3,114,17,0,0,0,114,182,0,0,0, - 114,183,0,0,0,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,13,95,115,97,110,105,116,121,95,99,104, - 101,99,107,167,3,0,0,115,22,0,0,0,0,2,10,1, - 18,1,8,1,8,1,8,1,10,1,10,1,4,1,8,2, - 12,1,114,196,0,0,0,122,16,78,111,32,109,111,100,117, - 108,101,32,110,97,109,101,100,32,122,4,123,33,114,125,99, - 2,0,0,0,0,0,0,0,8,0,0,0,8,0,0,0, - 67,0,0,0,115,220,0,0,0,100,0,125,2,124,0,160, - 0,100,1,161,1,100,2,25,0,125,3,124,3,114,134,124, - 3,116,1,106,2,107,7,114,42,116,3,124,1,124,3,131, - 2,1,0,124,0,116,1,106,2,107,6,114,62,116,1,106, - 2,124,0,25,0,83,0,116,1,106,2,124,3,25,0,125, - 4,122,10,124,4,106,4,125,2,87,0,110,50,4,0,116, - 5,107,10,114,132,1,0,1,0,1,0,116,6,100,3,23, - 0,160,7,124,0,124,3,161,2,125,5,116,8,124,5,124, - 0,100,4,141,2,100,0,130,2,89,0,110,2,88,0,116, - 9,124,0,124,2,131,2,125,6,124,6,100,0,107,8,114, - 172,116,8,116,6,160,7,124,0,161,1,124,0,100,4,141, - 2,130,1,110,8,116,10,124,6,131,1,125,7,124,3,114, - 216,116,1,106,2,124,3,25,0,125,4,116,11,124,4,124, - 0,160,0,100,1,161,1,100,5,25,0,124,7,131,3,1, - 0,124,7,83,0,41,6,78,114,128,0,0,0,114,22,0, - 0,0,122,23,59,32,123,33,114,125,32,105,115,32,110,111, - 116,32,97,32,112,97,99,107,97,103,101,114,16,0,0,0, - 233,2,0,0,0,41,12,114,129,0,0,0,114,15,0,0, - 0,114,92,0,0,0,114,67,0,0,0,114,140,0,0,0, - 114,106,0,0,0,218,8,95,69,82,82,95,77,83,71,114, - 45,0,0,0,218,19,77,111,100,117,108,101,78,111,116,70, - 111,117,110,100,69,114,114,111,114,114,191,0,0,0,114,157, - 0,0,0,114,5,0,0,0,41,8,114,17,0,0,0,218, - 7,105,109,112,111,114,116,95,114,163,0,0,0,114,130,0, - 0,0,90,13,112,97,114,101,110,116,95,109,111,100,117,108, - 101,114,155,0,0,0,114,95,0,0,0,114,96,0,0,0, - 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,218, - 23,95,102,105,110,100,95,97,110,100,95,108,111,97,100,95, - 117,110,108,111,99,107,101,100,186,3,0,0,115,42,0,0, - 0,0,1,4,1,14,1,4,1,10,1,10,2,10,1,10, - 1,10,1,2,1,10,1,14,1,16,1,20,1,10,1,8, - 1,20,2,8,1,4,2,10,1,22,1,114,201,0,0,0, - 99,2,0,0,0,0,0,0,0,4,0,0,0,10,0,0, - 0,67,0,0,0,115,106,0,0,0,116,0,124,0,131,1, - 143,50,1,0,116,1,106,2,160,3,124,0,116,4,161,2, - 125,2,124,2,116,4,107,8,114,54,116,5,124,0,124,1, - 131,2,87,0,2,0,53,0,81,0,82,0,163,0,83,0, - 87,0,53,0,81,0,82,0,88,0,124,2,100,1,107,8, - 114,94,100,2,160,6,124,0,161,1,125,3,116,7,124,3, - 124,0,100,3,141,2,130,1,116,8,124,0,131,1,1,0, - 124,2,83,0,41,4,122,25,70,105,110,100,32,97,110,100, - 32,108,111,97,100,32,116,104,101,32,109,111,100,117,108,101, - 46,78,122,40,105,109,112,111,114,116,32,111,102,32,123,125, - 32,104,97,108,116,101,100,59,32,78,111,110,101,32,105,110, - 32,115,121,115,46,109,111,100,117,108,101,115,114,16,0,0, - 0,41,9,114,50,0,0,0,114,15,0,0,0,114,92,0, - 0,0,114,34,0,0,0,218,14,95,78,69,69,68,83,95, - 76,79,65,68,73,78,71,114,201,0,0,0,114,45,0,0, - 0,114,199,0,0,0,114,65,0,0,0,41,4,114,17,0, - 0,0,114,200,0,0,0,114,96,0,0,0,114,75,0,0, - 0,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, - 218,14,95,102,105,110,100,95,97,110,100,95,108,111,97,100, - 216,3,0,0,115,22,0,0,0,0,2,10,1,14,1,8, - 1,32,2,8,1,4,1,2,255,4,2,12,2,8,1,114, - 203,0,0,0,114,22,0,0,0,99,3,0,0,0,0,0, - 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,42, - 0,0,0,116,0,124,0,124,1,124,2,131,3,1,0,124, - 2,100,1,107,4,114,32,116,1,124,0,124,1,124,2,131, - 3,125,0,116,2,124,0,116,3,131,2,83,0,41,2,97, - 50,1,0,0,73,109,112,111,114,116,32,97,110,100,32,114, - 101,116,117,114,110,32,116,104,101,32,109,111,100,117,108,101, - 32,98,97,115,101,100,32,111,110,32,105,116,115,32,110,97, - 109,101,44,32,116,104,101,32,112,97,99,107,97,103,101,32, - 116,104,101,32,99,97,108,108,32,105,115,10,32,32,32,32, - 98,101,105,110,103,32,109,97,100,101,32,102,114,111,109,44, - 32,97,110,100,32,116,104,101,32,108,101,118,101,108,32,97, - 100,106,117,115,116,109,101,110,116,46,10,10,32,32,32,32, - 84,104,105,115,32,102,117,110,99,116,105,111,110,32,114,101, - 112,114,101,115,101,110,116,115,32,116,104,101,32,103,114,101, - 97,116,101,115,116,32,99,111,109,109,111,110,32,100,101,110, - 111,109,105,110,97,116,111,114,32,111,102,32,102,117,110,99, - 116,105,111,110,97,108,105,116,121,10,32,32,32,32,98,101, - 116,119,101,101,110,32,105,109,112,111,114,116,95,109,111,100, - 117,108,101,32,97,110,100,32,95,95,105,109,112,111,114,116, - 95,95,46,32,84,104,105,115,32,105,110,99,108,117,100,101, - 115,32,115,101,116,116,105,110,103,32,95,95,112,97,99,107, - 97,103,101,95,95,32,105,102,10,32,32,32,32,116,104,101, - 32,108,111,97,100,101,114,32,100,105,100,32,110,111,116,46, - 10,10,32,32,32,32,114,22,0,0,0,41,4,114,196,0, - 0,0,114,184,0,0,0,114,203,0,0,0,218,11,95,103, - 99,100,95,105,109,112,111,114,116,114,195,0,0,0,114,10, - 0,0,0,114,10,0,0,0,114,11,0,0,0,114,204,0, - 0,0,232,3,0,0,115,8,0,0,0,0,9,12,1,8, - 1,12,1,114,204,0,0,0,169,1,218,9,114,101,99,117, - 114,115,105,118,101,99,3,0,0,0,1,0,0,0,8,0, - 0,0,11,0,0,0,67,0,0,0,115,226,0,0,0,124, - 1,68,0,93,216,125,4,116,0,124,4,116,1,131,2,115, - 66,124,3,114,34,124,0,106,2,100,1,23,0,125,5,110, - 4,100,2,125,5,116,3,100,3,124,5,155,0,100,4,116, - 4,124,4,131,1,106,2,155,0,157,4,131,1,130,1,110, - 154,124,4,100,5,107,2,114,108,124,3,115,106,116,5,124, - 0,100,6,131,2,114,106,116,6,124,0,124,0,106,7,124, - 2,100,7,100,8,141,4,1,0,110,112,116,5,124,0,124, - 4,131,2,115,220,100,9,160,8,124,0,106,2,124,4,161, - 2,125,6,122,14,116,9,124,2,124,6,131,2,1,0,87, - 0,110,72,4,0,116,10,107,10,114,218,1,0,125,7,1, - 0,122,42,124,7,106,11,124,6,107,2,114,200,116,12,106, - 13,160,14,124,6,116,15,161,2,100,10,107,9,114,200,87, - 0,89,0,162,8,113,4,130,0,87,0,53,0,100,10,125, - 7,126,7,88,0,89,0,110,2,88,0,113,4,124,0,83, - 0,41,11,122,238,70,105,103,117,114,101,32,111,117,116,32, - 119,104,97,116,32,95,95,105,109,112,111,114,116,95,95,32, - 115,104,111,117,108,100,32,114,101,116,117,114,110,46,10,10, - 32,32,32,32,84,104,101,32,105,109,112,111,114,116,95,32, - 112,97,114,97,109,101,116,101,114,32,105,115,32,97,32,99, - 97,108,108,97,98,108,101,32,119,104,105,99,104,32,116,97, - 107,101,115,32,116,104,101,32,110,97,109,101,32,111,102,32, - 109,111,100,117,108,101,32,116,111,10,32,32,32,32,105,109, - 112,111,114,116,46,32,73,116,32,105,115,32,114,101,113,117, - 105,114,101,100,32,116,111,32,100,101,99,111,117,112,108,101, - 32,116,104,101,32,102,117,110,99,116,105,111,110,32,102,114, - 111,109,32,97,115,115,117,109,105,110,103,32,105,109,112,111, - 114,116,108,105,98,39,115,10,32,32,32,32,105,109,112,111, - 114,116,32,105,109,112,108,101,109,101,110,116,97,116,105,111, - 110,32,105,115,32,100,101,115,105,114,101,100,46,10,10,32, - 32,32,32,122,8,46,95,95,97,108,108,95,95,122,13,96, - 96,102,114,111,109,32,108,105,115,116,39,39,122,8,73,116, - 101,109,32,105,110,32,122,18,32,109,117,115,116,32,98,101, - 32,115,116,114,44,32,110,111,116,32,250,1,42,218,7,95, - 95,97,108,108,95,95,84,114,205,0,0,0,114,178,0,0, - 0,78,41,16,114,192,0,0,0,114,193,0,0,0,114,1, - 0,0,0,114,194,0,0,0,114,14,0,0,0,114,4,0, - 0,0,218,16,95,104,97,110,100,108,101,95,102,114,111,109, - 108,105,115,116,114,208,0,0,0,114,45,0,0,0,114,67, - 0,0,0,114,199,0,0,0,114,17,0,0,0,114,15,0, - 0,0,114,92,0,0,0,114,34,0,0,0,114,202,0,0, - 0,41,8,114,96,0,0,0,218,8,102,114,111,109,108,105, - 115,116,114,200,0,0,0,114,206,0,0,0,218,1,120,90, - 5,119,104,101,114,101,90,9,102,114,111,109,95,110,97,109, - 101,90,3,101,120,99,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,114,209,0,0,0,247,3,0,0,115,44, - 0,0,0,0,10,8,1,10,1,4,1,12,2,4,1,28, - 2,8,1,14,1,10,1,2,255,8,2,10,1,14,1,2, - 1,14,1,16,4,10,1,16,255,2,2,8,1,22,1,114, - 209,0,0,0,99,1,0,0,0,0,0,0,0,3,0,0, - 0,6,0,0,0,67,0,0,0,115,146,0,0,0,124,0, - 160,0,100,1,161,1,125,1,124,0,160,0,100,2,161,1, - 125,2,124,1,100,3,107,9,114,82,124,2,100,3,107,9, - 114,78,124,1,124,2,106,1,107,3,114,78,116,2,106,3, - 100,4,124,1,155,2,100,5,124,2,106,1,155,2,100,6, - 157,5,116,4,100,7,100,8,141,3,1,0,124,1,83,0, - 124,2,100,3,107,9,114,96,124,2,106,1,83,0,116,2, - 106,3,100,9,116,4,100,7,100,8,141,3,1,0,124,0, - 100,10,25,0,125,1,100,11,124,0,107,7,114,142,124,1, - 160,5,100,12,161,1,100,13,25,0,125,1,124,1,83,0, - 41,14,122,167,67,97,108,99,117,108,97,116,101,32,119,104, - 97,116,32,95,95,112,97,99,107,97,103,101,95,95,32,115, - 104,111,117,108,100,32,98,101,46,10,10,32,32,32,32,95, - 95,112,97,99,107,97,103,101,95,95,32,105,115,32,110,111, - 116,32,103,117,97,114,97,110,116,101,101,100,32,116,111,32, - 98,101,32,100,101,102,105,110,101,100,32,111,114,32,99,111, - 117,108,100,32,98,101,32,115,101,116,32,116,111,32,78,111, - 110,101,10,32,32,32,32,116,111,32,114,101,112,114,101,115, - 101,110,116,32,116,104,97,116,32,105,116,115,32,112,114,111, - 112,101,114,32,118,97,108,117,101,32,105,115,32,117,110,107, - 110,111,119,110,46,10,10,32,32,32,32,114,144,0,0,0, - 114,105,0,0,0,78,122,32,95,95,112,97,99,107,97,103, - 101,95,95,32,33,61,32,95,95,115,112,101,99,95,95,46, - 112,97,114,101,110,116,32,40,122,4,32,33,61,32,250,1, - 41,233,3,0,0,0,41,1,90,10,115,116,97,99,107,108, - 101,118,101,108,122,89,99,97,110,39,116,32,114,101,115,111, - 108,118,101,32,112,97,99,107,97,103,101,32,102,114,111,109, - 32,95,95,115,112,101,99,95,95,32,111,114,32,95,95,112, - 97,99,107,97,103,101,95,95,44,32,102,97,108,108,105,110, - 103,32,98,97,99,107,32,111,110,32,95,95,110,97,109,101, - 95,95,32,97,110,100,32,95,95,112,97,116,104,95,95,114, - 1,0,0,0,114,140,0,0,0,114,128,0,0,0,114,22, - 0,0,0,41,6,114,34,0,0,0,114,130,0,0,0,114, - 188,0,0,0,114,189,0,0,0,114,190,0,0,0,114,129, - 0,0,0,41,3,218,7,103,108,111,98,97,108,115,114,182, - 0,0,0,114,95,0,0,0,114,10,0,0,0,114,10,0, - 0,0,114,11,0,0,0,218,17,95,99,97,108,99,95,95, - 95,112,97,99,107,97,103,101,95,95,28,4,0,0,115,38, - 0,0,0,0,7,10,1,10,1,8,1,18,1,22,2,2, - 0,2,254,6,3,4,1,8,1,6,2,6,2,2,0,2, - 254,6,3,8,1,8,1,14,1,114,215,0,0,0,114,10, - 0,0,0,99,5,0,0,0,0,0,0,0,9,0,0,0, - 5,0,0,0,67,0,0,0,115,180,0,0,0,124,4,100, - 1,107,2,114,18,116,0,124,0,131,1,125,5,110,36,124, - 1,100,2,107,9,114,30,124,1,110,2,105,0,125,6,116, - 1,124,6,131,1,125,7,116,0,124,0,124,7,124,4,131, - 3,125,5,124,3,115,150,124,4,100,1,107,2,114,84,116, - 0,124,0,160,2,100,3,161,1,100,1,25,0,131,1,83, - 0,124,0,115,92,124,5,83,0,116,3,124,0,131,1,116, - 3,124,0,160,2,100,3,161,1,100,1,25,0,131,1,24, - 0,125,8,116,4,106,5,124,5,106,6,100,2,116,3,124, - 5,106,6,131,1,124,8,24,0,133,2,25,0,25,0,83, - 0,110,26,116,7,124,5,100,4,131,2,114,172,116,8,124, - 5,124,3,116,0,131,3,83,0,124,5,83,0,100,2,83, - 0,41,5,97,215,1,0,0,73,109,112,111,114,116,32,97, - 32,109,111,100,117,108,101,46,10,10,32,32,32,32,84,104, - 101,32,39,103,108,111,98,97,108,115,39,32,97,114,103,117, - 109,101,110,116,32,105,115,32,117,115,101,100,32,116,111,32, - 105,110,102,101,114,32,119,104,101,114,101,32,116,104,101,32, - 105,109,112,111,114,116,32,105,115,32,111,99,99,117,114,114, - 105,110,103,32,102,114,111,109,10,32,32,32,32,116,111,32, - 104,97,110,100,108,101,32,114,101,108,97,116,105,118,101,32, - 105,109,112,111,114,116,115,46,32,84,104,101,32,39,108,111, - 99,97,108,115,39,32,97,114,103,117,109,101,110,116,32,105, - 115,32,105,103,110,111,114,101,100,46,32,84,104,101,10,32, - 32,32,32,39,102,114,111,109,108,105,115,116,39,32,97,114, - 103,117,109,101,110,116,32,115,112,101,99,105,102,105,101,115, - 32,119,104,97,116,32,115,104,111,117,108,100,32,101,120,105, - 115,116,32,97,115,32,97,116,116,114,105,98,117,116,101,115, - 32,111,110,32,116,104,101,32,109,111,100,117,108,101,10,32, - 32,32,32,98,101,105,110,103,32,105,109,112,111,114,116,101, - 100,32,40,101,46,103,46,32,96,96,102,114,111,109,32,109, - 111,100,117,108,101,32,105,109,112,111,114,116,32,60,102,114, - 111,109,108,105,115,116,62,96,96,41,46,32,32,84,104,101, - 32,39,108,101,118,101,108,39,10,32,32,32,32,97,114,103, - 117,109,101,110,116,32,114,101,112,114,101,115,101,110,116,115, - 32,116,104,101,32,112,97,99,107,97,103,101,32,108,111,99, - 97,116,105,111,110,32,116,111,32,105,109,112,111,114,116,32, - 102,114,111,109,32,105,110,32,97,32,114,101,108,97,116,105, - 118,101,10,32,32,32,32,105,109,112,111,114,116,32,40,101, - 46,103,46,32,96,96,102,114,111,109,32,46,46,112,107,103, - 32,105,109,112,111,114,116,32,109,111,100,96,96,32,119,111, - 117,108,100,32,104,97,118,101,32,97,32,39,108,101,118,101, - 108,39,32,111,102,32,50,41,46,10,10,32,32,32,32,114, - 22,0,0,0,78,114,128,0,0,0,114,140,0,0,0,41, - 9,114,204,0,0,0,114,215,0,0,0,218,9,112,97,114, - 116,105,116,105,111,110,114,180,0,0,0,114,15,0,0,0, - 114,92,0,0,0,114,1,0,0,0,114,4,0,0,0,114, - 209,0,0,0,41,9,114,17,0,0,0,114,214,0,0,0, - 218,6,108,111,99,97,108,115,114,210,0,0,0,114,183,0, - 0,0,114,96,0,0,0,90,8,103,108,111,98,97,108,115, - 95,114,182,0,0,0,90,7,99,117,116,95,111,102,102,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,10, - 95,95,105,109,112,111,114,116,95,95,55,4,0,0,115,30, - 0,0,0,0,11,8,1,10,2,16,1,8,1,12,1,4, - 3,8,1,18,1,4,1,4,4,26,3,32,1,10,1,12, - 2,114,218,0,0,0,99,1,0,0,0,0,0,0,0,2, - 0,0,0,3,0,0,0,67,0,0,0,115,38,0,0,0, - 116,0,160,1,124,0,161,1,125,1,124,1,100,0,107,8, - 114,30,116,2,100,1,124,0,23,0,131,1,130,1,116,3, - 124,1,131,1,83,0,41,2,78,122,25,110,111,32,98,117, - 105,108,116,45,105,110,32,109,111,100,117,108,101,32,110,97, - 109,101,100,32,41,4,114,158,0,0,0,114,165,0,0,0, - 114,79,0,0,0,114,157,0,0,0,41,2,114,17,0,0, - 0,114,95,0,0,0,114,10,0,0,0,114,10,0,0,0, - 114,11,0,0,0,218,18,95,98,117,105,108,116,105,110,95, - 102,114,111,109,95,110,97,109,101,92,4,0,0,115,8,0, - 0,0,0,1,10,1,8,1,12,1,114,219,0,0,0,99, - 2,0,0,0,0,0,0,0,10,0,0,0,5,0,0,0, - 67,0,0,0,115,166,0,0,0,124,1,97,0,124,0,97, - 1,116,2,116,1,131,1,125,2,116,1,106,3,160,4,161, - 0,68,0,93,72,92,2,125,3,125,4,116,5,124,4,124, - 2,131,2,114,26,124,3,116,1,106,6,107,6,114,60,116, - 7,125,5,110,18,116,0,160,8,124,3,161,1,114,26,116, - 9,125,5,110,2,113,26,116,10,124,4,124,5,131,2,125, - 6,116,11,124,6,124,4,131,2,1,0,113,26,116,1,106, - 3,116,12,25,0,125,7,100,1,68,0,93,46,125,8,124, - 8,116,1,106,3,107,7,114,138,116,13,124,8,131,1,125, - 9,110,10,116,1,106,3,124,8,25,0,125,9,116,14,124, - 7,124,8,124,9,131,3,1,0,113,114,100,2,83,0,41, - 3,122,250,83,101,116,117,112,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,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,10,32,32,32,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,65, - 115,32,115,121,115,32,105,115,32,110,101,101,100,101,100,32, - 102,111,114,32,115,121,115,46,109,111,100,117,108,101,115,32, - 97,99,99,101,115,115,32,97,110,100,32,95,105,109,112,32, - 105,115,32,110,101,101,100,101,100,32,116,111,32,108,111,97, - 100,32,98,117,105,108,116,45,105,110,10,32,32,32,32,109, - 111,100,117,108,101,115,44,32,116,104,111,115,101,32,116,119, - 111,32,109,111,100,117,108,101,115,32,109,117,115,116,32,98, - 101,32,101,120,112,108,105,99,105,116,108,121,32,112,97,115, - 115,101,100,32,105,110,46,10,10,32,32,32,32,41,3,114, - 23,0,0,0,114,188,0,0,0,114,64,0,0,0,78,41, - 15,114,57,0,0,0,114,15,0,0,0,114,14,0,0,0, - 114,92,0,0,0,218,5,105,116,101,109,115,114,192,0,0, - 0,114,78,0,0,0,114,158,0,0,0,114,88,0,0,0, - 114,172,0,0,0,114,141,0,0,0,114,147,0,0,0,114, - 1,0,0,0,114,219,0,0,0,114,5,0,0,0,41,10, - 218,10,115,121,115,95,109,111,100,117,108,101,218,11,95,105, - 109,112,95,109,111,100,117,108,101,90,11,109,111,100,117,108, - 101,95,116,121,112,101,114,17,0,0,0,114,96,0,0,0, - 114,109,0,0,0,114,95,0,0,0,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,114,10,0,0,0,114,10,0,0,0,114, - 11,0,0,0,218,6,95,115,101,116,117,112,99,4,0,0, - 115,36,0,0,0,0,9,4,1,4,3,8,1,18,1,10, - 1,10,1,6,1,10,1,6,2,2,1,10,1,12,3,10, - 1,8,1,10,1,10,2,10,1,114,223,0,0,0,99,2, - 0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,67, - 0,0,0,115,38,0,0,0,116,0,124,0,124,1,131,2, - 1,0,116,1,106,2,160,3,116,4,161,1,1,0,116,1, - 106,2,160,3,116,5,161,1,1,0,100,1,83,0,41,2, - 122,48,73,110,115,116,97,108,108,32,105,109,112,111,114,116, - 101,114,115,32,102,111,114,32,98,117,105,108,116,105,110,32, - 97,110,100,32,102,114,111,122,101,110,32,109,111,100,117,108, - 101,115,78,41,6,114,223,0,0,0,114,15,0,0,0,114, - 187,0,0,0,114,120,0,0,0,114,158,0,0,0,114,172, - 0,0,0,41,2,114,221,0,0,0,114,222,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,11,0,0,0,218,8, - 95,105,110,115,116,97,108,108,134,4,0,0,115,6,0,0, - 0,0,2,10,2,12,1,114,224,0,0,0,99,0,0,0, + 90,4,101,5,100,3,100,4,132,0,131,1,90,6,101,7, + 100,22,100,6,100,7,132,1,131,1,90,8,101,7,100,23, + 100,8,100,9,132,1,131,1,90,9,101,7,100,10,100,11, + 132,0,131,1,90,10,101,5,100,12,100,13,132,0,131,1, + 90,11,101,7,100,14,100,15,132,0,131,1,90,12,101,7, + 101,13,100,16,100,17,132,0,131,1,131,1,90,14,101,7, + 101,13,100,18,100,19,132,0,131,1,131,1,90,15,101,7, + 101,13,100,20,100,21,132,0,131,1,131,1,90,16,100,5, + 83,0,41,24,218,14,70,114,111,122,101,110,73,109,112,111, + 114,116,101,114,122,142,77,101,116,97,32,112,97,116,104,32, + 105,109,112,111,114,116,32,102,111,114,32,102,114,111,122,101, + 110,32,109,111,100,117,108,101,115,46,10,10,32,32,32,32, + 65,108,108,32,109,101,116,104,111,100,115,32,97,114,101,32, + 101,105,116,104,101,114,32,99,108,97,115,115,32,111,114,32, + 115,116,97,116,105,99,32,109,101,116,104,111,100,115,32,116, + 111,32,97,118,111,105,100,32,116,104,101,32,110,101,101,100, + 32,116,111,10,32,32,32,32,105,110,115,116,97,110,116,105, + 97,116,101,32,116,104,101,32,99,108,97,115,115,46,10,10, + 32,32,32,32,90,6,102,114,111,122,101,110,99,1,0,0, 0,0,0,0,0,1,0,0,0,4,0,0,0,67,0,0, - 0,115,32,0,0,0,100,1,100,2,108,0,125,0,124,0, - 97,1,124,0,160,2,116,3,106,4,116,5,25,0,161,1, - 1,0,100,2,83,0,41,3,122,57,73,110,115,116,97,108, - 108,32,105,109,112,111,114,116,101,114,115,32,116,104,97,116, - 32,114,101,113,117,105,114,101,32,101,120,116,101,114,110,97, - 108,32,102,105,108,101,115,121,115,116,101,109,32,97,99,99, - 101,115,115,114,22,0,0,0,78,41,6,218,26,95,102,114, - 111,122,101,110,95,105,109,112,111,114,116,108,105,98,95,101, - 120,116,101,114,110,97,108,114,126,0,0,0,114,224,0,0, - 0,114,15,0,0,0,114,92,0,0,0,114,1,0,0,0, - 41,1,114,225,0,0,0,114,10,0,0,0,114,10,0,0, - 0,114,11,0,0,0,218,27,95,105,110,115,116,97,108,108, - 95,101,120,116,101,114,110,97,108,95,105,109,112,111,114,116, - 101,114,115,142,4,0,0,115,6,0,0,0,0,3,8,1, - 4,1,114,226,0,0,0,41,2,78,78,41,1,78,41,2, - 78,114,22,0,0,0,41,4,78,78,114,10,0,0,0,114, - 22,0,0,0,41,50,114,3,0,0,0,114,126,0,0,0, - 114,12,0,0,0,114,18,0,0,0,114,59,0,0,0,114, - 33,0,0,0,114,42,0,0,0,114,19,0,0,0,114,20, - 0,0,0,114,49,0,0,0,114,50,0,0,0,114,53,0, - 0,0,114,65,0,0,0,114,67,0,0,0,114,76,0,0, - 0,114,86,0,0,0,114,90,0,0,0,114,97,0,0,0, - 114,111,0,0,0,114,112,0,0,0,114,91,0,0,0,114, - 141,0,0,0,114,147,0,0,0,114,151,0,0,0,114,107, - 0,0,0,114,93,0,0,0,114,156,0,0,0,114,157,0, - 0,0,114,94,0,0,0,114,158,0,0,0,114,172,0,0, - 0,114,177,0,0,0,114,184,0,0,0,114,186,0,0,0, - 114,191,0,0,0,114,196,0,0,0,90,15,95,69,82,82, - 95,77,83,71,95,80,82,69,70,73,88,114,198,0,0,0, - 114,201,0,0,0,218,6,111,98,106,101,99,116,114,202,0, - 0,0,114,203,0,0,0,114,204,0,0,0,114,209,0,0, - 0,114,215,0,0,0,114,218,0,0,0,114,219,0,0,0, - 114,223,0,0,0,114,224,0,0,0,114,226,0,0,0,114, - 10,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, - 0,0,0,218,8,60,109,111,100,117,108,101,62,1,0,0, - 0,115,94,0,0,0,4,24,4,2,8,8,8,8,4,2, - 4,3,16,4,14,68,14,21,14,16,8,37,8,17,8,11, - 14,8,8,11,8,12,8,16,8,36,14,101,16,26,10,45, - 14,72,8,17,8,17,8,30,8,37,8,42,8,15,14,73, - 14,77,14,13,8,9,8,9,10,47,8,16,4,1,8,2, - 8,27,6,3,8,16,10,15,14,37,8,27,10,37,8,7, - 8,35,8,8, + 0,115,16,0,0,0,100,1,160,0,124,0,106,1,116,2, + 106,3,161,2,83,0,41,2,114,161,0,0,0,114,153,0, + 0,0,41,4,114,45,0,0,0,114,1,0,0,0,114,173, + 0,0,0,114,138,0,0,0,41,1,218,1,109,114,10,0, + 0,0,114,10,0,0,0,114,11,0,0,0,114,99,0,0, + 0,23,3,0,0,115,2,0,0,0,0,7,122,26,70,114, + 111,122,101,110,73,109,112,111,114,116,101,114,46,109,111,100, + 117,108,101,95,114,101,112,114,78,99,4,0,0,0,0,0, + 0,0,4,0,0,0,5,0,0,0,67,0,0,0,115,34, + 0,0,0,116,0,160,1,124,1,161,1,114,26,116,2,124, + 1,124,0,124,0,106,3,100,1,141,3,83,0,100,0,83, + 0,100,0,83,0,41,2,78,114,137,0,0,0,41,4,114, + 57,0,0,0,114,88,0,0,0,114,91,0,0,0,114,138, + 0,0,0,114,162,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,114,166,0,0,0,32,3,0,0, + 115,6,0,0,0,0,2,10,1,16,2,122,24,70,114,111, + 122,101,110,73,109,112,111,114,116,101,114,46,102,105,110,100, + 95,115,112,101,99,99,3,0,0,0,0,0,0,0,3,0, + 0,0,3,0,0,0,67,0,0,0,115,18,0,0,0,116, + 0,160,1,124,1,161,1,114,14,124,0,83,0,100,1,83, + 0,41,2,122,93,70,105,110,100,32,97,32,102,114,111,122, + 101,110,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,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,57,0,0,0,114,88,0,0,0,41, + 3,114,163,0,0,0,114,81,0,0,0,114,164,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 167,0,0,0,39,3,0,0,115,2,0,0,0,0,7,122, + 26,70,114,111,122,101,110,73,109,112,111,114,116,101,114,46, + 102,105,110,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,4,0,0,0,100,1,83,0,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,10,0,0,0,41,2,114, + 163,0,0,0,114,95,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,114,149,0,0,0,48,3,0, + 0,115,2,0,0,0,0,2,122,28,70,114,111,122,101,110, + 73,109,112,111,114,116,101,114,46,99,114,101,97,116,101,95, + 109,111,100,117,108,101,99,1,0,0,0,0,0,0,0,3, + 0,0,0,4,0,0,0,67,0,0,0,115,64,0,0,0, + 124,0,106,0,106,1,125,1,116,2,160,3,124,1,161,1, + 115,36,116,4,100,1,160,5,124,1,161,1,124,1,100,2, + 141,2,130,1,116,6,116,2,106,7,124,1,131,2,125,2, + 116,8,124,2,124,0,106,9,131,2,1,0,100,0,83,0, + 114,87,0,0,0,41,10,114,105,0,0,0,114,17,0,0, + 0,114,57,0,0,0,114,88,0,0,0,114,79,0,0,0, + 114,45,0,0,0,114,67,0,0,0,218,17,103,101,116,95, + 102,114,111,122,101,110,95,111,98,106,101,99,116,218,4,101, + 120,101,99,114,7,0,0,0,41,3,114,96,0,0,0,114, + 17,0,0,0,218,4,99,111,100,101,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,150,0,0,0,52,3, + 0,0,115,14,0,0,0,0,2,8,1,10,1,10,1,2, + 255,6,2,12,1,122,26,70,114,111,122,101,110,73,109,112, + 111,114,116,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,10,0,0,0,116,0,124,0,124, + 1,131,2,83,0,41,1,122,95,76,111,97,100,32,97,32, + 102,114,111,122,101,110,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,41,1,114,97,0,0,0,114, + 168,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,114,155,0,0,0,61,3,0,0,115,2,0,0, + 0,0,7,122,26,70,114,111,122,101,110,73,109,112,111,114, + 116,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,3,0,0,0, + 67,0,0,0,115,10,0,0,0,116,0,160,1,124,1,161, + 1,83,0,41,1,122,45,82,101,116,117,114,110,32,116,104, + 101,32,99,111,100,101,32,111,98,106,101,99,116,32,102,111, + 114,32,116,104,101,32,102,114,111,122,101,110,32,109,111,100, + 117,108,101,46,41,2,114,57,0,0,0,114,175,0,0,0, + 114,168,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,114,169,0,0,0,70,3,0,0,115,2,0, + 0,0,0,4,122,23,70,114,111,122,101,110,73,109,112,111, + 114,116,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,83,0,41,2,122,54,82, + 101,116,117,114,110,32,78,111,110,101,32,97,115,32,102,114, + 111,122,101,110,32,109,111,100,117,108,101,115,32,100,111,32, + 110,111,116,32,104,97,118,101,32,115,111,117,114,99,101,32, + 99,111,100,101,46,78,114,10,0,0,0,114,168,0,0,0, + 114,10,0,0,0,114,10,0,0,0,114,11,0,0,0,114, + 170,0,0,0,76,3,0,0,115,2,0,0,0,0,4,122, + 25,70,114,111,122,101,110,73,109,112,111,114,116,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,3,0,0,0,67,0,0,0,115, + 10,0,0,0,116,0,160,1,124,1,161,1,83,0,41,1, + 122,46,82,101,116,117,114,110,32,84,114,117,101,32,105,102, + 32,116,104,101,32,102,114,111,122,101,110,32,109,111,100,117, + 108,101,32,105,115,32,97,32,112,97,99,107,97,103,101,46, + 41,2,114,57,0,0,0,90,17,105,115,95,102,114,111,122, + 101,110,95,112,97,99,107,97,103,101,114,168,0,0,0,114, + 10,0,0,0,114,10,0,0,0,114,11,0,0,0,114,115, + 0,0,0,82,3,0,0,115,2,0,0,0,0,4,122,25, + 70,114,111,122,101,110,73,109,112,111,114,116,101,114,46,105, + 115,95,112,97,99,107,97,103,101,41,2,78,78,41,1,78, + 41,17,114,1,0,0,0,114,0,0,0,0,114,2,0,0, + 0,114,3,0,0,0,114,138,0,0,0,114,171,0,0,0, + 114,99,0,0,0,114,172,0,0,0,114,166,0,0,0,114, + 167,0,0,0,114,149,0,0,0,114,150,0,0,0,114,155, + 0,0,0,114,90,0,0,0,114,169,0,0,0,114,170,0, + 0,0,114,115,0,0,0,114,10,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,114,173,0,0,0, + 12,3,0,0,115,46,0,0,0,8,2,4,7,4,2,2, + 1,10,8,2,1,12,6,2,1,12,8,2,1,10,3,2, + 1,10,8,2,1,10,8,2,1,2,1,12,4,2,1,2, + 1,12,4,2,1,2,1,114,173,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,32,0,0,0,101,0,90,1,100,0,90,2,100,1, + 90,3,100,2,100,3,132,0,90,4,100,4,100,5,132,0, + 90,5,100,6,83,0,41,7,218,18,95,73,109,112,111,114, + 116,76,111,99,107,67,111,110,116,101,120,116,122,36,67,111, + 110,116,101,120,116,32,109,97,110,97,103,101,114,32,102,111, + 114,32,116,104,101,32,105,109,112,111,114,116,32,108,111,99, + 107,46,99,1,0,0,0,0,0,0,0,1,0,0,0,2, + 0,0,0,67,0,0,0,115,12,0,0,0,116,0,160,1, + 161,0,1,0,100,1,83,0,41,2,122,24,65,99,113,117, + 105,114,101,32,116,104,101,32,105,109,112,111,114,116,32,108, + 111,99,107,46,78,41,2,114,57,0,0,0,114,58,0,0, + 0,114,47,0,0,0,114,10,0,0,0,114,10,0,0,0, + 114,11,0,0,0,114,54,0,0,0,95,3,0,0,115,2, + 0,0,0,0,2,122,28,95,73,109,112,111,114,116,76,111, + 99,107,67,111,110,116,101,120,116,46,95,95,101,110,116,101, + 114,95,95,99,4,0,0,0,0,0,0,0,4,0,0,0, + 2,0,0,0,67,0,0,0,115,12,0,0,0,116,0,160, + 1,161,0,1,0,100,1,83,0,41,2,122,60,82,101,108, + 101,97,115,101,32,116,104,101,32,105,109,112,111,114,116,32, + 108,111,99,107,32,114,101,103,97,114,100,108,101,115,115,32, + 111,102,32,97,110,121,32,114,97,105,115,101,100,32,101,120, + 99,101,112,116,105,111,110,115,46,78,41,2,114,57,0,0, + 0,114,60,0,0,0,41,4,114,30,0,0,0,90,8,101, + 120,99,95,116,121,112,101,90,9,101,120,99,95,118,97,108, + 117,101,90,13,101,120,99,95,116,114,97,99,101,98,97,99, + 107,114,10,0,0,0,114,10,0,0,0,114,11,0,0,0, + 114,56,0,0,0,99,3,0,0,115,2,0,0,0,0,2, + 122,27,95,73,109,112,111,114,116,76,111,99,107,67,111,110, + 116,101,120,116,46,95,95,101,120,105,116,95,95,78,41,6, + 114,1,0,0,0,114,0,0,0,0,114,2,0,0,0,114, + 3,0,0,0,114,54,0,0,0,114,56,0,0,0,114,10, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,114,178,0,0,0,91,3,0,0,115,6,0,0,0, + 8,2,4,2,8,4,114,178,0,0,0,99,3,0,0,0, + 0,0,0,0,5,0,0,0,5,0,0,0,67,0,0,0, + 115,64,0,0,0,124,1,160,0,100,1,124,2,100,2,24, + 0,161,2,125,3,116,1,124,3,131,1,124,2,107,0,114, + 36,116,2,100,3,131,1,130,1,124,3,100,4,25,0,125, + 4,124,0,114,60,100,5,160,3,124,4,124,0,161,2,83, + 0,124,4,83,0,41,6,122,50,82,101,115,111,108,118,101, + 32,97,32,114,101,108,97,116,105,118,101,32,109,111,100,117, + 108,101,32,110,97,109,101,32,116,111,32,97,110,32,97,98, + 115,111,108,117,116,101,32,111,110,101,46,114,128,0,0,0, + 114,37,0,0,0,122,50,97,116,116,101,109,112,116,101,100, + 32,114,101,108,97,116,105,118,101,32,105,109,112,111,114,116, + 32,98,101,121,111,110,100,32,116,111,112,45,108,101,118,101, + 108,32,112,97,99,107,97,103,101,114,22,0,0,0,250,5, + 123,125,46,123,125,41,4,218,6,114,115,112,108,105,116,218, + 3,108,101,110,218,10,86,97,108,117,101,69,114,114,111,114, + 114,45,0,0,0,41,5,114,17,0,0,0,218,7,112,97, + 99,107,97,103,101,218,5,108,101,118,101,108,90,4,98,105, + 116,115,90,4,98,97,115,101,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,13,95,114,101,115,111,108,118, + 101,95,110,97,109,101,104,3,0,0,115,10,0,0,0,0, + 2,16,1,12,1,8,1,8,1,114,185,0,0,0,99,3, + 0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,67, + 0,0,0,115,34,0,0,0,124,0,160,0,124,1,124,2, + 161,2,125,3,124,3,100,0,107,8,114,24,100,0,83,0, + 116,1,124,1,124,3,131,2,83,0,114,13,0,0,0,41, + 2,114,167,0,0,0,114,91,0,0,0,41,4,218,6,102, + 105,110,100,101,114,114,17,0,0,0,114,164,0,0,0,114, + 109,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,17,95,102,105,110,100,95,115,112,101,99,95, + 108,101,103,97,99,121,113,3,0,0,115,8,0,0,0,0, + 3,12,1,8,1,4,1,114,187,0,0,0,99,3,0,0, + 0,0,0,0,0,10,0,0,0,10,0,0,0,67,0,0, + 0,115,12,1,0,0,116,0,106,1,125,3,124,3,100,1, + 107,8,114,22,116,2,100,2,131,1,130,1,124,3,115,38, + 116,3,160,4,100,3,116,5,161,2,1,0,124,0,116,0, + 106,6,107,6,125,4,124,3,68,0,93,210,125,5,116,7, + 131,0,143,84,1,0,122,10,124,5,106,8,125,6,87,0, + 110,54,4,0,116,9,107,10,114,128,1,0,1,0,1,0, + 116,10,124,5,124,0,124,1,131,3,125,7,124,7,100,1, + 107,8,114,124,89,0,87,0,53,0,81,0,82,0,163,0, + 113,52,89,0,110,14,88,0,124,6,124,0,124,1,124,2, + 131,3,125,7,87,0,53,0,81,0,82,0,88,0,124,7, + 100,1,107,9,114,52,124,4,144,0,115,254,124,0,116,0, + 106,6,107,6,144,0,114,254,116,0,106,6,124,0,25,0, + 125,8,122,10,124,8,106,11,125,9,87,0,110,28,4,0, + 116,9,107,10,114,226,1,0,1,0,1,0,124,7,6,0, + 89,0,2,0,1,0,83,0,88,0,124,9,100,1,107,8, + 114,244,124,7,2,0,1,0,83,0,124,9,2,0,1,0, + 83,0,113,52,124,7,2,0,1,0,83,0,113,52,100,1, + 83,0,41,4,122,21,70,105,110,100,32,97,32,109,111,100, + 117,108,101,39,115,32,115,112,101,99,46,78,122,53,115,121, + 115,46,109,101,116,97,95,112,97,116,104,32,105,115,32,78, + 111,110,101,44,32,80,121,116,104,111,110,32,105,115,32,108, + 105,107,101,108,121,32,115,104,117,116,116,105,110,103,32,100, + 111,119,110,122,22,115,121,115,46,109,101,116,97,95,112,97, + 116,104,32,105,115,32,101,109,112,116,121,41,12,114,15,0, + 0,0,218,9,109,101,116,97,95,112,97,116,104,114,79,0, + 0,0,218,9,95,119,97,114,110,105,110,103,115,218,4,119, + 97,114,110,218,13,73,109,112,111,114,116,87,97,114,110,105, + 110,103,114,92,0,0,0,114,178,0,0,0,114,166,0,0, + 0,114,106,0,0,0,114,187,0,0,0,114,105,0,0,0, + 41,10,114,17,0,0,0,114,164,0,0,0,114,165,0,0, + 0,114,188,0,0,0,90,9,105,115,95,114,101,108,111,97, + 100,114,186,0,0,0,114,166,0,0,0,114,95,0,0,0, + 114,96,0,0,0,114,105,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,10,95,102,105,110,100, + 95,115,112,101,99,122,3,0,0,115,54,0,0,0,0,2, + 6,1,8,2,8,3,4,1,12,5,10,1,8,1,8,1, + 2,1,10,1,14,1,12,1,8,1,20,2,22,1,8,2, + 18,1,10,1,2,1,10,1,14,4,14,2,8,1,8,2, + 10,2,10,2,114,192,0,0,0,99,3,0,0,0,0,0, + 0,0,3,0,0,0,5,0,0,0,67,0,0,0,115,108, + 0,0,0,116,0,124,0,116,1,131,2,115,28,116,2,100, + 1,160,3,116,4,124,0,131,1,161,1,131,1,130,1,124, + 2,100,2,107,0,114,44,116,5,100,3,131,1,130,1,124, + 2,100,2,107,4,114,84,116,0,124,1,116,1,131,2,115, + 72,116,2,100,4,131,1,130,1,110,12,124,1,115,84,116, + 6,100,5,131,1,130,1,124,0,115,104,124,2,100,2,107, + 2,114,104,116,5,100,6,131,1,130,1,100,7,83,0,41, + 8,122,28,86,101,114,105,102,121,32,97,114,103,117,109,101, + 110,116,115,32,97,114,101,32,34,115,97,110,101,34,46,122, + 31,109,111,100,117,108,101,32,110,97,109,101,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,123,125, + 114,22,0,0,0,122,18,108,101,118,101,108,32,109,117,115, + 116,32,98,101,32,62,61,32,48,122,31,95,95,112,97,99, + 107,97,103,101,95,95,32,110,111,116,32,115,101,116,32,116, + 111,32,97,32,115,116,114,105,110,103,122,54,97,116,116,101, + 109,112,116,101,100,32,114,101,108,97,116,105,118,101,32,105, + 109,112,111,114,116,32,119,105,116,104,32,110,111,32,107,110, + 111,119,110,32,112,97,114,101,110,116,32,112,97,99,107,97, + 103,101,122,17,69,109,112,116,121,32,109,111,100,117,108,101, + 32,110,97,109,101,78,41,7,218,10,105,115,105,110,115,116, + 97,110,99,101,218,3,115,116,114,218,9,84,121,112,101,69, + 114,114,111,114,114,45,0,0,0,114,14,0,0,0,114,182, + 0,0,0,114,79,0,0,0,169,3,114,17,0,0,0,114, + 183,0,0,0,114,184,0,0,0,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,13,95,115,97,110,105,116, + 121,95,99,104,101,99,107,169,3,0,0,115,22,0,0,0, + 0,2,10,1,18,1,8,1,8,1,8,1,10,1,10,1, + 4,1,8,2,12,1,114,197,0,0,0,122,16,78,111,32, + 109,111,100,117,108,101,32,110,97,109,101,100,32,122,4,123, + 33,114,125,99,2,0,0,0,0,0,0,0,8,0,0,0, + 8,0,0,0,67,0,0,0,115,220,0,0,0,100,0,125, + 2,124,0,160,0,100,1,161,1,100,2,25,0,125,3,124, + 3,114,134,124,3,116,1,106,2,107,7,114,42,116,3,124, + 1,124,3,131,2,1,0,124,0,116,1,106,2,107,6,114, + 62,116,1,106,2,124,0,25,0,83,0,116,1,106,2,124, + 3,25,0,125,4,122,10,124,4,106,4,125,2,87,0,110, + 50,4,0,116,5,107,10,114,132,1,0,1,0,1,0,116, + 6,100,3,23,0,160,7,124,0,124,3,161,2,125,5,116, + 8,124,5,124,0,100,4,141,2,100,0,130,2,89,0,110, + 2,88,0,116,9,124,0,124,2,131,2,125,6,124,6,100, + 0,107,8,114,172,116,8,116,6,160,7,124,0,161,1,124, + 0,100,4,141,2,130,1,110,8,116,10,124,6,131,1,125, + 7,124,3,114,216,116,1,106,2,124,3,25,0,125,4,116, + 11,124,4,124,0,160,0,100,1,161,1,100,5,25,0,124, + 7,131,3,1,0,124,7,83,0,41,6,78,114,128,0,0, + 0,114,22,0,0,0,122,23,59,32,123,33,114,125,32,105, + 115,32,110,111,116,32,97,32,112,97,99,107,97,103,101,114, + 16,0,0,0,233,2,0,0,0,41,12,114,129,0,0,0, + 114,15,0,0,0,114,92,0,0,0,114,67,0,0,0,114, + 141,0,0,0,114,106,0,0,0,218,8,95,69,82,82,95, + 77,83,71,114,45,0,0,0,218,19,77,111,100,117,108,101, + 78,111,116,70,111,117,110,100,69,114,114,111,114,114,192,0, + 0,0,114,159,0,0,0,114,5,0,0,0,41,8,114,17, + 0,0,0,218,7,105,109,112,111,114,116,95,114,164,0,0, + 0,114,130,0,0,0,90,13,112,97,114,101,110,116,95,109, + 111,100,117,108,101,114,157,0,0,0,114,95,0,0,0,114, + 96,0,0,0,114,10,0,0,0,114,10,0,0,0,114,11, + 0,0,0,218,23,95,102,105,110,100,95,97,110,100,95,108, + 111,97,100,95,117,110,108,111,99,107,101,100,188,3,0,0, + 115,42,0,0,0,0,1,4,1,14,1,4,1,10,1,10, + 2,10,1,10,1,10,1,2,1,10,1,14,1,16,1,20, + 1,10,1,8,1,20,2,8,1,4,2,10,1,22,1,114, + 202,0,0,0,99,2,0,0,0,0,0,0,0,4,0,0, + 0,10,0,0,0,67,0,0,0,115,106,0,0,0,116,0, + 124,0,131,1,143,50,1,0,116,1,106,2,160,3,124,0, + 116,4,161,2,125,2,124,2,116,4,107,8,114,54,116,5, + 124,0,124,1,131,2,87,0,2,0,53,0,81,0,82,0, + 163,0,83,0,87,0,53,0,81,0,82,0,88,0,124,2, + 100,1,107,8,114,94,100,2,160,6,124,0,161,1,125,3, + 116,7,124,3,124,0,100,3,141,2,130,1,116,8,124,0, + 131,1,1,0,124,2,83,0,41,4,122,25,70,105,110,100, + 32,97,110,100,32,108,111,97,100,32,116,104,101,32,109,111, + 100,117,108,101,46,78,122,40,105,109,112,111,114,116,32,111, + 102,32,123,125,32,104,97,108,116,101,100,59,32,78,111,110, + 101,32,105,110,32,115,121,115,46,109,111,100,117,108,101,115, + 114,16,0,0,0,41,9,114,50,0,0,0,114,15,0,0, + 0,114,92,0,0,0,114,34,0,0,0,218,14,95,78,69, + 69,68,83,95,76,79,65,68,73,78,71,114,202,0,0,0, + 114,45,0,0,0,114,200,0,0,0,114,65,0,0,0,41, + 4,114,17,0,0,0,114,201,0,0,0,114,96,0,0,0, + 114,75,0,0,0,114,10,0,0,0,114,10,0,0,0,114, + 11,0,0,0,218,14,95,102,105,110,100,95,97,110,100,95, + 108,111,97,100,218,3,0,0,115,22,0,0,0,0,2,10, + 1,14,1,8,1,32,2,8,1,4,1,2,255,4,2,12, + 2,8,1,114,204,0,0,0,114,22,0,0,0,99,3,0, + 0,0,0,0,0,0,3,0,0,0,4,0,0,0,67,0, + 0,0,115,42,0,0,0,116,0,124,0,124,1,124,2,131, + 3,1,0,124,2,100,1,107,4,114,32,116,1,124,0,124, + 1,124,2,131,3,125,0,116,2,124,0,116,3,131,2,83, + 0,41,2,97,50,1,0,0,73,109,112,111,114,116,32,97, + 110,100,32,114,101,116,117,114,110,32,116,104,101,32,109,111, + 100,117,108,101,32,98,97,115,101,100,32,111,110,32,105,116, + 115,32,110,97,109,101,44,32,116,104,101,32,112,97,99,107, + 97,103,101,32,116,104,101,32,99,97,108,108,32,105,115,10, + 32,32,32,32,98,101,105,110,103,32,109,97,100,101,32,102, + 114,111,109,44,32,97,110,100,32,116,104,101,32,108,101,118, + 101,108,32,97,100,106,117,115,116,109,101,110,116,46,10,10, + 32,32,32,32,84,104,105,115,32,102,117,110,99,116,105,111, + 110,32,114,101,112,114,101,115,101,110,116,115,32,116,104,101, + 32,103,114,101,97,116,101,115,116,32,99,111,109,109,111,110, + 32,100,101,110,111,109,105,110,97,116,111,114,32,111,102,32, + 102,117,110,99,116,105,111,110,97,108,105,116,121,10,32,32, + 32,32,98,101,116,119,101,101,110,32,105,109,112,111,114,116, + 95,109,111,100,117,108,101,32,97,110,100,32,95,95,105,109, + 112,111,114,116,95,95,46,32,84,104,105,115,32,105,110,99, + 108,117,100,101,115,32,115,101,116,116,105,110,103,32,95,95, + 112,97,99,107,97,103,101,95,95,32,105,102,10,32,32,32, + 32,116,104,101,32,108,111,97,100,101,114,32,100,105,100,32, + 110,111,116,46,10,10,32,32,32,32,114,22,0,0,0,41, + 4,114,197,0,0,0,114,185,0,0,0,114,204,0,0,0, + 218,11,95,103,99,100,95,105,109,112,111,114,116,114,196,0, + 0,0,114,10,0,0,0,114,10,0,0,0,114,11,0,0, + 0,114,205,0,0,0,234,3,0,0,115,8,0,0,0,0, + 9,12,1,8,1,12,1,114,205,0,0,0,169,1,218,9, + 114,101,99,117,114,115,105,118,101,99,3,0,0,0,1,0, + 0,0,8,0,0,0,11,0,0,0,67,0,0,0,115,226, + 0,0,0,124,1,68,0,93,216,125,4,116,0,124,4,116, + 1,131,2,115,66,124,3,114,34,124,0,106,2,100,1,23, + 0,125,5,110,4,100,2,125,5,116,3,100,3,124,5,155, + 0,100,4,116,4,124,4,131,1,106,2,155,0,157,4,131, + 1,130,1,110,154,124,4,100,5,107,2,114,108,124,3,115, + 106,116,5,124,0,100,6,131,2,114,106,116,6,124,0,124, + 0,106,7,124,2,100,7,100,8,141,4,1,0,110,112,116, + 5,124,0,124,4,131,2,115,220,100,9,160,8,124,0,106, + 2,124,4,161,2,125,6,122,14,116,9,124,2,124,6,131, + 2,1,0,87,0,110,72,4,0,116,10,107,10,114,218,1, + 0,125,7,1,0,122,42,124,7,106,11,124,6,107,2,114, + 200,116,12,106,13,160,14,124,6,116,15,161,2,100,10,107, + 9,114,200,87,0,89,0,162,8,113,4,130,0,87,0,53, + 0,100,10,125,7,126,7,88,0,89,0,110,2,88,0,113, + 4,124,0,83,0,41,11,122,238,70,105,103,117,114,101,32, + 111,117,116,32,119,104,97,116,32,95,95,105,109,112,111,114, + 116,95,95,32,115,104,111,117,108,100,32,114,101,116,117,114, + 110,46,10,10,32,32,32,32,84,104,101,32,105,109,112,111, + 114,116,95,32,112,97,114,97,109,101,116,101,114,32,105,115, + 32,97,32,99,97,108,108,97,98,108,101,32,119,104,105,99, + 104,32,116,97,107,101,115,32,116,104,101,32,110,97,109,101, + 32,111,102,32,109,111,100,117,108,101,32,116,111,10,32,32, + 32,32,105,109,112,111,114,116,46,32,73,116,32,105,115,32, + 114,101,113,117,105,114,101,100,32,116,111,32,100,101,99,111, + 117,112,108,101,32,116,104,101,32,102,117,110,99,116,105,111, + 110,32,102,114,111,109,32,97,115,115,117,109,105,110,103,32, + 105,109,112,111,114,116,108,105,98,39,115,10,32,32,32,32, + 105,109,112,111,114,116,32,105,109,112,108,101,109,101,110,116, + 97,116,105,111,110,32,105,115,32,100,101,115,105,114,101,100, + 46,10,10,32,32,32,32,122,8,46,95,95,97,108,108,95, + 95,122,13,96,96,102,114,111,109,32,108,105,115,116,39,39, + 122,8,73,116,101,109,32,105,110,32,122,18,32,109,117,115, + 116,32,98,101,32,115,116,114,44,32,110,111,116,32,250,1, + 42,218,7,95,95,97,108,108,95,95,84,114,206,0,0,0, + 114,179,0,0,0,78,41,16,114,193,0,0,0,114,194,0, + 0,0,114,1,0,0,0,114,195,0,0,0,114,14,0,0, + 0,114,4,0,0,0,218,16,95,104,97,110,100,108,101,95, + 102,114,111,109,108,105,115,116,114,209,0,0,0,114,45,0, + 0,0,114,67,0,0,0,114,200,0,0,0,114,17,0,0, + 0,114,15,0,0,0,114,92,0,0,0,114,34,0,0,0, + 114,203,0,0,0,41,8,114,96,0,0,0,218,8,102,114, + 111,109,108,105,115,116,114,201,0,0,0,114,207,0,0,0, + 218,1,120,90,5,119,104,101,114,101,90,9,102,114,111,109, + 95,110,97,109,101,90,3,101,120,99,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,114,210,0,0,0,249,3, + 0,0,115,44,0,0,0,0,10,8,1,10,1,4,1,12, + 2,4,1,28,2,8,1,14,1,10,1,2,255,8,2,10, + 1,14,1,2,1,14,1,16,4,10,1,16,255,2,2,8, + 1,22,1,114,210,0,0,0,99,1,0,0,0,0,0,0, + 0,3,0,0,0,6,0,0,0,67,0,0,0,115,146,0, + 0,0,124,0,160,0,100,1,161,1,125,1,124,0,160,0, + 100,2,161,1,125,2,124,1,100,3,107,9,114,82,124,2, + 100,3,107,9,114,78,124,1,124,2,106,1,107,3,114,78, + 116,2,106,3,100,4,124,1,155,2,100,5,124,2,106,1, + 155,2,100,6,157,5,116,4,100,7,100,8,141,3,1,0, + 124,1,83,0,124,2,100,3,107,9,114,96,124,2,106,1, + 83,0,116,2,106,3,100,9,116,4,100,7,100,8,141,3, + 1,0,124,0,100,10,25,0,125,1,100,11,124,0,107,7, + 114,142,124,1,160,5,100,12,161,1,100,13,25,0,125,1, + 124,1,83,0,41,14,122,167,67,97,108,99,117,108,97,116, + 101,32,119,104,97,116,32,95,95,112,97,99,107,97,103,101, + 95,95,32,115,104,111,117,108,100,32,98,101,46,10,10,32, + 32,32,32,95,95,112,97,99,107,97,103,101,95,95,32,105, + 115,32,110,111,116,32,103,117,97,114,97,110,116,101,101,100, + 32,116,111,32,98,101,32,100,101,102,105,110,101,100,32,111, + 114,32,99,111,117,108,100,32,98,101,32,115,101,116,32,116, + 111,32,78,111,110,101,10,32,32,32,32,116,111,32,114,101, + 112,114,101,115,101,110,116,32,116,104,97,116,32,105,116,115, + 32,112,114,111,112,101,114,32,118,97,108,117,101,32,105,115, + 32,117,110,107,110,111,119,110,46,10,10,32,32,32,32,114, + 145,0,0,0,114,105,0,0,0,78,122,32,95,95,112,97, + 99,107,97,103,101,95,95,32,33,61,32,95,95,115,112,101, + 99,95,95,46,112,97,114,101,110,116,32,40,122,4,32,33, + 61,32,250,1,41,233,3,0,0,0,41,1,90,10,115,116, + 97,99,107,108,101,118,101,108,122,89,99,97,110,39,116,32, + 114,101,115,111,108,118,101,32,112,97,99,107,97,103,101,32, + 102,114,111,109,32,95,95,115,112,101,99,95,95,32,111,114, + 32,95,95,112,97,99,107,97,103,101,95,95,44,32,102,97, + 108,108,105,110,103,32,98,97,99,107,32,111,110,32,95,95, + 110,97,109,101,95,95,32,97,110,100,32,95,95,112,97,116, + 104,95,95,114,1,0,0,0,114,141,0,0,0,114,128,0, + 0,0,114,22,0,0,0,41,6,114,34,0,0,0,114,130, + 0,0,0,114,189,0,0,0,114,190,0,0,0,114,191,0, + 0,0,114,129,0,0,0,41,3,218,7,103,108,111,98,97, + 108,115,114,183,0,0,0,114,95,0,0,0,114,10,0,0, + 0,114,10,0,0,0,114,11,0,0,0,218,17,95,99,97, + 108,99,95,95,95,112,97,99,107,97,103,101,95,95,30,4, + 0,0,115,38,0,0,0,0,7,10,1,10,1,8,1,18, + 1,22,2,2,0,2,254,6,3,4,1,8,1,6,2,6, + 2,2,0,2,254,6,3,8,1,8,1,14,1,114,216,0, + 0,0,114,10,0,0,0,99,5,0,0,0,0,0,0,0, + 9,0,0,0,5,0,0,0,67,0,0,0,115,180,0,0, + 0,124,4,100,1,107,2,114,18,116,0,124,0,131,1,125, + 5,110,36,124,1,100,2,107,9,114,30,124,1,110,2,105, + 0,125,6,116,1,124,6,131,1,125,7,116,0,124,0,124, + 7,124,4,131,3,125,5,124,3,115,150,124,4,100,1,107, + 2,114,84,116,0,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,83,0,124,0,115,92,124,5,83,0,116,3,124, + 0,131,1,116,3,124,0,160,2,100,3,161,1,100,1,25, + 0,131,1,24,0,125,8,116,4,106,5,124,5,106,6,100, + 2,116,3,124,5,106,6,131,1,124,8,24,0,133,2,25, + 0,25,0,83,0,110,26,116,7,124,5,100,4,131,2,114, + 172,116,8,124,5,124,3,116,0,131,3,83,0,124,5,83, + 0,100,2,83,0,41,5,97,215,1,0,0,73,109,112,111, + 114,116,32,97,32,109,111,100,117,108,101,46,10,10,32,32, + 32,32,84,104,101,32,39,103,108,111,98,97,108,115,39,32, + 97,114,103,117,109,101,110,116,32,105,115,32,117,115,101,100, + 32,116,111,32,105,110,102,101,114,32,119,104,101,114,101,32, + 116,104,101,32,105,109,112,111,114,116,32,105,115,32,111,99, + 99,117,114,114,105,110,103,32,102,114,111,109,10,32,32,32, + 32,116,111,32,104,97,110,100,108,101,32,114,101,108,97,116, + 105,118,101,32,105,109,112,111,114,116,115,46,32,84,104,101, + 32,39,108,111,99,97,108,115,39,32,97,114,103,117,109,101, + 110,116,32,105,115,32,105,103,110,111,114,101,100,46,32,84, + 104,101,10,32,32,32,32,39,102,114,111,109,108,105,115,116, + 39,32,97,114,103,117,109,101,110,116,32,115,112,101,99,105, + 102,105,101,115,32,119,104,97,116,32,115,104,111,117,108,100, + 32,101,120,105,115,116,32,97,115,32,97,116,116,114,105,98, + 117,116,101,115,32,111,110,32,116,104,101,32,109,111,100,117, + 108,101,10,32,32,32,32,98,101,105,110,103,32,105,109,112, + 111,114,116,101,100,32,40,101,46,103,46,32,96,96,102,114, + 111,109,32,109,111,100,117,108,101,32,105,109,112,111,114,116, + 32,60,102,114,111,109,108,105,115,116,62,96,96,41,46,32, + 32,84,104,101,32,39,108,101,118,101,108,39,10,32,32,32, + 32,97,114,103,117,109,101,110,116,32,114,101,112,114,101,115, + 101,110,116,115,32,116,104,101,32,112,97,99,107,97,103,101, + 32,108,111,99,97,116,105,111,110,32,116,111,32,105,109,112, + 111,114,116,32,102,114,111,109,32,105,110,32,97,32,114,101, + 108,97,116,105,118,101,10,32,32,32,32,105,109,112,111,114, + 116,32,40,101,46,103,46,32,96,96,102,114,111,109,32,46, + 46,112,107,103,32,105,109,112,111,114,116,32,109,111,100,96, + 96,32,119,111,117,108,100,32,104,97,118,101,32,97,32,39, + 108,101,118,101,108,39,32,111,102,32,50,41,46,10,10,32, + 32,32,32,114,22,0,0,0,78,114,128,0,0,0,114,141, + 0,0,0,41,9,114,205,0,0,0,114,216,0,0,0,218, + 9,112,97,114,116,105,116,105,111,110,114,181,0,0,0,114, + 15,0,0,0,114,92,0,0,0,114,1,0,0,0,114,4, + 0,0,0,114,210,0,0,0,41,9,114,17,0,0,0,114, + 215,0,0,0,218,6,108,111,99,97,108,115,114,211,0,0, + 0,114,184,0,0,0,114,96,0,0,0,90,8,103,108,111, + 98,97,108,115,95,114,183,0,0,0,90,7,99,117,116,95, + 111,102,102,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,10,95,95,105,109,112,111,114,116,95,95,57,4, + 0,0,115,30,0,0,0,0,11,8,1,10,2,16,1,8, + 1,12,1,4,3,8,1,18,1,4,1,4,4,26,3,32, + 1,10,1,12,2,114,219,0,0,0,99,1,0,0,0,0, + 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, + 38,0,0,0,116,0,160,1,124,0,161,1,125,1,124,1, + 100,0,107,8,114,30,116,2,100,1,124,0,23,0,131,1, + 130,1,116,3,124,1,131,1,83,0,41,2,78,122,25,110, + 111,32,98,117,105,108,116,45,105,110,32,109,111,100,117,108, + 101,32,110,97,109,101,100,32,41,4,114,160,0,0,0,114, + 166,0,0,0,114,79,0,0,0,114,159,0,0,0,41,2, + 114,17,0,0,0,114,95,0,0,0,114,10,0,0,0,114, + 10,0,0,0,114,11,0,0,0,218,18,95,98,117,105,108, + 116,105,110,95,102,114,111,109,95,110,97,109,101,94,4,0, + 0,115,8,0,0,0,0,1,10,1,8,1,12,1,114,220, + 0,0,0,99,2,0,0,0,0,0,0,0,10,0,0,0, + 5,0,0,0,67,0,0,0,115,166,0,0,0,124,1,97, + 0,124,0,97,1,116,2,116,1,131,1,125,2,116,1,106, + 3,160,4,161,0,68,0,93,72,92,2,125,3,125,4,116, + 5,124,4,124,2,131,2,114,26,124,3,116,1,106,6,107, + 6,114,60,116,7,125,5,110,18,116,0,160,8,124,3,161, + 1,114,26,116,9,125,5,110,2,113,26,116,10,124,4,124, + 5,131,2,125,6,116,11,124,6,124,4,131,2,1,0,113, + 26,116,1,106,3,116,12,25,0,125,7,100,1,68,0,93, + 46,125,8,124,8,116,1,106,3,107,7,114,138,116,13,124, + 8,131,1,125,9,110,10,116,1,106,3,124,8,25,0,125, + 9,116,14,124,7,124,8,124,9,131,3,1,0,113,114,100, + 2,83,0,41,3,122,250,83,101,116,117,112,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,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,10,32, + 32,32,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,65,115,32,115,121,115,32,105,115,32,110,101,101, + 100,101,100,32,102,111,114,32,115,121,115,46,109,111,100,117, + 108,101,115,32,97,99,99,101,115,115,32,97,110,100,32,95, + 105,109,112,32,105,115,32,110,101,101,100,101,100,32,116,111, + 32,108,111,97,100,32,98,117,105,108,116,45,105,110,10,32, + 32,32,32,109,111,100,117,108,101,115,44,32,116,104,111,115, + 101,32,116,119,111,32,109,111,100,117,108,101,115,32,109,117, + 115,116,32,98,101,32,101,120,112,108,105,99,105,116,108,121, + 32,112,97,115,115,101,100,32,105,110,46,10,10,32,32,32, + 32,41,3,114,23,0,0,0,114,189,0,0,0,114,64,0, + 0,0,78,41,15,114,57,0,0,0,114,15,0,0,0,114, + 14,0,0,0,114,92,0,0,0,218,5,105,116,101,109,115, + 114,193,0,0,0,114,78,0,0,0,114,160,0,0,0,114, + 88,0,0,0,114,173,0,0,0,114,142,0,0,0,114,148, + 0,0,0,114,1,0,0,0,114,220,0,0,0,114,5,0, + 0,0,41,10,218,10,115,121,115,95,109,111,100,117,108,101, + 218,11,95,105,109,112,95,109,111,100,117,108,101,90,11,109, + 111,100,117,108,101,95,116,121,112,101,114,17,0,0,0,114, + 96,0,0,0,114,109,0,0,0,114,95,0,0,0,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,114,10,0,0,0,114,10, + 0,0,0,114,11,0,0,0,218,6,95,115,101,116,117,112, + 101,4,0,0,115,36,0,0,0,0,9,4,1,4,3,8, + 1,18,1,10,1,10,1,6,1,10,1,6,2,2,1,10, + 1,12,3,10,1,8,1,10,1,10,2,10,1,114,224,0, + 0,0,99,2,0,0,0,0,0,0,0,2,0,0,0,3, + 0,0,0,67,0,0,0,115,38,0,0,0,116,0,124,0, + 124,1,131,2,1,0,116,1,106,2,160,3,116,4,161,1, + 1,0,116,1,106,2,160,3,116,5,161,1,1,0,100,1, + 83,0,41,2,122,48,73,110,115,116,97,108,108,32,105,109, + 112,111,114,116,101,114,115,32,102,111,114,32,98,117,105,108, + 116,105,110,32,97,110,100,32,102,114,111,122,101,110,32,109, + 111,100,117,108,101,115,78,41,6,114,224,0,0,0,114,15, + 0,0,0,114,188,0,0,0,114,120,0,0,0,114,160,0, + 0,0,114,173,0,0,0,41,2,114,222,0,0,0,114,223, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,11,0, + 0,0,218,8,95,105,110,115,116,97,108,108,136,4,0,0, + 115,6,0,0,0,0,2,10,2,12,1,114,225,0,0,0, + 99,0,0,0,0,0,0,0,0,1,0,0,0,4,0,0, + 0,67,0,0,0,115,32,0,0,0,100,1,100,2,108,0, + 125,0,124,0,97,1,124,0,160,2,116,3,106,4,116,5, + 25,0,161,1,1,0,100,2,83,0,41,3,122,57,73,110, + 115,116,97,108,108,32,105,109,112,111,114,116,101,114,115,32, + 116,104,97,116,32,114,101,113,117,105,114,101,32,101,120,116, + 101,114,110,97,108,32,102,105,108,101,115,121,115,116,101,109, + 32,97,99,99,101,115,115,114,22,0,0,0,78,41,6,218, + 26,95,102,114,111,122,101,110,95,105,109,112,111,114,116,108, + 105,98,95,101,120,116,101,114,110,97,108,114,126,0,0,0, + 114,225,0,0,0,114,15,0,0,0,114,92,0,0,0,114, + 1,0,0,0,41,1,114,226,0,0,0,114,10,0,0,0, + 114,10,0,0,0,114,11,0,0,0,218,27,95,105,110,115, + 116,97,108,108,95,101,120,116,101,114,110,97,108,95,105,109, + 112,111,114,116,101,114,115,144,4,0,0,115,6,0,0,0, + 0,3,8,1,4,1,114,227,0,0,0,41,2,78,78,41, + 1,78,41,2,78,114,22,0,0,0,41,4,78,78,114,10, + 0,0,0,114,22,0,0,0,41,50,114,3,0,0,0,114, + 126,0,0,0,114,12,0,0,0,114,18,0,0,0,114,59, + 0,0,0,114,33,0,0,0,114,42,0,0,0,114,19,0, + 0,0,114,20,0,0,0,114,49,0,0,0,114,50,0,0, + 0,114,53,0,0,0,114,65,0,0,0,114,67,0,0,0, + 114,76,0,0,0,114,86,0,0,0,114,90,0,0,0,114, + 97,0,0,0,114,111,0,0,0,114,112,0,0,0,114,91, + 0,0,0,114,142,0,0,0,114,148,0,0,0,114,152,0, + 0,0,114,107,0,0,0,114,93,0,0,0,114,158,0,0, + 0,114,159,0,0,0,114,94,0,0,0,114,160,0,0,0, + 114,173,0,0,0,114,178,0,0,0,114,185,0,0,0,114, + 187,0,0,0,114,192,0,0,0,114,197,0,0,0,90,15, + 95,69,82,82,95,77,83,71,95,80,82,69,70,73,88,114, + 199,0,0,0,114,202,0,0,0,218,6,111,98,106,101,99, + 116,114,203,0,0,0,114,204,0,0,0,114,205,0,0,0, + 114,210,0,0,0,114,216,0,0,0,114,219,0,0,0,114, + 220,0,0,0,114,224,0,0,0,114,225,0,0,0,114,227, + 0,0,0,114,10,0,0,0,114,10,0,0,0,114,10,0, + 0,0,114,11,0,0,0,218,8,60,109,111,100,117,108,101, + 62,1,0,0,0,115,94,0,0,0,4,24,4,2,8,8, + 8,8,4,2,4,3,16,4,14,68,14,21,14,16,8,37, + 8,17,8,11,14,8,8,11,8,12,8,16,8,36,14,101, + 16,26,10,45,14,72,8,17,8,17,8,30,8,37,8,42, + 8,15,14,73,14,79,14,13,8,9,8,9,10,47,8,16, + 4,1,8,2,8,27,6,3,8,16,10,15,14,37,8,27, + 10,37,8,7,8,35,8,8, }; From 85e102a2b090dd693d0801ae2edb9660cfa0f281 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Mon, 4 Feb 2019 17:15:13 -0800 Subject: [PATCH 0011/1727] bpo-35299: Fixed sysconfig and distutils during PGO profiling (GH-11744) --- Lib/distutils/command/build_ext.py | 5 ++-- Lib/distutils/sysconfig.py | 25 ++++++++++++++----- Lib/distutils/tests/test_build_ext.py | 6 +++-- Lib/sysconfig.py | 13 +++++++--- .../2019-02-02-14-47-12.bpo-35299.1rgEzd.rst | 2 ++ Tools/msi/dev/dev.wixproj | 3 ++- 6 files changed, 40 insertions(+), 14 deletions(-) create mode 100644 Misc/NEWS.d/next/Windows/2019-02-02-14-47-12.bpo-35299.1rgEzd.rst diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 158465d2338c20..0428466b00c902 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -161,9 +161,10 @@ def finalize_options(self): # Put the Python "system" include dir at the end, so that # any local include dirs take precedence. - self.include_dirs.append(py_include) + self.include_dirs.extend(py_include.split(os.path.pathsep)) if plat_py_include != py_include: - self.include_dirs.append(plat_py_include) + self.include_dirs.extend( + plat_py_include.split(os.path.pathsep)) self.ensure_string_list('libraries') self.ensure_string_list('link_objects') diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index b433fc86ffccd7..40af493cdfb5f2 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -29,9 +29,7 @@ project_base = os.path.abspath(os.environ["_PYTHON_PROJECT_BASE"]) else: project_base = os.path.dirname(os.path.abspath(sys.executable)) -if (os.name == 'nt' and - project_base.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): - project_base = os.path.dirname(os.path.dirname(project_base)) + # python_build: (Boolean) if true, we're either building Python or # building an extension with an un-installed Python, so we use @@ -41,16 +39,26 @@ def _is_python_source_dir(d): if os.path.isfile(os.path.join(d, "Modules", fn)): return True return False + _sys_home = getattr(sys, '_home', None) -if (_sys_home and os.name == 'nt' and - _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): - _sys_home = os.path.dirname(os.path.dirname(_sys_home)) + +if os.name == 'nt': + def _fix_pcbuild(d): + if d and os.path.normcase(d).startswith( + os.path.normcase(os.path.join(PREFIX, "PCbuild"))): + return PREFIX + return d + project_base = _fix_pcbuild(project_base) + _sys_home = _fix_pcbuild(_sys_home) + def _python_build(): if _sys_home: return _is_python_source_dir(_sys_home) return _is_python_source_dir(project_base) + python_build = _python_build() + # Calculate the build qualifier flags if they are defined. Adding the flags # to the include and lib directories only makes sense for an installation, not # an in-source build. @@ -99,6 +107,11 @@ def get_python_inc(plat_specific=0, prefix=None): python_dir = 'python' + get_python_version() + build_flags return os.path.join(prefix, "include", python_dir) elif os.name == "nt": + if python_build: + # Include both the include and PC dir to ensure we can find + # pyconfig.h + return (os.path.join(prefix, "include") + os.path.pathsep + + os.path.join(prefix, "PC")) return os.path.join(prefix, "include") else: raise DistutilsPlatformError( diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index a72218274ca90e..88847f9e9aa7b1 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -177,10 +177,12 @@ def test_finalize_options(self): cmd.finalize_options() py_include = sysconfig.get_python_inc() - self.assertIn(py_include, cmd.include_dirs) + for p in py_include.split(os.path.pathsep): + self.assertIn(p, cmd.include_dirs) plat_py_include = sysconfig.get_python_inc(plat_specific=1) - self.assertIn(plat_py_include, cmd.include_dirs) + for p in plat_py_include.split(os.path.pathsep): + self.assertIn(p, cmd.include_dirs) # make sure cmd.libraries is turned into a list # if it's a string diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index e0f9c18531b674..cc8c7962b1bca2 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -125,9 +125,16 @@ def _is_python_source_dir(d): return False _sys_home = getattr(sys, '_home', None) -if (_sys_home and os.name == 'nt' and - _sys_home.lower().endswith(('\\pcbuild\\win32', '\\pcbuild\\amd64'))): - _sys_home = os.path.dirname(os.path.dirname(_sys_home)) + +if os.name == 'nt': + def _fix_pcbuild(d): + if d and os.path.normcase(d).startswith( + os.path.normcase(os.path.join(_PREFIX, "PCbuild"))): + return _PREFIX + return d + _PROJECT_BASE = _fix_pcbuild(_PROJECT_BASE) + _sys_home = _fix_pcbuild(_sys_home) + def is_python_build(check_home=False): if check_home and _sys_home: return _is_python_source_dir(_sys_home) diff --git a/Misc/NEWS.d/next/Windows/2019-02-02-14-47-12.bpo-35299.1rgEzd.rst b/Misc/NEWS.d/next/Windows/2019-02-02-14-47-12.bpo-35299.1rgEzd.rst new file mode 100644 index 00000000000000..19fba619b5ab9a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2019-02-02-14-47-12.bpo-35299.1rgEzd.rst @@ -0,0 +1,2 @@ +Fix sysconfig detection of the source directory and distutils handling of +pyconfig.h during PGO profiling diff --git a/Tools/msi/dev/dev.wixproj b/Tools/msi/dev/dev.wixproj index bc3a19ce33ca38..4a56cec35722cf 100644 --- a/Tools/msi/dev/dev.wixproj +++ b/Tools/msi/dev/dev.wixproj @@ -21,7 +21,8 @@ - + $(PySourcePath) !(bindpath.src) $(PySourcePath) From 9da3583e78603a81b1839e17a420079f734a75b0 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 4 Feb 2019 23:32:55 -0800 Subject: [PATCH 0012/1727] Fix typo (micro->nano) (GH-11759) --- Tools/scripts/var_access_benchmark.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/scripts/var_access_benchmark.py b/Tools/scripts/var_access_benchmark.py index b4f3b972705660..f8490457e65ad0 100644 --- a/Tools/scripts/var_access_benchmark.py +++ b/Tools/scripts/var_access_benchmark.py @@ -269,4 +269,4 @@ def loop_overhead(trials=trials): continue timing = min(Timer(f).repeat(7, 1000)) timing *= 1000000 / (len(trials) * steps_per_trial) - print(u'{:6.1f} \N{greek small letter mu}s\t{}'.format(timing, f.__name__)) + print('{:6.1f} ns\t{}'.format(timing, f.__name__)) From f34517094049170acc311bac30f68fa67f27a301 Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 5 Feb 2019 17:04:40 +0900 Subject: [PATCH 0013/1727] asyncio: use dict instead of OrderedDict (GH-11710) --- Lib/asyncio/base_events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index cec47ce67f3824..36fe7e0076c969 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -1187,7 +1187,7 @@ async def create_datagram_endpoint(self, protocol_factory, (local_addr, remote_addr)), ) else: # join address by (family, protocol) - addr_infos = collections.OrderedDict() + addr_infos = {} # Using order preserving dict for idx, addr in ((0, local_addr), (1, remote_addr)): if addr is not None: assert isinstance(addr, tuple) and len(addr) == 2, ( From c95404ff65dab1469dcd1dfec58ba54a8e7e7b3a Mon Sep 17 00:00:00 2001 From: Inada Naoki Date: Tue, 5 Feb 2019 17:05:43 +0900 Subject: [PATCH 0014/1727] email: use dict instead of OrderedDict (GH-11709) --- Lib/email/_header_value_parser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py index 416da1a80d9c5f..922daa2560f006 100644 --- a/Lib/email/_header_value_parser.py +++ b/Lib/email/_header_value_parser.py @@ -70,7 +70,6 @@ import re import urllib # For urllib.parse.unquote from string import hexdigits -from collections import OrderedDict from operator import itemgetter from email import _encoded_words as _ew from email import errors @@ -720,7 +719,7 @@ def params(self): # to assume the RFC 2231 pieces can come in any order. However, we # output them in the order that we first see a given name, which gives # us a stable __str__. - params = OrderedDict() + params = {} # Using order preserving dict from Python 3.7+ for token in self: if not token.token_type.endswith('parameter'): continue From cd90f6a3692e0f7ef0a13aae651e19a08d1f9b31 Mon Sep 17 00:00:00 2001 From: Harmandeep Singh Date: Tue, 5 Feb 2019 15:46:13 +0530 Subject: [PATCH 0015/1727] bpo-20001: update pathlib landing image (GH-11304) --- Doc/library/pathlib-inheritance.png | Bin 6456 -> 6431 bytes Doc/library/pathlib-inheritance.svg | 5 +---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Doc/library/pathlib-inheritance.png b/Doc/library/pathlib-inheritance.png index f0e8d021341844dd68e3153d6c9d4d4091334bb0..628ae6e9adb6fa99a779a0fab699c79c6749ba84 100644 GIT binary patch literal 6431 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 BxikO( literal 6456 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 lo$GL*FtmAm^zW{5LLiPXv diff --git a/Doc/library/pathlib-inheritance.svg b/Doc/library/pathlib-inheritance.svg index 9f42005e0a12bd..49057f678fd7d0 100644 --- a/Doc/library/pathlib-inheritance.svg +++ b/Doc/library/pathlib-inheritance.svg @@ -1,4 +1 @@ - - - - + \ No newline at end of file From e9bc4172d18db9c182d8e04dd7b033097a994c06 Mon Sep 17 00:00:00 2001 From: Mariatta Date: Wed, 6 Feb 2019 12:45:03 -0800 Subject: [PATCH 0016/1727] Fix url to core-mentorship mailing list (GH-11775) --- Doc/bugs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/bugs.rst b/Doc/bugs.rst index 3206a456b3a88f..c449ba2e719203 100644 --- a/Doc/bugs.rst +++ b/Doc/bugs.rst @@ -89,4 +89,4 @@ any and all questions pertaining to the process of fixing issues in Python. .. _Documentation bugs: https://bugs.python.org/issue?@filter=status&@filter=components&components=4&status=1&@columns=id,activity,title,status&@sort=-activity .. _Python Developer's Guide: https://devguide.python.org/ -.. _core-mentorship mailing list: https://mail.python.org/mailman/listinfo/core-mentorship/ +.. _core-mentorship mailing list: https://mail.python.org/mailman3/lists/core-mentorship.python.org/ From bc098515864d0d1ffe8fb97ca1a0526c30fee45a Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Thu, 7 Feb 2019 07:04:02 +0000 Subject: [PATCH 0017/1727] bpo-35606: Implement math.prod (GH-11359) --- Doc/library/math.rst | 12 ++ Doc/whatsnew/3.8.rst | 9 + Lib/test/test_math.py | 31 ++++ .../2018-12-29-21-59-03.bpo-35606.NjGjou.rst | 3 + Modules/clinic/mathmodule.c.h | 39 +++- Modules/mathmodule.c | 167 ++++++++++++++++++ 6 files changed, 260 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-29-21-59-03.bpo-35606.NjGjou.rst diff --git a/Doc/library/math.rst b/Doc/library/math.rst index 76226c282d5e68..7129525c788767 100644 --- a/Doc/library/math.rst +++ b/Doc/library/math.rst @@ -178,6 +178,18 @@ Number-theoretic and representation functions of *x* and are floats. +.. function:: prod(iterable, *, start=1) + + Calculate the product of all the elements in the input *iterable*. + The default *start* value for the product is ``1``. + + When the iterable is empty, return the start value. This function is + intended specifically for use with numeric values and may reject + non-numeric types. + + .. versionadded:: 3.8 + + .. function:: remainder(x, y) Return the IEEE 754-style remainder of *x* with respect to *y*. For diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index a3982b0dfe0931..a90bc274eb6bfa 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -171,6 +171,15 @@ json.tool Add option ``--json-lines`` to parse every input line as separate JSON object. (Contributed by Weipeng Hong in :issue:`31553`.) + +math +---- + +Added new function, :func:`math.prod`, as analogous function to :func:`sum` +that returns the product of a 'start' value (default: 1) times an iterable of +numbers. (Contributed by Pablo Galindo in :issue:`issue35606`) + + os.path ------- diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index f9b11f3f74e654..083759ca75e16b 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1724,6 +1724,37 @@ def test_fractions(self): self.assertAllClose(fraction_examples, rel_tol=1e-8) self.assertAllNotClose(fraction_examples, rel_tol=1e-9) + def test_prod(self): + prod = math.prod + self.assertEqual(prod([]), 1) + self.assertEqual(prod([], start=5), 5) + self.assertEqual(prod(list(range(2,8))), 5040) + self.assertEqual(prod(iter(list(range(2,8)))), 5040) + self.assertEqual(prod(range(1, 10), start=10), 3628800) + + self.assertEqual(prod([1, 2, 3, 4, 5]), 120) + self.assertEqual(prod([1.0, 2.0, 3.0, 4.0, 5.0]), 120.0) + self.assertEqual(prod([1, 2, 3, 4.0, 5.0]), 120.0) + self.assertEqual(prod([1.0, 2.0, 3.0, 4, 5]), 120.0) + + # Test overflow in fast-path for integers + self.assertEqual(prod([1, 1, 2**32, 1, 1]), 2**32) + # Test overflow in fast-path for floats + self.assertEqual(prod([1.0, 1.0, 2**32, 1, 1]), float(2**32)) + + self.assertRaises(TypeError, prod) + self.assertRaises(TypeError, prod, 42) + self.assertRaises(TypeError, prod, ['a', 'b', 'c']) + self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '') + self.assertRaises(TypeError, prod, [b'a', b'c'], b'') + values = [bytearray(b'a'), bytearray(b'b')] + self.assertRaises(TypeError, prod, values, bytearray(b'')) + self.assertRaises(TypeError, prod, [[1], [2], [3]]) + self.assertRaises(TypeError, prod, [{2:3}]) + self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3}) + self.assertRaises(TypeError, prod, [[1], [2], [3]], []) + with self.assertRaises(TypeError): + prod([10, 20], [30, 40]) # start is a keyword-only argument def test_main(): from doctest import DocFileSuite diff --git a/Misc/NEWS.d/next/Library/2018-12-29-21-59-03.bpo-35606.NjGjou.rst b/Misc/NEWS.d/next/Library/2018-12-29-21-59-03.bpo-35606.NjGjou.rst new file mode 100644 index 00000000000000..d70b0bcb5d48e6 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-29-21-59-03.bpo-35606.NjGjou.rst @@ -0,0 +1,3 @@ +Implement :func:`math.prod` as analogous function to :func:`sum` that +returns the product of a 'start' value (default: 1) times an iterable of +numbers. Patch by Pablo Galindo. diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index 82a4c4a0e7a403..b99a8deecea11e 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -556,4 +556,41 @@ math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject exit: return return_value; } -/*[clinic end generated code: output=0664f30046da09fe input=a9049054013a1b77]*/ + +PyDoc_STRVAR(math_prod__doc__, +"prod($module, iterable, /, *, start=1)\n" +"--\n" +"\n" +"Calculate the product of all the elements in the input iterable.\n" +"\n" +"The default start value for the product is 1.\n" +"\n" +"When the iterable is empty, return the start value. This function is\n" +"intended specifically for use with numeric values and may reject\n" +"non-numeric types."); + +#define MATH_PROD_METHODDEF \ + {"prod", (PyCFunction)(void(*)(void))math_prod, METH_FASTCALL|METH_KEYWORDS, math_prod__doc__}, + +static PyObject * +math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start); + +static PyObject * +math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"", "start", NULL}; + static _PyArg_Parser _parser = {"O|$O:prod", _keywords, 0}; + PyObject *iterable; + PyObject *start = NULL; + + if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, + &iterable, &start)) { + goto exit; + } + return_value = math_prod_impl(module, iterable, start); + +exit: + return return_value; +} +/*[clinic end generated code: output=20505690ca6fe402 input=a9049054013a1b77]*/ diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 83dab1269d631d..d2f8d5334736eb 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2494,6 +2494,172 @@ math_isclose_impl(PyObject *module, double a, double b, double rel_tol, } +/*[clinic input] +math.prod + + iterable: object + / + * + start: object(c_default="NULL") = 1 + +Calculate the product of all the elements in the input iterable. + +The default start value for the product is 1. + +When the iterable is empty, return the start value. This function is +intended specifically for use with numeric values and may reject +non-numeric types. +[clinic start generated code]*/ + +static PyObject * +math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start) +/*[clinic end generated code: output=36153bedac74a198 input=4c5ab0682782ed54]*/ +{ + PyObject *result = start; + PyObject *temp, *item, *iter; + + iter = PyObject_GetIter(iterable); + if (iter == NULL) { + return NULL; + } + + if (result == NULL) { + result = PyLong_FromLong(1); + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } else { + Py_INCREF(result); + } +#ifndef SLOW_PROD + /* Fast paths for integers keeping temporary products in C. + * Assumes all inputs are the same type. + * If the assumption fails, default to use PyObjects instead. + */ + if (PyLong_CheckExact(result)) { + int overflow; + long i_result = PyLong_AsLongAndOverflow(result, &overflow); + /* If this already overflowed, don't even enter the loop. */ + if (overflow == 0) { + Py_DECREF(result); + result = NULL; + } + /* Loop over all the items in the iterable until we finish, we overflow + * or we found a non integer element */ + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) { + return NULL; + } + return PyLong_FromLong(i_result); + } + if (PyLong_CheckExact(item)) { + long b = PyLong_AsLongAndOverflow(item, &overflow); + long x = i_result * b; + /* Continue if there is no overflow */ + if (overflow == 0 + && x < INT_MAX && x > INT_MIN + && !(b != 0 && x / i_result != b)) { + i_result = x; + Py_DECREF(item); + continue; + } + } + /* Either overflowed or is not an int. + * Restore real objects and process normally */ + result = PyLong_FromLong(i_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } + + /* Fast paths for floats keeping temporary products in C. + * Assumes all inputs are the same type. + * If the assumption fails, default to use PyObjects instead. + */ + if (PyFloat_CheckExact(result)) { + double f_result = PyFloat_AS_DOUBLE(result); + Py_DECREF(result); + result = NULL; + while(result == NULL) { + item = PyIter_Next(iter); + if (item == NULL) { + Py_DECREF(iter); + if (PyErr_Occurred()) { + return NULL; + } + return PyFloat_FromDouble(f_result); + } + if (PyFloat_CheckExact(item)) { + f_result *= PyFloat_AS_DOUBLE(item); + Py_DECREF(item); + continue; + } + if (PyLong_CheckExact(item)) { + long value; + int overflow; + value = PyLong_AsLongAndOverflow(item, &overflow); + if (!overflow) { + f_result *= (double)value; + Py_DECREF(item); + continue; + } + } + result = PyFloat_FromDouble(f_result); + if (result == NULL) { + Py_DECREF(item); + Py_DECREF(iter); + return NULL; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) { + Py_DECREF(iter); + return NULL; + } + } + } +#endif + /* Consume rest of the iterable (if any) that could not be handled + * by specialized functions above.*/ + for(;;) { + item = PyIter_Next(iter); + if (item == NULL) { + /* error, or end-of-sequence */ + if (PyErr_Occurred()) { + Py_DECREF(result); + result = NULL; + } + break; + } + temp = PyNumber_Multiply(result, item); + Py_DECREF(result); + Py_DECREF(item); + result = temp; + if (result == NULL) + break; + } + Py_DECREF(iter); + return result; +} + + static PyMethodDef math_methods[] = { {"acos", math_acos, METH_O, math_acos_doc}, {"acosh", math_acosh, METH_O, math_acosh_doc}, @@ -2541,6 +2707,7 @@ static PyMethodDef math_methods[] = { {"tan", math_tan, METH_O, math_tan_doc}, {"tanh", math_tanh, METH_O, math_tanh_doc}, MATH_TRUNC_METHODDEF + MATH_PROD_METHODDEF {NULL, NULL} /* sentinel */ }; From 2848d9d29914948621bce26bf0d9a89f2e19b97b Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Thu, 7 Feb 2019 03:03:11 -0800 Subject: [PATCH 0018/1727] bpo-35917: Test multiprocessing manager classes and shareable types (GH-11772) multiprocessing: provide unittests for manager classes and shareable types --- Lib/test/_test_multiprocessing.py | 246 ++++++++++++++++++ .../2019-02-06-18-06-16.bpo-35917.-Clv1L.rst | 3 + 2 files changed, 249 insertions(+) create mode 100644 Misc/NEWS.d/next/Tests/2019-02-06-18-06-16.bpo-35917.-Clv1L.rst diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 7341131231a4f0..2f839b952126a3 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -4706,6 +4706,252 @@ def is_alive(self): any(process.is_alive() for process in forked_processes)) +class TestSyncManagerTypes(unittest.TestCase): + """Test all the types which can be shared between a parent and a + child process by using a manager which acts as an intermediary + between them. + + In the following unit-tests the base type is created in the parent + process, the @classmethod represents the worker process and the + shared object is readable and editable between the two. + + # The child. + @classmethod + def _test_list(cls, obj): + assert obj[0] == 5 + assert obj.append(6) + + # The parent. + def test_list(self): + o = self.manager.list() + o.append(5) + self.run_worker(self._test_list, o) + assert o[1] == 6 + """ + manager_class = multiprocessing.managers.SyncManager + + def setUp(self): + self.manager = self.manager_class() + self.manager.start() + self.proc = None + + def tearDown(self): + if self.proc is not None and self.proc.is_alive(): + self.proc.terminate() + self.proc.join() + self.manager.shutdown() + + @classmethod + def setUpClass(cls): + support.reap_children() + + tearDownClass = setUpClass + + def wait_proc_exit(self): + # Only the manager process should be returned by active_children() + # but this can take a bit on slow machines, so wait a few seconds + # if there are other children too (see #17395). + join_process(self.proc) + start_time = time.monotonic() + t = 0.01 + while len(multiprocessing.active_children()) > 1: + time.sleep(t) + t *= 2 + dt = time.monotonic() - start_time + if dt >= 5.0: + test.support.environment_altered = True + print("Warning -- multiprocessing.Manager still has %s active " + "children after %s seconds" + % (multiprocessing.active_children(), dt), + file=sys.stderr) + break + + def run_worker(self, worker, obj): + self.proc = multiprocessing.Process(target=worker, args=(obj, )) + self.proc.daemon = True + self.proc.start() + self.wait_proc_exit() + self.assertEqual(self.proc.exitcode, 0) + + @classmethod + def _test_queue(cls, obj): + assert obj.qsize() == 2 + assert obj.full() + assert not obj.empty() + assert obj.get() == 5 + assert not obj.empty() + assert obj.get() == 6 + assert obj.empty() + + def test_queue(self, qname="Queue"): + o = getattr(self.manager, qname)(2) + o.put(5) + o.put(6) + self.run_worker(self._test_queue, o) + assert o.empty() + assert not o.full() + + def test_joinable_queue(self): + self.test_queue("JoinableQueue") + + @classmethod + def _test_event(cls, obj): + assert obj.is_set() + obj.wait() + obj.clear() + obj.wait(0.001) + + def test_event(self): + o = self.manager.Event() + o.set() + self.run_worker(self._test_event, o) + assert not o.is_set() + o.wait(0.001) + + @classmethod + def _test_lock(cls, obj): + obj.acquire() + + def test_lock(self, lname="Lock"): + o = getattr(self.manager, lname)() + self.run_worker(self._test_lock, o) + o.release() + self.assertRaises(RuntimeError, o.release) # already released + + @classmethod + def _test_rlock(cls, obj): + obj.acquire() + obj.release() + + def test_rlock(self, lname="Lock"): + o = getattr(self.manager, lname)() + self.run_worker(self._test_rlock, o) + + @classmethod + def _test_semaphore(cls, obj): + obj.acquire() + + def test_semaphore(self, sname="Semaphore"): + o = getattr(self.manager, sname)() + self.run_worker(self._test_semaphore, o) + o.release() + + def test_bounded_semaphore(self): + self.test_semaphore(sname="BoundedSemaphore") + + @classmethod + def _test_condition(cls, obj): + obj.acquire() + obj.release() + + def test_condition(self): + o = self.manager.Condition() + self.run_worker(self._test_condition, o) + + @classmethod + def _test_barrier(cls, obj): + assert obj.parties == 5 + obj.reset() + + def test_barrier(self): + o = self.manager.Barrier(5) + self.run_worker(self._test_barrier, o) + + @classmethod + def _test_pool(cls, obj): + # TODO: fix https://bugs.python.org/issue35919 + with obj: + pass + + def test_pool(self): + o = self.manager.Pool(processes=4) + self.run_worker(self._test_pool, o) + + @classmethod + def _test_list(cls, obj): + assert obj[0] == 5 + assert obj.count(5) == 1 + assert obj.index(5) == 0 + obj.sort() + obj.reverse() + for x in obj: + pass + assert len(obj) == 1 + assert obj.pop(0) == 5 + + def test_list(self): + o = self.manager.list() + o.append(5) + self.run_worker(self._test_list, o) + assert not o + self.assertEqual(len(o), 0) + + @classmethod + def _test_dict(cls, obj): + assert len(obj) == 1 + assert obj['foo'] == 5 + assert obj.get('foo') == 5 + # TODO: fix https://bugs.python.org/issue35918 + # assert obj.has_key('foo') + assert list(obj.items()) == [('foo', 5)] + assert list(obj.keys()) == ['foo'] + assert list(obj.values()) == [5] + assert obj.copy() == {'foo': 5} + assert obj.popitem() == ('foo', 5) + + def test_dict(self): + o = self.manager.dict() + o['foo'] = 5 + self.run_worker(self._test_dict, o) + assert not o + self.assertEqual(len(o), 0) + + @classmethod + def _test_value(cls, obj): + assert obj.value == 1 + assert obj.get() == 1 + obj.set(2) + + def test_value(self): + o = self.manager.Value('i', 1) + self.run_worker(self._test_value, o) + self.assertEqual(o.value, 2) + self.assertEqual(o.get(), 2) + + @classmethod + def _test_array(cls, obj): + assert obj[0] == 0 + assert obj[1] == 1 + assert len(obj) == 2 + assert list(obj) == [0, 1] + + def test_array(self): + o = self.manager.Array('i', [0, 1]) + self.run_worker(self._test_array, o) + + @classmethod + def _test_namespace(cls, obj): + assert obj.x == 0 + assert obj.y == 1 + + def test_namespace(self): + o = self.manager.Namespace() + o.x = 0 + o.y = 1 + self.run_worker(self._test_namespace, o) + + +try: + import multiprocessing.shared_memory +except ImportError: + @unittest.skip("SharedMemoryManager not available on this platform") + class TestSharedMemoryManagerTypes(TestSyncManagerTypes): + pass +else: + class TestSharedMemoryManagerTypes(TestSyncManagerTypes): + """Same as above but by using SharedMemoryManager.""" + manager_class = multiprocessing.shared_memory.SharedMemoryManager + class MiscTestCase(unittest.TestCase): def test__all__(self): diff --git a/Misc/NEWS.d/next/Tests/2019-02-06-18-06-16.bpo-35917.-Clv1L.rst b/Misc/NEWS.d/next/Tests/2019-02-06-18-06-16.bpo-35917.-Clv1L.rst new file mode 100644 index 00000000000000..546d47e39d872e --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2019-02-06-18-06-16.bpo-35917.-Clv1L.rst @@ -0,0 +1,3 @@ +multiprocessing: provide unit tests for SyncManager and SharedMemoryManager +classes + all the shareable types which are supposed to be supported by +them. (patch by Giampaolo Rodola) From f289084c83190cc72db4a70c58f007ec62e75247 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 7 Feb 2019 08:22:45 -0500 Subject: [PATCH 0019/1727] bpo-24209: In http.server script, rely on getaddrinfo to bind to preferred address based on the bind parameter. (#11767) In http.server script, rely on getaddrinfo to bind to preferred address based on the bind parameter. As a result, now IPv6 is used as the default (including IPv4 on dual-stack systems). Enhanced tests. --- Lib/http/server.py | 30 +++++--- Lib/test/test_httpservers.py | 68 +++++++++++++++---- .../2019-02-06-01-40-55.bpo-24209.awtwPD.rst | 1 + 3 files changed, 76 insertions(+), 23 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-02-06-01-40-55.bpo-24209.awtwPD.rst diff --git a/Lib/http/server.py b/Lib/http/server.py index 29c720ea7ea87e..b247675ec45e81 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -1224,24 +1224,34 @@ def run_cgi(self): self.log_message("CGI script exited OK") +def _get_best_family(*address): + infos = socket.getaddrinfo( + *address, + type=socket.SOCK_STREAM, + flags=socket.AI_PASSIVE, + ) + family, type, proto, canonname, sockaddr = next(iter(infos)) + return family, sockaddr + + def test(HandlerClass=BaseHTTPRequestHandler, ServerClass=ThreadingHTTPServer, - protocol="HTTP/1.0", port=8000, bind=""): + protocol="HTTP/1.0", port=8000, bind=None): """Test the HTTP request handler class. This runs an HTTP server on port 8000 (or the port argument). """ - server_address = (bind, port) - - if ':' in bind: - ServerClass.address_family = socket.AF_INET6 + ServerClass.address_family, addr = _get_best_family(bind, port) HandlerClass.protocol_version = protocol - with ServerClass(server_address, HandlerClass) as httpd: - sa = httpd.socket.getsockname() - serve_message = "Serving HTTP on {host} port {port} (http://{host}:{port}/) ..." - print(serve_message.format(host=sa[0], port=sa[1])) + with ServerClass(addr, HandlerClass) as httpd: + host, port = httpd.socket.getsockname()[:2] + url_host = f'[{host}]' if ':' in host else host + print( + f"Serving HTTP on {host} port {port} " + f"(http://{url_host}:{port}/) ..." + ) try: httpd.serve_forever() except KeyboardInterrupt: @@ -1254,7 +1264,7 @@ def test(HandlerClass=BaseHTTPRequestHandler, parser = argparse.ArgumentParser() parser.add_argument('--cgi', action='store_true', help='Run as CGI Server') - parser.add_argument('--bind', '-b', default='', metavar='ADDRESS', + parser.add_argument('--bind', '-b', metavar='ADDRESS', help='Specify alternate bind address ' '[default: all interfaces]') parser.add_argument('--directory', '-d', default=os.getcwd(), diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 3d8e0af8b45c27..8357ee9145d7e5 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -1118,21 +1118,63 @@ def test_all(self): class ScriptTestCase(unittest.TestCase): + + def mock_server_class(self): + return mock.MagicMock( + return_value=mock.MagicMock( + __enter__=mock.MagicMock( + return_value=mock.MagicMock( + socket=mock.MagicMock( + getsockname=lambda: ('', 0), + ), + ), + ), + ), + ) + + @mock.patch('builtins.print') + def test_server_test_unspec(self, _): + mock_server = self.mock_server_class() + server.test(ServerClass=mock_server, bind=None) + self.assertIn( + mock_server.address_family, + (socket.AF_INET6, socket.AF_INET), + ) + + @mock.patch('builtins.print') + def test_server_test_localhost(self, _): + mock_server = self.mock_server_class() + server.test(ServerClass=mock_server, bind="localhost") + self.assertIn( + mock_server.address_family, + (socket.AF_INET6, socket.AF_INET), + ) + + ipv6_addrs = ( + "::", + "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "::1", + ) + + ipv4_addrs = ( + "0.0.0.0", + "8.8.8.8", + "127.0.0.1", + ) + @mock.patch('builtins.print') def test_server_test_ipv6(self, _): - mock_server = mock.MagicMock() - server.test(ServerClass=mock_server, bind="::") - self.assertEqual(mock_server.address_family, socket.AF_INET6) - - mock_server.reset_mock() - server.test(ServerClass=mock_server, - bind="2001:0db8:85a3:0000:0000:8a2e:0370:7334") - self.assertEqual(mock_server.address_family, socket.AF_INET6) - - mock_server.reset_mock() - server.test(ServerClass=mock_server, - bind="::1") - self.assertEqual(mock_server.address_family, socket.AF_INET6) + for bind in self.ipv6_addrs: + mock_server = self.mock_server_class() + server.test(ServerClass=mock_server, bind=bind) + self.assertEqual(mock_server.address_family, socket.AF_INET6) + + @mock.patch('builtins.print') + def test_server_test_ipv4(self, _): + for bind in self.ipv4_addrs: + mock_server = self.mock_server_class() + server.test(ServerClass=mock_server, bind=bind) + self.assertEqual(mock_server.address_family, socket.AF_INET) def test_main(verbose=None): diff --git a/Misc/NEWS.d/next/Library/2019-02-06-01-40-55.bpo-24209.awtwPD.rst b/Misc/NEWS.d/next/Library/2019-02-06-01-40-55.bpo-24209.awtwPD.rst new file mode 100644 index 00000000000000..4d555fd4125a49 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-06-01-40-55.bpo-24209.awtwPD.rst @@ -0,0 +1 @@ +In http.server script, rely on getaddrinfo to bind to preferred address based on the bind parameter. Now default bind or binding to a name may bind to IPv6 or dual-stack, depending on the environment. \ No newline at end of file From df8d2cde63c865446468351f8f648e1c7bd45109 Mon Sep 17 00:00:00 2001 From: Pierre Glaser Date: Thu, 7 Feb 2019 20:36:48 +0100 Subject: [PATCH 0020/1727] bpo-35911: add cell constructor (GH-11771) Add a cell constructor, expose the cell type in the types module. --- Doc/library/types.rst | 8 ++++ Doc/reference/datamodel.rst | 4 +- Lib/test/test_funcattrs.py | 9 ++++ Lib/types.py | 7 ++++ .../2019-02-06-17-50-59.bpo-35911.oiWE8.rst | 3 ++ Objects/cellobject.c | 42 ++++++++++++++++++- 6 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-02-06-17-50-59.bpo-35911.oiWE8.rst diff --git a/Doc/library/types.rst b/Doc/library/types.rst index b19aa0273ef52c..07c3a2e7f68276 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -136,6 +136,14 @@ Standard names are defined for the following types: The type for code objects such as returned by :func:`compile`. +.. data:: CellType + + The type for cell objects: such objects are used as containers for + a function's free variables. + + .. versionadded:: 3.8 + + .. data:: MethodType The type of methods of user-defined class instances. diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 83e1d239b34a75..9961aee14e0652 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -539,7 +539,9 @@ Callable types the value of the cell, as well as set the value. Additional information about a function's definition can be retrieved from its - code object; see the description of internal types below. + code object; see the description of internal types below. The + :data:`cell ` type can be accessed in the :mod:`types` + module. Instance methods .. index:: diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 35fd657ec0ba56..11d68cc75e2089 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -83,6 +83,15 @@ def f(): print(a) self.assertEqual(c[0].__class__.__name__, "cell") self.cannot_set_attr(f, "__closure__", c, AttributeError) + def test_cell_new(self): + cell_obj = types.CellType(1) + self.assertEqual(cell_obj.cell_contents, 1) + + cell_obj = types.CellType() + msg = "shouldn't be able to read an empty cell" + with self.assertRaises(ValueError, msg=msg): + cell_obj.cell_contents + def test_empty_cell(self): def f(): print(a) try: diff --git a/Lib/types.py b/Lib/types.py index ce4652f3718976..53b588da75696b 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -15,6 +15,13 @@ def _f(): pass MappingProxyType = type(type.__dict__) SimpleNamespace = type(sys.implementation) +def _cell_factory(): + a = 1 + def f(): + nonlocal a + return f.__closure__[0] +CellType = type(_cell_factory()) + def _g(): yield 1 GeneratorType = type(_g()) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-02-06-17-50-59.bpo-35911.oiWE8.rst b/Misc/NEWS.d/next/Core and Builtins/2019-02-06-17-50-59.bpo-35911.oiWE8.rst new file mode 100644 index 00000000000000..458ccb49fa4121 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-02-06-17-50-59.bpo-35911.oiWE8.rst @@ -0,0 +1,3 @@ +Enable the creation of cell objects by adding a ``cell.__new__`` method, and +expose the type ``cell`` in ``Lib/types.py`` under the name CellType. Patch by +Pierre Glaser. diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 86bebb9604a579..4e359f889fdc81 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -20,6 +20,37 @@ PyCell_New(PyObject *obj) return (PyObject *)op; } +PyDoc_STRVAR(cell_new_doc, +"cell([contents])\n" +"--\n" +"\n" +"Create a new cell object.\n" +"\n" +" contents\n" +" the contents of the cell. If not specified, the cell will be empty,\n" +" and \n further attempts to access its cell_contents attribute will\n" +" raise a ValueError."); + + +static PyObject * +cell_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + PyObject *obj = NULL; + + if (!_PyArg_NoKeywords("cell", kwargs)) { + goto exit; + } + /* min = 0: we allow the cell to be empty */ + if (!PyArg_UnpackTuple(args, "cell", 0, 1, &obj)) { + goto exit; + } + return_value = PyCell_New(obj); + +exit: + return return_value; +} + PyObject * PyCell_Get(PyObject *op) { @@ -146,7 +177,7 @@ PyTypeObject PyCell_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - 0, /* tp_doc */ + cell_new_doc, /* tp_doc */ (traverseproc)cell_traverse, /* tp_traverse */ (inquiry)cell_clear, /* tp_clear */ cell_richcompare, /* tp_richcompare */ @@ -156,4 +187,13 @@ PyTypeObject PyCell_Type = { 0, /* tp_methods */ 0, /* tp_members */ cell_getsetlist, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)cell_new, /* tp_new */ + 0, /* tp_free */ }; From 96d37dbcd23e65a7a57819aeced9034296ef747e Mon Sep 17 00:00:00 2001 From: Fish Date: Thu, 7 Feb 2019 14:51:59 -0500 Subject: [PATCH 0021/1727] bpo-35615: Fix crashes when copying a Weak{Key,Value}Dictionary. (GH-11384) Protect dict iterations by wrapping them with _IterationGuard in the following methods: - WeakValueDictionary.copy() - WeakValueDictionary.__deepcopy__() - WeakKeyDictionary.copy() - WeakKeyDictionary.__deepcopy__() --- Lib/test/test_weakref.py | 82 +++++++++++++++++++ Lib/weakref.py | 36 ++++---- .../2018-12-30-20-00-05.bpo-35615.Uz1SVh.rst | 3 + 3 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-30-20-00-05.bpo-35615.Uz1SVh.rst diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py index 9fa0bbd7808766..1fac08dafc7d98 100644 --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -8,6 +8,7 @@ import copy import threading import time +import random from test import support from test.support import script_helper @@ -1688,6 +1689,87 @@ def test_threaded_weak_valued_consistency(self): self.assertEqual(len(d), 1) o = None # lose ref + def check_threaded_weak_dict_copy(self, type_, deepcopy): + # `type_` should be either WeakKeyDictionary or WeakValueDictionary. + # `deepcopy` should be either True or False. + exc = [] + + class DummyKey: + def __init__(self, ctr): + self.ctr = ctr + + class DummyValue: + def __init__(self, ctr): + self.ctr = ctr + + def dict_copy(d, exc): + try: + if deepcopy is True: + _ = copy.deepcopy(d) + else: + _ = d.copy() + except Exception as ex: + exc.append(ex) + + def pop_and_collect(lst): + gc_ctr = 0 + while lst: + i = random.randint(0, len(lst) - 1) + gc_ctr += 1 + lst.pop(i) + if gc_ctr % 10000 == 0: + gc.collect() # just in case + + self.assertIn(type_, (weakref.WeakKeyDictionary, weakref.WeakValueDictionary)) + + d = type_() + keys = [] + values = [] + # Initialize d with many entries + for i in range(70000): + k, v = DummyKey(i), DummyValue(i) + keys.append(k) + values.append(v) + d[k] = v + del k + del v + + t_copy = threading.Thread(target=dict_copy, args=(d, exc,)) + if type_ is weakref.WeakKeyDictionary: + t_collect = threading.Thread(target=pop_and_collect, args=(keys,)) + else: # weakref.WeakValueDictionary + t_collect = threading.Thread(target=pop_and_collect, args=(values,)) + + t_copy.start() + t_collect.start() + + t_copy.join() + t_collect.join() + + # Test exceptions + if exc: + raise exc[0] + + def test_threaded_weak_key_dict_copy(self): + # Issue #35615: Weakref keys or values getting GC'ed during dict + # copying should not result in a crash. + self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, False) + + def test_threaded_weak_key_dict_deepcopy(self): + # Issue #35615: Weakref keys or values getting GC'ed during dict + # copying should not result in a crash. + self.check_threaded_weak_dict_copy(weakref.WeakKeyDictionary, True) + + def test_threaded_weak_value_dict_copy(self): + # Issue #35615: Weakref keys or values getting GC'ed during dict + # copying should not result in a crash. + self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, False) + + def test_threaded_weak_value_dict_deepcopy(self): + # Issue #35615: Weakref keys or values getting GC'ed during dict + # copying should not result in a crash. + self.check_threaded_weak_dict_copy(weakref.WeakValueDictionary, True) + from test import mapping_tests diff --git a/Lib/weakref.py b/Lib/weakref.py index 99de2eab741439..753f07291e20e8 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -171,10 +171,11 @@ def copy(self): if self._pending_removals: self._commit_removals() new = WeakValueDictionary() - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[key] = o + with _IterationGuard(self): + for key, wr in self.data.items(): + o = wr() + if o is not None: + new[key] = o return new __copy__ = copy @@ -184,10 +185,11 @@ def __deepcopy__(self, memo): if self._pending_removals: self._commit_removals() new = self.__class__() - for key, wr in self.data.items(): - o = wr() - if o is not None: - new[deepcopy(key, memo)] = o + with _IterationGuard(self): + for key, wr in self.data.items(): + o = wr() + if o is not None: + new[deepcopy(key, memo)] = o return new def get(self, key, default=None): @@ -408,10 +410,11 @@ def __setitem__(self, key, value): def copy(self): new = WeakKeyDictionary() - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = value + with _IterationGuard(self): + for key, value in self.data.items(): + o = key() + if o is not None: + new[o] = value return new __copy__ = copy @@ -419,10 +422,11 @@ def copy(self): def __deepcopy__(self, memo): from copy import deepcopy new = self.__class__() - for key, value in self.data.items(): - o = key() - if o is not None: - new[o] = deepcopy(value, memo) + with _IterationGuard(self): + for key, value in self.data.items(): + o = key() + if o is not None: + new[o] = deepcopy(value, memo) return new def get(self, key, default=None): diff --git a/Misc/NEWS.d/next/Library/2018-12-30-20-00-05.bpo-35615.Uz1SVh.rst b/Misc/NEWS.d/next/Library/2018-12-30-20-00-05.bpo-35615.Uz1SVh.rst new file mode 100644 index 00000000000000..4aff8f7f30c8fe --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-12-30-20-00-05.bpo-35615.Uz1SVh.rst @@ -0,0 +1,3 @@ +:mod:`weakref`: Fix a RuntimeError when copying a WeakKeyDictionary or a +WeakValueDictionary, due to some keys or values disappearing while +iterating. From d9503c307a8b6a7b73f6344183602ffb014d3356 Mon Sep 17 00:00:00 2001 From: Paul Ganssle Date: Fri, 8 Feb 2019 11:02:00 -0500 Subject: [PATCH 0022/1727] Add What's New entry for date subclass behavior (#11790) This was a backwards incompatible change and should be clearly noted. Related bugs: bpo-32417: https://bugs.python.org/issue32417 bpo-35364: https://bugs.python.org/issue35364 --- Doc/whatsnew/3.8.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index a90bc274eb6bfa..740c608418ab20 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -115,6 +115,14 @@ Other Language Changes a :exc:`SyntaxWarning` instead. (Contributed by Serhiy Storchaka in :issue:`32912`.) +* Arithmetic operations between subclasses of :class:`datetime.date` or + :class:`datetime.datetime` and :class:`datetime.timedelta` objects now return + an instance of the subclass, rather than the base class. This also affects + the return type of operations whose implementation (directly or indirectly) + uses :class:`datetime.timedelta` arithmetic, such as + :meth:`datetime.datetime.astimezone`. + (Contributed by Paul Ganssle in :issue:`32417`.) + New Modules =========== From 64360ada0f6123a051e9dc6cd04f030ec1322e46 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 8 Feb 2019 10:37:39 -0800 Subject: [PATCH 0023/1727] Complete and neaten-up namedtuple's replacement of builtin function lookups with derefs (GH-11794) --- Lib/collections/__init__.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py index aee79b93160249..d88c4aaaee8921 100644 --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -390,7 +390,7 @@ def namedtuple(typename, field_names, *, rename=False, defaults=None, module=Non arg_list = repr(field_names).replace("'", "")[1:-1] repr_fmt = '(' + ', '.join(f'{name}=%r' for name in field_names) + ')' tuple_new = tuple.__new__ - _len = len + _dict, _tuple, _len, _map, _zip = dict, tuple, len, map, zip # Create all the named tuple methods to be added to the class namespace @@ -414,7 +414,7 @@ def _make(cls, iterable): 'or iterable') def _replace(_self, **kwds): - result = _self._make(map(kwds.pop, field_names, _self)) + result = _self._make(_map(kwds.pop, field_names, _self)) if kwds: raise ValueError(f'Got unexpected field names: {list(kwds)!r}') return result @@ -426,18 +426,15 @@ def __repr__(self): 'Return a nicely formatted representation string' return self.__class__.__name__ + repr_fmt % self - _dict, _zip = dict, zip - def _asdict(self): 'Return a new dict which maps field names to their values.' return _dict(_zip(self._fields, self)) def __getnewargs__(self): 'Return self as a plain tuple. Used by copy and pickle.' - return tuple(self) + return _tuple(self) # Modify function metadata to help with introspection and debugging - for method in (__new__, _make.__func__, _replace, __repr__, _asdict, __getnewargs__): method.__qualname__ = f'{typename}.{method.__name__}' From 5741c45acf9b0ce22ff0dbf56322fe0ff16cfcfc Mon Sep 17 00:00:00 2001 From: Neil Schemenauer Date: Fri, 8 Feb 2019 10:48:46 -0800 Subject: [PATCH 0024/1727] bpo-35903: Use autoconfig to probe for shm_open() and shm_unlink(). (#11765) Use autoconfig to probe for shm_open() and shm_unlink(). Set SHM_NEEDS_LIBRT if we must link with librt to get the shm_* functions. Change setup.py to use the autoconfig defines. These changes should make it more likely that _multiprocessing/posixshmem.c gets built correctly on different platforms. --- configure | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ configure.ac | 24 ++++++++++++ pyconfig.h.in | 12 ++++++ setup.py | 7 ++-- 4 files changed, 142 insertions(+), 3 deletions(-) diff --git a/configure b/configure index ebd9f904b09afb..b78a7b22610019 100755 --- a/configure +++ b/configure @@ -16862,6 +16862,108 @@ $as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h fi +# checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c +# shm_* may only be available if linking against librt +save_LIBS="$LIBS" +save_includes_default="$ac_includes_default" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing shm_open" >&5 +$as_echo_n "checking for library containing shm_open... " >&6; } +if ${ac_cv_search_shm_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shm_open (); +int +main () +{ +return shm_open (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_shm_open=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_shm_open+:} false; then : + break +fi +done +if ${ac_cv_search_shm_open+:} false; then : + +else + ac_cv_search_shm_open=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_shm_open" >&5 +$as_echo "$ac_cv_search_shm_open" >&6; } +ac_res=$ac_cv_search_shm_open +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +if test "$ac_cv_search_shm_open" = "-lrt"; then + +$as_echo "#define SHM_NEEDS_LIBRT 1" >>confdefs.h + +fi +for ac_header in sys/mman.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mman_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_MMAN_H 1 +_ACEOF + +fi + +done + +# temporarily override ac_includes_default for AC_CHECK_FUNCS below +ac_includes_default="\ +${ac_includes_default} +#ifndef __cplusplus +# ifdef HAVE_SYS_MMAN_H +# include +# endif +#endif +" +for ac_func in shm_open shm_unlink +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +# we don't want to link with librt always, restore LIBS +LIBS="$save_LIBS" +ac_includes_default="$save_includes_default" + # Check for usable OpenSSL found=false diff --git a/configure.ac b/configure.ac index 721edb015ea36f..eeedfedd236f0b 100644 --- a/configure.ac +++ b/configure.ac @@ -5443,6 +5443,30 @@ if test "$have_getrandom" = yes; then [Define to 1 if the getrandom() function is available]) fi +# checks for POSIX shared memory, used by Modules/_multiprocessing/posixshmem.c +# shm_* may only be available if linking against librt +save_LIBS="$LIBS" +save_includes_default="$ac_includes_default" +AC_SEARCH_LIBS(shm_open, rt) +if test "$ac_cv_search_shm_open" = "-lrt"; then + AC_DEFINE(SHM_NEEDS_LIBRT, 1, + [Define to 1 if you must link with -lrt for shm_open().]) +fi +AC_CHECK_HEADERS(sys/mman.h) +# temporarily override ac_includes_default for AC_CHECK_FUNCS below +ac_includes_default="\ +${ac_includes_default} +#ifndef __cplusplus +# ifdef HAVE_SYS_MMAN_H +# include +# endif +#endif +" +AC_CHECK_FUNCS([shm_open shm_unlink]) +# we don't want to link with librt always, restore LIBS +LIBS="$save_LIBS" +ac_includes_default="$save_includes_default" + # Check for usable OpenSSL AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no]) diff --git a/pyconfig.h.in b/pyconfig.h.in index a2a56230fc13be..ab9e9e10f7ce91 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -144,6 +144,18 @@ /* Define to 1 if you have the `copysign' function. */ #undef HAVE_COPYSIGN +/* Define to 1 if you must link with -lrt for shm_open(). */ +#undef SHM_NEEDS_LIBRT + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the shm_open syscall */ +#undef HAVE_SHM_OPEN + +/* Define to 1 if you have the shm_unlink syscall */ +#undef HAVE_SHM_UNLINK + /* Define to 1 if you have the header file. */ #undef HAVE_CRYPT_H diff --git a/setup.py b/setup.py index d54bbe0f43ed8d..4a01a8f45ac4b8 100644 --- a/setup.py +++ b/setup.py @@ -1592,12 +1592,13 @@ class db_found(Exception): pass if (sysconfig.get_config_var('HAVE_SEM_OPEN') and not sysconfig.get_config_var('POSIX_SEMAPHORES_NOT_ENABLED')): multiprocessing_srcs.append('_multiprocessing/semaphore.c') - if (self.compiler.find_library_file(lib_dirs, 'rt') or - host_platform != 'cygwin'): + if (sysconfig.get_config_var('HAVE_SHM_OPEN') and + sysconfig.get_config_var('HAVE_SHM_UNLINK')): posixshmem_srcs = [ '_multiprocessing/posixshmem.c', ] libs = [] - if self.compiler.find_library_file(lib_dirs, 'rt'): + if sysconfig.get_config_var('SHM_NEEDS_LIBRT'): + # need to link with librt to get shm_open() libs.append('rt') exts.append( Extension('_posixshmem', posixshmem_srcs, define_macros={}, From 7ab3d1573c123fdd582a239d01f8475651df38f2 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Fri, 8 Feb 2019 15:09:26 -0600 Subject: [PATCH 0025/1727] Rework tuple hash tests. (GH-10161) Add tooling that will useful in future updates, paying particular attention to difficult cases where only the upper bits on the input vary. --- Lib/test/support/__init__.py | 41 ++++ Lib/test/test_tuple.py | 351 ++++++++++++++++++++++++++--------- 2 files changed, 308 insertions(+), 84 deletions(-) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 697182ea775f04..436f648a979c0f 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -2944,3 +2944,44 @@ def __fspath__(self): def maybe_get_event_loop_policy(): """Return the global event loop policy if one is set, else return None.""" return asyncio.events._event_loop_policy + +# Helpers for testing hashing. +NHASHBITS = sys.hash_info.width # number of bits in hash() result +assert NHASHBITS in (32, 64) + +# Return mean and sdev of number of collisions when tossing nballs balls +# uniformly at random into nbins bins. By definition, the number of +# collisions is the number of balls minus the number of occupied bins at +# the end. +def collision_stats(nbins, nballs): + n, k = nbins, nballs + # prob a bin empty after k trials = (1 - 1/n)**k + # mean # empty is then n * (1 - 1/n)**k + # so mean # occupied is n - n * (1 - 1/n)**k + # so collisions = k - (n - n*(1 - 1/n)**k) + # + # For the variance: + # n*(n-1)*(1-2/n)**k + meanempty - meanempty**2 = + # n*(n-1)*(1-2/n)**k + meanempty * (1 - meanempty) + # + # Massive cancellation occurs, and, e.g., for a 64-bit hash code + # 1-1/2**64 rounds uselessly to 1.0. Rather than make heroic (and + # error-prone) efforts to rework the naive formulas to avoid those, + # we use the `decimal` module to get plenty of extra precision. + # + # Note: the exact values are straightforward to compute with + # rationals, but in context that's unbearably slow, requiring + # multi-million bit arithmetic. + import decimal + with decimal.localcontext() as ctx: + bits = n.bit_length() * 2 # bits in n**2 + # At least that many bits will likely cancel out. + # Use that many decimal digits instead. + ctx.prec = max(bits, 30) + dn = decimal.Decimal(n) + p1empty = ((dn - 1) / dn) ** k + meanempty = n * p1empty + occupied = n - meanempty + collisions = k - occupied + var = dn*(dn-1)*((dn-2)/dn)**k + meanempty * (1 - meanempty) + return float(collisions), float(var.sqrt()) diff --git a/Lib/test/test_tuple.py b/Lib/test/test_tuple.py index 929f85316438fb..ca46d0b5a64539 100644 --- a/Lib/test/test_tuple.py +++ b/Lib/test/test_tuple.py @@ -4,6 +4,17 @@ import gc import pickle +# For tuple hashes, we normally only run a test to ensure that we get +# the same results across platforms in a handful of cases. If that's +# so, there's no real point to running more. Set RUN_ALL_HASH_TESTS to +# run more anyway. That's usually of real interest only when analyzing, +# or changing, the hash algorithm. In which case it's usually also +# most useful to set JUST_SHOW_HASH_RESULTS, to see all the results +# instead of wrestling with test "failures". See the bottom of the +# file for extensive notes on what we're testing here and why. +RUN_ALL_HASH_TESTS = False +JUST_SHOW_HASH_RESULTS = False # if RUN_ALL_HASH_TESTS, just display + class TupleTest(seq_tests.CommonTest): type2test = tuple @@ -62,104 +73,183 @@ def f(): yield i self.assertEqual(list(tuple(f())), list(range(1000))) + # We expect tuples whose base components have deterministic hashes to + # have deterministic hashes too - and, indeed, the same hashes across + # platforms with hash codes of the same bit width. + def test_hash_exact(self): + def check_one_exact(t, e32, e64): + got = hash(t) + expected = e32 if support.NHASHBITS == 32 else e64 + if got != expected: + msg = f"FAIL hash({t!r}) == {got} != {expected}" + self.fail(msg) + + check_one_exact((), 750394483, 5740354900026072187) + check_one_exact((0,), 1214856301, -8753497827991233192) + check_one_exact((0, 0), -168982784, -8458139203682520985) + check_one_exact((0.5,), 2077348973, -408149959306781352) + check_one_exact((0.5, (), (-2, 3, (4, 6))), 714642271, + -1845940830829704396) + # Various tests for hashing of tuples to check that we get few collisions. + # Does something only if RUN_ALL_HASH_TESTS is true. # - # Earlier versions of the tuple hash algorithm had collisions + # Earlier versions of the tuple hash algorithm had massive collisions # reported at: # - https://bugs.python.org/issue942952 # - https://bugs.python.org/issue34751 - # - # Notes: - # - The hash of tuples is deterministic: if the test passes once on a given - # system, it will always pass. So the probabilities mentioned in the - # test_hash functions below should be interpreted assuming that the - # hashes are random. - # - Due to the structure in the testsuite inputs, collisions are not - # independent. For example, if hash((a,b)) == hash((c,d)), then also - # hash((a,b,x)) == hash((c,d,x)). But the quoted probabilities assume - # independence anyway. - # - We limit the hash to 32 bits in the tests to have a good test on - # 64-bit systems too. Furthermore, this is also a sanity check that the - # lower 32 bits of a 64-bit hash are sufficiently random too. - def test_hash1(self): - # Check for hash collisions between small integers in range(50) and - # certain tuples and nested tuples of such integers. - N=50 + def test_hash_optional(self): + from itertools import product + + if not RUN_ALL_HASH_TESTS: + return + + # If specified, `expected` is a 2-tuple of expected + # (number_of_collisions, pileup) values, and the test fails if + # those aren't the values we get. Also if specified, the test + # fails if z > `zlimit`. + def tryone_inner(tag, nbins, hashes, expected=None, zlimit=None): + from collections import Counter + + nballs = len(hashes) + mean, sdev = support.collision_stats(nbins, nballs) + c = Counter(hashes) + collisions = nballs - len(c) + z = (collisions - mean) / sdev + pileup = max(c.values()) - 1 + del c + got = (collisions, pileup) + failed = False + prefix = "" + if zlimit is not None and z > zlimit: + failed = True + prefix = f"FAIL z > {zlimit}; " + if expected is not None and got != expected: + failed = True + prefix += f"FAIL {got} != {expected}; " + if failed or JUST_SHOW_HASH_RESULTS: + msg = f"{prefix}{tag}; pileup {pileup:,} mean {mean:.1f} " + msg += f"coll {collisions:,} z {z:+.1f}" + if JUST_SHOW_HASH_RESULTS: + import sys + print(msg, file=sys.__stdout__) + else: + self.fail(msg) + + def tryone(tag, xs, + native32=None, native64=None, hi32=None, lo32=None, + zlimit=None): + NHASHBITS = support.NHASHBITS + hashes = list(map(hash, xs)) + tryone_inner(tag + f"; {NHASHBITS}-bit hash codes", + 1 << NHASHBITS, + hashes, + native32 if NHASHBITS == 32 else native64, + zlimit) + + if NHASHBITS > 32: + shift = NHASHBITS - 32 + tryone_inner(tag + "; 32-bit upper hash codes", + 1 << 32, + [h >> shift for h in hashes], + hi32, + zlimit) + + mask = (1 << 32) - 1 + tryone_inner(tag + "; 32-bit lower hash codes", + 1 << 32, + [h & mask for h in hashes], + lo32, + zlimit) + + # Tuples of smallish positive integers are common - nice if we + # get "better than random" for these. + tryone("range(100) by 3", list(product(range(100), repeat=3)), + (0, 0), (0, 0), (4, 1), (0, 0)) + + # A previous hash had systematic problems when mixing integers of + # similar magnitude but opposite sign, obscurely related to that + # j ^ -2 == -j when j is odd. + cands = list(range(-10, -1)) + list(range(9)) + + # Note: -1 is omitted because hash(-1) == hash(-2) == -2, and + # there's nothing the tuple hash can do to avoid collisions + # inherited from collisions in the tuple components' hashes. + tryone("-10 .. 8 by 4", list(product(cands, repeat=4)), + (0, 0), (0, 0), (0, 0), (0, 0)) + del cands + + # The hashes here are a weird mix of values where all the + # variation is in the lowest bits and across a single high-order + # bit - the middle bits are all zeroes. A decent hash has to + # both propagate low bits to the left and high bits to the + # right. This is also complicated a bit in that there are + # collisions among the hashes of the integers in L alone. + L = [n << 60 for n in range(100)] + tryone("0..99 << 60 by 3", list(product(L, repeat=3)), + (0, 0), (0, 0), (0, 0), (324, 1)) + del L + + # Used to suffer a massive number of collisions. + tryone("[-3, 3] by 18", list(product([-3, 3], repeat=18)), + (7, 1), (0, 0), (7, 1), (6, 1)) + + # And even worse. hash(0.5) has only a single bit set, at the + # high end. A decent hash needs to propagate high bits right. + tryone("[0, 0.5] by 18", list(product([0, 0.5], repeat=18)), + (5, 1), (0, 0), (9, 1), (12, 1)) + + # Hashes of ints and floats are the same across platforms. + # String hashes vary even on a single platform across runs, due + # to hash randomization for strings. So we can't say exactly + # what this should do. Instead we insist that the # of + # collisions is no more than 4 sdevs above the theoretically + # random mean. Even if the tuple hash can't achieve that on its + # own, the string hash is trying to be decently pseudo-random + # (in all bit positions) on _its_ own. We can at least test + # that the tuple hash doesn't systematically ruin that. + tryone("4-char tuples", + list(product("abcdefghijklmnopqrstuvwxyz", repeat=4)), + zlimit=4.0) + + # The "old tuple test". See https://bugs.python.org/issue942952. + # Ensures, for example, that the hash: + # is non-commutative + # spreads closely spaced values + # doesn't exhibit cancellation in tuples like (x,(x,y)) + N = 50 base = list(range(N)) - xp = [(i, j) for i in base for j in base] - inps = base + [(i, j) for i in base for j in xp] + \ - [(i, j) for i in xp for j in base] + xp + list(zip(base)) - self.assertEqual(len(inps), 252600) - hashes = set(hash(x) % 2**32 for x in inps) - collisions = len(inps) - len(hashes) - - # For a pure random 32-bit hash and N = 252,600 test items, the - # expected number of collisions equals - # - # 2**(-32) * N(N-1)/2 = 7.4 - # - # We allow up to 15 collisions, which suffices to make the test - # pass with 99.5% confidence. - self.assertLessEqual(collisions, 15) - - def test_hash2(self): - # Check for hash collisions between small integers (positive and - # negative), tuples and nested tuples of such integers. - - # All numbers in the interval [-n, ..., n] except -1 because - # hash(-1) == hash(-2). + xp = list(product(base, repeat=2)) + inps = base + list(product(base, xp)) + \ + list(product(xp, base)) + xp + list(zip(base)) + tryone("old tuple test", inps, + (2, 1), (0, 0), (52, 49), (7, 1)) + del base, xp, inps + + # The "new tuple test". See https://bugs.python.org/issue34751. + # Even more tortured nesting, and a mix of signed ints of very + # small magnitude. n = 5 A = [x for x in range(-n, n+1) if x != -1] - B = A + [(a,) for a in A] - - L2 = [(a,b) for a in A for b in A] - L3 = L2 + [(a,b,c) for a in A for b in A for c in A] - L4 = L3 + [(a,b,c,d) for a in A for b in A for c in A for d in A] - + L2 = list(product(A, repeat=2)) + L3 = L2 + list(product(A, repeat=3)) + L4 = L3 + list(product(A, repeat=4)) # T = list of testcases. These consist of all (possibly nested # at most 2 levels deep) tuples containing at most 4 items from # the set A. T = A T += [(a,) for a in B + L4] - T += [(a,b) for a in L3 for b in B] - T += [(a,b) for a in L2 for b in L2] - T += [(a,b) for a in B for b in L3] - T += [(a,b,c) for a in B for b in B for c in L2] - T += [(a,b,c) for a in B for b in L2 for c in B] - T += [(a,b,c) for a in L2 for b in B for c in B] - T += [(a,b,c,d) for a in B for b in B for c in B for d in B] - self.assertEqual(len(T), 345130) - hashes = set(hash(x) % 2**32 for x in T) - collisions = len(T) - len(hashes) - - # For a pure random 32-bit hash and N = 345,130 test items, the - # expected number of collisions equals - # - # 2**(-32) * N(N-1)/2 = 13.9 - # - # We allow up to 20 collisions, which suffices to make the test - # pass with 95.5% confidence. - self.assertLessEqual(collisions, 20) - - def test_hash3(self): - # Check for hash collisions between tuples containing 0.0 and 0.5. - # The hashes of 0.0 and 0.5 itself differ only in one high bit. - # So this implicitly tests propagation of high bits to low bits. - from itertools import product - T = list(product([0.0, 0.5], repeat=18)) - self.assertEqual(len(T), 262144) - hashes = set(hash(x) % 2**32 for x in T) - collisions = len(T) - len(hashes) - - # For a pure random 32-bit hash and N = 262,144 test items, the - # expected number of collisions equals - # - # 2**(-32) * N(N-1)/2 = 8.0 - # - # We allow up to 15 collisions, which suffices to make the test - # pass with 99.1% confidence. - self.assertLessEqual(collisions, 15) + T += product(L3, B) + T += product(L2, repeat=2) + T += product(B, L3) + T += product(B, B, L2) + T += product(B, L2, B) + T += product(L2, B, B) + T += product(B, repeat=4) + assert len(T) == 345130 + tryone("new tuple test", T, + (9, 1), (0, 0), (21, 5), (6, 1)) def test_repr(self): l0 = tuple() @@ -298,5 +388,98 @@ def test_lexicographic_ordering(self): self.assertLess(a, b) self.assertLess(b, c) +# Notes on testing hash codes. The primary thing is that Python doesn't +# care about "random" hash codes. To the contrary, we like them to be +# very regular when possible, so that the low-order bits are as evenly +# distributed as possible. For integers this is easy: hash(i) == i for +# all not-huge i except i==-1. +# +# For tuples of mixed type there's really no hope of that, so we want +# "randomish" here instead. But getting close to pseudo-random in all +# bit positions is more expensive than we've been willing to pay for. +# +# We can tolerate large deviations from random - what we don't want is +# catastrophic pileups on a relative handful of hash codes. The dict +# and set lookup routines remain effective provided that full-width hash +# codes for not-equal objects are distinct. +# +# So we compute various statistics here based on what a "truly random" +# hash would do, but don't automate "pass or fail" based on those +# results. Instead those are viewed as inputs to human judgment, and the +# automated tests merely ensure we get the _same_ results across +# platforms. In fact, we normally don't bother to run them at all - +# set RUN_ALL_HASH_TESTS to force it. +# +# When global JUST_SHOW_HASH_RESULTS is True, the tuple hash statistics +# are just displayed to stdout. A typical output line looks like: +# +# old tuple test; 32-bit upper hash codes; \ +# pileup 49 mean 7.4 coll 52 z +16.4 +# +# "old tuple test" is just a string name for the test being run. +# +# "32-bit upper hash codes" means this was run under a 64-bit build and +# we've shifted away the lower 32 bits of the hash codes. +# +# "pileup" is 0 if there were no collisions across those hash codes. +# It's 1 less than the maximum number of times any single hash code was +# seen. So in this case, there was (at least) one hash code that was +# seen 50 times: that hash code "piled up" 49 more times than ideal. +# +# "mean" is the number of collisions a perfectly random hash function +# would have yielded, on average. +# +# "coll" is the number of collisions actually seen. +# +# "z" is "coll - mean" divided by the standard deviation of the number +# of collisions a perfectly random hash function would suffer. A +# positive value is "worse than random", and negative value "better than +# random". Anything of magnitude greater than 3 would be highly suspect +# for a hash function that claimed to be random. It's essentially +# impossible that a truly random function would deliver a result 16.4 +# sdevs "worse than random". +# +# But we don't care here! That's why the test isn't coded to fail. +# Knowing something about how the high-order hash code bits behave +# provides insight, but is irrelevant to how the dict and set lookup +# code performs. The low-order bits are much more important to that, +# and on the same test those did "just like random": +# +# old tuple test; 32-bit lower hash codes; \ +# pileup 1 mean 7.4 coll 7 z -0.2 +# +# So there are always tradeoffs to consider. For another: +# +# 0..99 << 60 by 3; 32-bit hash codes; \ +# pileup 0 mean 116.4 coll 0 z -10.8 +# +# That was run under a 32-bit build, and is spectacularly "better than +# random". On a 64-bit build the wider hash codes are fine too: +# +# 0..99 << 60 by 3; 64-bit hash codes; \ +# pileup 0 mean 0.0 coll 0 z -0.0 +# +# but their lower 32 bits are poor: +# +# 0..99 << 60 by 3; 32-bit lower hash codes; \ +# pileup 1 mean 116.4 coll 324 z +19.2 +# +# In a statistical sense that's waaaaay too many collisions, but (a) 324 +# collisions out of a million hash codes isn't anywhere near being a +# real problem; and, (b) the worst pileup on a single hash code is a measly +# 1 extra. It's a relatively poor case for the tuple hash, but still +# fine for practical use. +# +# This isn't, which is what Python 3.7.1 produced for the hashes of +# itertools.product([0, 0.5], repeat=18). Even with a fat 64-bit +# hashcode, the highest pileup was over 16,000 - making a dict/set +# lookup on one of the colliding values thousands of times slower (on +# average) than we expect. +# +# [0, 0.5] by 18; 64-bit hash codes; \ +# pileup 16,383 mean 0.0 coll 262,128 z +6073641856.9 +# [0, 0.5] by 18; 32-bit lower hash codes; \ +# pileup 262,143 mean 8.0 coll 262,143 z +92683.6 + if __name__ == "__main__": unittest.main() From 2dda72a2e8e1f1ab28011a65194db5d03979dbb3 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 8 Feb 2019 18:55:02 -0800 Subject: [PATCH 0026/1727] lru_cache: Add more comments. Fix comment typos. Clarify a comment. (GH-11795) --- Modules/_functoolsmodule.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index d72aaff2b13c4a..3f1c01651ded1b 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -661,6 +661,26 @@ sequence is empty."); /* lru_cache object **********************************************************/ +/* There are four principal algorithmic differences from the pure python version: + + 1). The C version relies on the GIL instead of having its own reentrant lock. + + 2). The prev/next link fields use borrowed references. + + 3). For a full cache, the pure python version rotates the location of the + root entry so that it never has to move individual links and it can + limit updates to just the key and result fields. However, in the C + version, links are temporarily removed while the cache dict updates are + occurring. Afterwards, they are appended or prepended back into the + doubly-linked lists. + + 4) In the Python version, the _HashSeq class is used to prevent __hash__ + from being called more than once. In the C version, the "known hash" + variants of dictionary calls as used to the same effect. + +*/ + + /* this object is used delimit args and keywords in the cache keys */ static PyObject *kwd_mark = NULL; @@ -1009,14 +1029,15 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds link = self->root.next; lru_cache_extract_link(link); /* Remove it from the cache. - The cache dict holds one reference to the link, - and the linked list holds yet one reference to it. */ + The cache dict holds one reference to the link. + We created one other reference when the link was created. + The linked list only has borrowed references. */ popresult = _PyDict_Pop_KnownHash(self->cache, link->key, link->hash, Py_None); if (popresult == Py_None) { /* Getting here means that the user function call or another thread has already removed the old key from the dictionary. - This link is now an orpan. Since we don't want to leave the + This link is now an orphan. Since we don't want to leave the cache in an inconsistent state, we don't restore the link. */ Py_DECREF(popresult); Py_DECREF(link); @@ -1048,7 +1069,7 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds prev and next fields set to valid values. We have to wait for successful insertion in the cache dict before adding the link to the linked list. Otherwise, the potentially reentrant - __eq__ call could cause the then ophan link to be visited. */ + __eq__ call could cause the then orphan link to be visited. */ if (_PyDict_SetItem_KnownHash(self->cache, key, (PyObject *)link, hash) < 0) { /* Somehow the cache dict update failed. We no longer can From 8a03ff2ff4db973c9fe152561f1796e72cb71132 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 8 Feb 2019 22:51:51 -0500 Subject: [PATCH 0027/1727] bpo-35833: Revise IDLE doc for control codes sent to Shell. (GH-11799) Add a code example block. --- Doc/library/idle.rst | 35 +++++++++++---- Lib/idlelib/NEWS.txt | 3 ++ Lib/idlelib/help.html | 45 +++++++++++++------ .../2019-02-08-22-14-24.bpo-35833.XKFRvF.rst | 1 + 4 files changed, 62 insertions(+), 22 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2019-02-08-22-14-24.bpo-35833.XKFRvF.rst diff --git a/Doc/library/idle.rst b/Doc/library/idle.rst index 56d7c9f4c2c297..8290039c968b2f 100644 --- a/Doc/library/idle.rst +++ b/Doc/library/idle.rst @@ -716,14 +716,33 @@ In contrast, some system text windows only keep the last n lines of output. A Windows console, for instance, keeps a user-settable 1 to 9999 lines, with 300 the default. -Text widgets display a subset of Unicode, the Basic Multilingual Plane (BMP). -Which characters get a proper glyph instead of a replacement box depends on -the operating system and installed fonts. Newline characters cause following -text to appear on a new line, but other control characters are either -replaced with a box or deleted. However, ``repr()``, which is used for -interactive echo of expression values, replaces control characters, -some BMP codepoints, and all non-BMP characters with escape codes -before they are output. +A Tk Text widget, and hence IDLE's Shell, displays characters (codepoints) +in the the BMP (Basic Multilingual Plane) subset of Unicode. +Which characters are displayed with a proper glyph and which with a +replacement box depends on the operating system and installed fonts. +Tab characters cause the following text to begin after +the next tab stop. (They occur every 8 'characters'). +Newline characters cause following text to appear on a new line. +Other control characters are ignored or displayed as a space, box, or +something else, depending on the operating system and font. +(Moving the text cursor through such output with arrow keys may exhibit +some surprising spacing behavior.) + +.. code-block:: none + + >>> s = 'a\tb\a<\x02><\r>\bc\nd' + >>> len(s) + 14 + >>> s # Display repr(s) + 'a\tb\x07<\x02><\r>\x08c\nd' + >>> print(s, end='') # Display s as is. + # Result varies by OS and font. Try it. + +The ``repr`` function is used for interactive echo of expression +values. It returns an altered version of the input string in which +control codes, some BMP codepoints, and all non-BMP codepoints are +replaced with escape codes. As demonstrated above, it allows one to +identify the characters in a string, regardless of how they are displayed. Normal and error output are generally kept separate (on separate lines) from code input and each other. They each get different highlight colors. diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index 61457e93d2381c..60454c24c6a8cd 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2019-10-20? ====================================== +bpo-35833: Revise IDLE doc for control codes sent to Shell. +Add a code example block. + bpo-35770: IDLE macosx deletes Options => Configure IDLE. It previously deleted Window => Zoom Height by mistake. (Zoom Height is now on the Options menu). On Mac, the settings diff --git a/Lib/idlelib/help.html b/Lib/idlelib/help.html index 80c87f6ebdf1b2..374159f807e9b8 100644 --- a/Lib/idlelib/help.html +++ b/Lib/idlelib/help.html @@ -6,7 +6,7 @@ - IDLE — Python 3.8.0a0 documentation + IDLE — Python 3.8.0a1 documentation @@ -19,7 +19,7 @@ @@ -72,7 +72,7 @@

Navigation

  • - 3.8.0a0 Documentation » + 3.8.0a1 Documentation »
  • @@ -673,14 +673,31 @@

    User output in Shell -

    Text widgets display a subset of Unicode, the Basic Multilingual Plane (BMP). -Which characters get a proper glyph instead of a replacement box depends on -the operating system and installed fonts. Newline characters cause following -text to appear on a new line, but other control characters are either -replaced with a box or deleted. However, repr(), which is used for -interactive echo of expression values, replaces control characters, -some BMP codepoints, and all non-BMP characters with escape codes -before they are output.

    +

    A Tk Text widget, and hence IDLE’s Shell, displays characters (codepoints) +in the the BMP (Basic Multilingual Plane) subset of Unicode. +Which characters are displayed with a proper glyph and which with a +replacement box depends on the operating system and installed fonts. +Tab characters cause the following text to begin after +the next tab stop. (They occur every 8 ‘characters’). +Newline characters cause following text to appear on a new line. +Other control characters are ignored or displayed as a space, box, or +something else, depending on the operating system and font. +(Moving the text cursor through such output with arrow keys may exhibit +some surprising spacing behavior.)

    +
    >>> s = 'a\tb\a<\x02><\r>\bc\nd'
    +>>> len(s)
    +14
    +>>> s  # Display repr(s)
    +'a\tb\x07<\x02><\r>\x08c\nd'
    +>>> print(s, end='')  # Display s as is.
    +# Result varies by OS and font.  Try it.
    +
    +
    +

    The repr function is used for interactive echo of expression +values. It returns an altered version of the input string in which +control codes, some BMP codepoints, and all non-BMP codepoints are +replaced with escape codes. As demonstrated above, it allows one to +identify the characters in a string, regardless of how they are displayed.

    Normal and error output are generally kept separate (on separate lines) from code input and each other. They each get different highlight colors.

    For SyntaxError tracebacks, the normal ‘^’ marking where the error was @@ -889,7 +906,7 @@

    Navigation

  • - 3.8.0a0 Documentation » + 3.8.0a1 Documentation »
  • @@ -912,7 +929,7 @@

    Navigation