From solipsis at pitrou.net Sun Nov 1 03:44:31 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 01 Nov 2015 08:44:31 +0000 Subject: [Python-checkins] Daily reference leaks (f7db966c9fee): sum=17880 Message-ID: <20151101084431.59807.3154@psf.io> results for f7db966c9fee on branch "default" -------------------------------------------- test_capi leaked [1599, 1599, 1599] references, sum=4797 test_capi leaked [387, 389, 389] memory blocks, sum=1165 test_functools leaked [0, 2, 2] memory blocks, sum=4 test_threading leaked [3196, 3196, 3196] references, sum=9588 test_threading leaked [774, 776, 776] memory blocks, sum=2326 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflog3Lnth8', '--timeout', '7200'] From python-checkins at python.org Sun Nov 1 09:14:31 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 14:14:31 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1Mzk1?= =?utf-8?q?=3A_Fixed_crash_when_highly_nested_OrderedDict_structures_were?= Message-ID: <20151101141431.482.68322@psf.io> https://hg.python.org/cpython/rev/ce8c850a52d4 changeset: 98922:ce8c850a52d4 branch: 3.5 parent: 98920:f884590ee620 user: Serhiy Storchaka date: Sun Nov 01 16:12:34 2015 +0200 summary: Issue #25395: Fixed crash when highly nested OrderedDict structures were garbage collected. files: Lib/test/test_collections.py | 24 ++++++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/odictobject.c | 17 ++++++++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -2025,6 +2025,30 @@ items = [('a', 1), ('c', 3), ('b', 2)] self.assertEqual(list(MyOD(items).items()), items) + def test_highly_nested(self): + # Issue 25395: crashes during garbage collection + OrderedDict = self.module.OrderedDict + obj = None + for _ in range(1000): + obj = OrderedDict([(None, obj)]) + del obj + support.gc_collect() + + def test_highly_nested_subclass(self): + # Issue 25395: crashes during garbage collection + OrderedDict = self.module.OrderedDict + deleted = [] + class MyOD(OrderedDict): + def __del__(self): + deleted.append(self.i) + obj = None + for i in range(100): + obj = MyOD([(None, obj)]) + obj.i = i + del obj + support.gc_collect() + self.assertEqual(deleted, list(reversed(range(100)))) + class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25395: Fixed crash when highly nested OrderedDict structures were + garbage collected. + - Issue #25274: sys.setrecursionlimit() now raises a RecursionError if the new recursion limit is too low depending at the current recursion depth. Modify also the "lower-water mark" formula to make it monotonic. This mark is used diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1431,17 +1431,28 @@ static void odict_dealloc(PyODictObject *self) { + PyThreadState *tstate = PyThreadState_GET(); + PyObject_GC_UnTrack(self); - Py_TRASHCAN_SAFE_BEGIN(self); + Py_TRASHCAN_SAFE_BEGIN(self) + Py_XDECREF(self->od_inst_dict); if (self->od_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); _odict_clear_nodes(self); - Py_TRASHCAN_SAFE_END(self); - /* must be last */ + /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism, + * temporarily decrement trash_delete_nesting to prevent triggering it + * and putting the partially deallocated object on the trashcan's + * to-be-deleted-later list. + */ + --tstate->trash_delete_nesting; + assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL); PyDict_Type.tp_dealloc((PyObject *)self); + ++tstate->trash_delete_nesting; + + Py_TRASHCAN_SAFE_END(self) }; /* tp_repr */ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 09:14:33 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 14:14:33 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325395=3A_Fixed_crash_when_highly_nested_Ordered?= =?utf-8?q?Dict_structures_were?= Message-ID: <20151101141431.59785.99735@psf.io> https://hg.python.org/cpython/rev/bd6bfa5fe203 changeset: 98923:bd6bfa5fe203 parent: 98921:f7db966c9fee parent: 98922:ce8c850a52d4 user: Serhiy Storchaka date: Sun Nov 01 16:13:45 2015 +0200 summary: Issue #25395: Fixed crash when highly nested OrderedDict structures were garbage collected. files: Lib/test/test_collections.py | 24 ++++++++++++++++++++++++ Misc/NEWS | 3 +++ Objects/odictobject.c | 17 ++++++++++++++--- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -2033,6 +2033,30 @@ items = [('a', 1), ('c', 3), ('b', 2)] self.assertEqual(list(MyOD(items).items()), items) + def test_highly_nested(self): + # Issue 25395: crashes during garbage collection + OrderedDict = self.module.OrderedDict + obj = None + for _ in range(1000): + obj = OrderedDict([(None, obj)]) + del obj + support.gc_collect() + + def test_highly_nested_subclass(self): + # Issue 25395: crashes during garbage collection + OrderedDict = self.module.OrderedDict + deleted = [] + class MyOD(OrderedDict): + def __del__(self): + deleted.append(self.i) + obj = None + for i in range(100): + obj = MyOD([(None, obj)]) + obj.i = i + del obj + support.gc_collect() + self.assertEqual(deleted, list(reversed(range(100)))) + class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25395: Fixed crash when highly nested OrderedDict structures were + garbage collected. + - Issue #25401: Optimize bytes.fromhex() and bytearray.fromhex(): they are now between 2x and 3.5x faster. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1431,17 +1431,28 @@ static void odict_dealloc(PyODictObject *self) { + PyThreadState *tstate = PyThreadState_GET(); + PyObject_GC_UnTrack(self); - Py_TRASHCAN_SAFE_BEGIN(self); + Py_TRASHCAN_SAFE_BEGIN(self) + Py_XDECREF(self->od_inst_dict); if (self->od_weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *)self); _odict_clear_nodes(self); - Py_TRASHCAN_SAFE_END(self); - /* must be last */ + /* Call the base tp_dealloc(). Since it too uses the trashcan mechanism, + * temporarily decrement trash_delete_nesting to prevent triggering it + * and putting the partially deallocated object on the trashcan's + * to-be-deleted-later list. + */ + --tstate->trash_delete_nesting; + assert(_tstate->trash_delete_nesting < PyTrash_UNWIND_LEVEL); PyDict_Type.tp_dealloc((PyObject *)self); + ++tstate->trash_delete_nesting; + + Py_TRASHCAN_SAFE_END(self) }; /* tp_repr */ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 09:46:46 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 14:46:46 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325510=3A_fileinput=2EFileInput=2Ereadline=28=29_now_r?= =?utf-8?q?eturns_b=27=27_instead_of_=27=27?= Message-ID: <20151101144646.59803.72256@psf.io> https://hg.python.org/cpython/rev/321b34824020 changeset: 98925:321b34824020 branch: 3.5 parent: 98922:ce8c850a52d4 parent: 98924:e27c589e1c6a user: Serhiy Storchaka date: Sun Nov 01 16:45:26 2015 +0200 summary: Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. files: Lib/fileinput.py | 5 ++++- Lib/test/test_fileinput.py | 15 +++++++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 23 insertions(+), 1 deletions(-) diff --git a/Lib/fileinput.py b/Lib/fileinput.py --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -315,7 +315,10 @@ return line if not self._file: if not self._files: - return "" + if 'b' in self._mode: + return b'' + else: + return '' self._filename = self._files[0] self._files = self._files[1:] self._filelineno = 0 diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -288,6 +288,21 @@ with self.assertRaises(UnicodeDecodeError): # Read to the end of file. list(fi) + self.assertEqual(fi.readline(), '') + self.assertEqual(fi.readline(), '') + + def test_readline_binary_mode(self): + with open(TESTFN, 'wb') as f: + f.write(b'A\nB\r\nC\rD') + self.addCleanup(safe_unlink, TESTFN) + + with FileInput(files=TESTFN, mode='rb') as fi: + self.assertEqual(fi.readline(), b'A\n') + self.assertEqual(fi.readline(), b'B\r\n') + self.assertEqual(fi.readline(), b'C\rD') + # Read to the end of file. + self.assertEqual(fi.readline(), b'') + self.assertEqual(fi.readline(), b'') def test_context_manager(self): try: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -48,6 +48,10 @@ Library ------- +- Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' + at the end if the FileInput was opened with binary mode. + Patch by Ryosuke Ito. + - Issue #25503: Fixed inspect.getdoc() for inherited docstrings of properties. Original patch by John Mark Vandenberg. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 09:46:46 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 14:46:46 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTEw?= =?utf-8?q?=3A_fileinput=2EFileInput=2Ereadline=28=29_now_returns_b=27=27_?= =?utf-8?q?instead_of_=27=27?= Message-ID: <20151101144646.80230.75458@psf.io> https://hg.python.org/cpython/rev/e27c589e1c6a changeset: 98924:e27c589e1c6a branch: 3.4 parent: 98909:44464bbd339c user: Serhiy Storchaka date: Sun Nov 01 16:43:58 2015 +0200 summary: Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. files: Lib/fileinput.py | 5 ++++- Lib/test/test_fileinput.py | 15 +++++++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 23 insertions(+), 1 deletions(-) diff --git a/Lib/fileinput.py b/Lib/fileinput.py --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -315,7 +315,10 @@ return line if not self._file: if not self._files: - return "" + if 'b' in self._mode: + return b'' + else: + return '' self._filename = self._files[0] self._files = self._files[1:] self._filelineno = 0 diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -288,6 +288,21 @@ with self.assertRaises(UnicodeDecodeError): # Read to the end of file. list(fi) + self.assertEqual(fi.readline(), '') + self.assertEqual(fi.readline(), '') + + def test_readline_binary_mode(self): + with open(TESTFN, 'wb') as f: + f.write(b'A\nB\r\nC\rD') + self.addCleanup(safe_unlink, TESTFN) + + with FileInput(files=TESTFN, mode='rb') as fi: + self.assertEqual(fi.readline(), b'A\n') + self.assertEqual(fi.readline(), b'B\r\n') + self.assertEqual(fi.readline(), b'C\rD') + # Read to the end of file. + self.assertEqual(fi.readline(), b'') + self.assertEqual(fi.readline(), b'') def test_context_manager(self): try: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -96,6 +96,10 @@ Library ------- +- Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' + at the end if the FileInput was opened with binary mode. + Patch by Ryosuke Ito. + - Issue #21827: Fixed textwrap.dedent() for the case when largest common whitespace is a substring of smallest leading whitespace. Based on patch by Robert Li. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 09:46:46 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 14:46:46 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325510=3A_fileinput=2EFileInput=2Ereadline=28=29?= =?utf-8?q?_now_returns_b=27=27_instead_of_=27=27?= Message-ID: <20151101144646.12529.79861@psf.io> https://hg.python.org/cpython/rev/4f0e293e6eb0 changeset: 98926:4f0e293e6eb0 parent: 98923:bd6bfa5fe203 parent: 98925:321b34824020 user: Serhiy Storchaka date: Sun Nov 01 16:45:54 2015 +0200 summary: Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. files: Lib/fileinput.py | 5 ++++- Lib/test/test_fileinput.py | 15 +++++++++++++++ Misc/NEWS | 4 ++++ 3 files changed, 23 insertions(+), 1 deletions(-) diff --git a/Lib/fileinput.py b/Lib/fileinput.py --- a/Lib/fileinput.py +++ b/Lib/fileinput.py @@ -315,7 +315,10 @@ return line if not self._file: if not self._files: - return "" + if 'b' in self._mode: + return b'' + else: + return '' self._filename = self._files[0] self._files = self._files[1:] self._filelineno = 0 diff --git a/Lib/test/test_fileinput.py b/Lib/test/test_fileinput.py --- a/Lib/test/test_fileinput.py +++ b/Lib/test/test_fileinput.py @@ -288,6 +288,21 @@ with self.assertRaises(UnicodeDecodeError): # Read to the end of file. list(fi) + self.assertEqual(fi.readline(), '') + self.assertEqual(fi.readline(), '') + + def test_readline_binary_mode(self): + with open(TESTFN, 'wb') as f: + f.write(b'A\nB\r\nC\rD') + self.addCleanup(safe_unlink, TESTFN) + + with FileInput(files=TESTFN, mode='rb') as fi: + self.assertEqual(fi.readline(), b'A\n') + self.assertEqual(fi.readline(), b'B\r\n') + self.assertEqual(fi.readline(), b'C\rD') + # Read to the end of file. + self.assertEqual(fi.readline(), b'') + self.assertEqual(fi.readline(), b'') def test_context_manager(self): try: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -66,6 +66,10 @@ Library ------- +- Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' + at the end if the FileInput was opened with binary mode. + Patch by Ryosuke Ito. + - Issue #25503: Fixed inspect.getdoc() for inherited docstrings of properties. Original patch by John Mark Vandenberg. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 10:14:49 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 01 Nov 2015 15:14:49 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2318973=3A_Command-?= =?utf-8?q?line_interface_of_the_calendar_module_now_uses_argparse?= Message-ID: <20151101151448.100266.34847@psf.io> https://hg.python.org/cpython/rev/9f8b5053e30d changeset: 98927:9f8b5053e30d user: Serhiy Storchaka date: Sun Nov 01 17:14:27 2015 +0200 summary: Issue #18973: Command-line interface of the calendar module now uses argparse instead of optparse. files: Lib/calendar.py | 81 +++++++++++++++------------ Lib/test/test_calendar.py | 8 +- Misc/NEWS | 3 + 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -605,51 +605,63 @@ def main(args): - import optparse - parser = optparse.OptionParser(usage="usage: %prog [options] [year [month]]") - parser.add_option( + import argparse + parser = argparse.ArgumentParser() + textgroup = parser.add_argument_group('text only arguments') + htmlgroup = parser.add_argument_group('html only arguments') + textgroup.add_argument( "-w", "--width", - dest="width", type="int", default=2, - help="width of date column (default 2, text only)" + type=int, default=2, + help="width of date column (default 2)" ) - parser.add_option( + textgroup.add_argument( "-l", "--lines", - dest="lines", type="int", default=1, - help="number of lines for each week (default 1, text only)" + type=int, default=1, + help="number of lines for each week (default 1)" ) - parser.add_option( + textgroup.add_argument( "-s", "--spacing", - dest="spacing", type="int", default=6, - help="spacing between months (default 6, text only)" + type=int, default=6, + help="spacing between months (default 6)" ) - parser.add_option( + textgroup.add_argument( "-m", "--months", - dest="months", type="int", default=3, - help="months per row (default 3, text only)" + type=int, default=3, + help="months per row (default 3)" ) - parser.add_option( + htmlgroup.add_argument( "-c", "--css", - dest="css", default="calendar.css", - help="CSS to use for page (html only)" + default="calendar.css", + help="CSS to use for page" ) - parser.add_option( + parser.add_argument( "-L", "--locale", - dest="locale", default=None, + default=None, help="locale to be used from month and weekday names" ) - parser.add_option( + parser.add_argument( "-e", "--encoding", - dest="encoding", default=None, - help="Encoding to use for output." + default=None, + help="encoding to use for output" ) - parser.add_option( + parser.add_argument( "-t", "--type", - dest="type", default="text", + default="text", choices=("text", "html"), help="output type (text or html)" ) + parser.add_argument( + "year", + nargs='?', type=int, + help="year number (1-9999)" + ) + parser.add_argument( + "month", + nargs='?', type=int, + help="month number (1-12, text only)" + ) - (options, args) = parser.parse_args(args) + options = parser.parse_args(args[1:]) if options.locale and not options.encoding: parser.error("if --locale is specified --encoding is required") @@ -667,10 +679,10 @@ encoding = sys.getdefaultencoding() optdict = dict(encoding=encoding, css=options.css) write = sys.stdout.buffer.write - if len(args) == 1: + if options.year is None: write(cal.formatyearpage(datetime.date.today().year, **optdict)) - elif len(args) == 2: - write(cal.formatyearpage(int(args[1]), **optdict)) + elif options.month is None: + write(cal.formatyearpage(options.year, **optdict)) else: parser.error("incorrect number of arguments") sys.exit(1) @@ -680,18 +692,15 @@ else: cal = TextCalendar() optdict = dict(w=options.width, l=options.lines) - if len(args) != 3: + if options.month is None: optdict["c"] = options.spacing optdict["m"] = options.months - if len(args) == 1: + if options.year is None: result = cal.formatyear(datetime.date.today().year, **optdict) - elif len(args) == 2: - result = cal.formatyear(int(args[1]), **optdict) - elif len(args) == 3: - result = cal.formatmonth(int(args[1]), int(args[2]), **optdict) + elif options.month is None: + result = cal.formatyear(options.year, **optdict) else: - parser.error("incorrect number of arguments") - sys.exit(1) + result = cal.formatmonth(options.year, options.month, **optdict) write = sys.stdout.write if options.encoding: result = result.encode(options.encoding) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -702,19 +702,19 @@ def assertFailure(self, *args): rc, stdout, stderr = assert_python_failure('-m', 'calendar', *args) - self.assertIn(b'Usage:', stderr) + self.assertIn(b'usage:', stderr) self.assertEqual(rc, 2) def test_help(self): stdout = self.run_ok('-h') - self.assertIn(b'Usage:', stdout) + self.assertIn(b'usage:', stdout) self.assertIn(b'calendar.py', stdout) self.assertIn(b'--help', stdout) def test_illegal_arguments(self): self.assertFailure('-z') - #self.assertFailure('spam') - #self.assertFailure('2004', 'spam') + self.assertFailure('spam') + self.assertFailure('2004', 'spam') self.assertFailure('-t', 'html', '2004', '1') def test_output_current_year(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -66,6 +66,9 @@ Library ------- +- Issue #18973: Command-line interface of the calendar module now uses argparse + instead of optparse. + - Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 17:45:45 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 01 Nov 2015 22:45:45 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_2=2E7=2E11_dates?= Message-ID: <20151101224545.10180.52887@psf.io> https://hg.python.org/peps/rev/65205e4943c7 changeset: 6125:65205e4943c7 user: Benjamin Peterson date: Sun Nov 01 14:45:41 2015 -0800 summary: 2.7.11 dates files: pep-0373.txt | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/pep-0373.txt b/pep-0373.txt --- a/pep-0373.txt +++ b/pep-0373.txt @@ -56,7 +56,8 @@ Planned future release dates: -- 2.7.11 December, 2015 +- 2.7.11rc1 2015-11-21 +- 2.7.11 2015-12-05 - beyond this date, releases as needed Dates of previous maintenance releases: -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Sun Nov 1 23:29:17 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 02 Nov 2015 04:29:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTIz?= =?utf-8?q?=3A_Further_a-to-an_corrections_new_in_3=2E5?= Message-ID: <20151102042917.80214.33425@psf.io> https://hg.python.org/cpython/rev/2347271172b3 changeset: 98930:2347271172b3 branch: 3.5 user: Martin Panter date: Mon Nov 02 04:20:33 2015 +0000 summary: Issue #25523: Further a-to-an corrections new in 3.5 files: Doc/library/argparse.rst | 2 +- Doc/reference/datamodel.rst | 4 ++-- Doc/whatsnew/3.5.rst | 2 +- Lib/concurrent/futures/process.py | 2 +- Lib/signal.py | 2 +- Lib/unittest/test/test_discovery.py | 4 ++-- Misc/NEWS | 2 +- Modules/_collectionsmodule.c | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -530,7 +530,7 @@ ^^^^^^^^^^^^ Normally, when you pass an argument list to the -:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`, +:meth:`~ArgumentParser.parse_args` method of an :class:`ArgumentParser`, it :ref:`recognizes abbreviations ` of long options. This feature can be disabled by setting ``allow_abbrev`` to ``False``:: diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2358,7 +2358,7 @@ ``__aiter__`` implementation, and an *asynchronous iterator* can call asynchronous code in its ``__anext__`` method. -Asynchronous iterators can be used in a :keyword:`async for` statement. +Asynchronous iterators can be used in an :keyword:`async for` statement. .. method:: object.__aiter__(self) @@ -2393,7 +2393,7 @@ An *asynchronous context manager* is a *context manager* that is able to suspend execution in its ``__aenter__`` and ``__aexit__`` methods. -Asynchronous context managers can be used in a :keyword:`async with` statement. +Asynchronous context managers can be used in an :keyword:`async with` statement. .. method:: object.__aenter__(self) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -465,7 +465,7 @@ PEP 475: Retry system calls failing with EINTR ---------------------------------------------- -A :py:data:`errno.EINTR` error code is returned whenever a system call, that +An :py:data:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would raise :exc:`InterruptedError` in such case. This meant that, when writing a Python application, the developer had two choices: diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -456,7 +456,7 @@ submit.__doc__ = _base.Executor.submit.__doc__ def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/signal.py b/Lib/signal.py --- a/Lib/signal.py +++ b/Lib/signal.py @@ -34,7 +34,7 @@ def _enum_to_int(value): """Convert an IntEnum member to a numeric value. - If it's not a IntEnum member return the value itself. + If it's not an IntEnum member return the value itself. """ try: return int(value) diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -255,12 +255,12 @@ self.addCleanup(sys.path.remove, abspath('/foo')) # Test data: we expect the following: - # a listdir to find our package, and a isfile and isdir check on it. + # a listdir to find our package, and isfile and isdir checks on it. # a module-from-name call to turn that into a module # followed by load_tests. # then our load_tests will call discover() which is messy # but that finally chains into find_tests again for the child dir - - # which is why we don't have a infinite loop. + # which is why we don't have an infinite loop. # We expect to see: # the module load tests for both package and plain module called, # and the plain module result nested by the package module load_tests diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1990,7 +1990,7 @@ - Issue #23132: Improve performance and introspection support of comparison methods created by functool.total_ordering. -- Issue #19776: Add a expanduser() method on Path objects. +- Issue #19776: Add an expanduser() method on Path objects. - Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and fragment when it redirects to add a trailing slash. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -629,7 +629,7 @@ Conceptually, a rotate by one is equivalent to a pop on one side and an append on the other. However, a pop/append pair is unnecessarily slow -because it requires a incref/decref pair for an object located randomly +because it requires an incref/decref pair for an object located randomly in memory. It is better to just move the object pointer from one block to the next without changing the reference count. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 23:29:16 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 02 Nov 2015 04:29:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTIz?= =?utf-8?q?=3A_Correct_=22a=22_article_to_=22an=22_article?= Message-ID: <20151102042916.480.45721@psf.io> https://hg.python.org/cpython/rev/d8ff13414deb changeset: 98928:d8ff13414deb branch: 3.4 parent: 98924:e27c589e1c6a user: Martin Panter date: Mon Nov 02 03:37:02 2015 +0000 summary: Issue #25523: Correct "a" article to "an" article This changes the main documentation, doc strings, source code comments, and a couple error messages in the test suite. In some cases the word was removed or edited some other way to fix the grammar. files: Doc/c-api/buffer.rst | 2 +- Doc/faq/programming.rst | 2 +- Doc/library/chunk.rst | 2 +- Doc/library/concurrent.futures.rst | 4 +- Doc/library/ctypes.rst | 2 +- Doc/library/difflib.rst | 2 +- Doc/library/fcntl.rst | 6 +- Doc/library/ftplib.rst | 4 +- Doc/library/functions.rst | 6 +- Doc/library/gzip.rst | 2 +- Doc/library/http.cookiejar.rst | 2 +- Doc/library/http.server.rst | 4 +- Doc/library/mailbox.rst | 2 +- Doc/library/multiprocessing.rst | 2 +- Doc/library/nntplib.rst | 2 +- Doc/library/optparse.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/pickle.rst | 4 +- Doc/library/pyexpat.rst | 2 +- Doc/library/shutil.rst | 4 +- Doc/library/smtplib.rst | 4 +- Doc/library/socket.rst | 4 +- Doc/library/sqlite3.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sunau.rst | 4 +- Doc/library/tempfile.rst | 2 +- Doc/library/unittest.mock.rst | 2 +- Doc/library/xml.dom.pulldom.rst | 2 +- Doc/tutorial/errors.rst | 2 +- Doc/tutorial/introduction.rst | 2 +- Doc/whatsnew/2.1.rst | 2 +- Doc/whatsnew/2.3.rst | 2 +- Doc/whatsnew/3.1.rst | 2 +- Doc/whatsnew/3.2.rst | 4 +- Doc/whatsnew/3.3.rst | 2 +- Include/abstract.h | 2 +- Include/codecs.h | 4 +- Lib/_pyio.py | 2 +- Lib/asyncio/streams.py | 2 +- Lib/calendar.py | 2 +- Lib/chunk.py | 2 +- Lib/codecs.py | 6 +- Lib/concurrent/futures/_base.py | 2 +- Lib/difflib.py | 2 +- Lib/distutils/cygwinccompiler.py | 6 +- Lib/ftplib.py | 4 +- Lib/getopt.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/ReplaceDialog.py | 2 +- Lib/io.py | 2 +- Lib/lib2to3/fixes/fix_input.py | 2 +- Lib/nntplib.py | 2 +- Lib/pickle.py | 4 +- Lib/test/decimaltestdata/fma.decTest | 1 + Lib/test/decimaltestdata/multiply.decTest | 1 + Lib/test/pystone.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_cmd.py | 2 +- Lib/test/test_codecs.py | 2 +- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_ipaddress.py | 4 +- Lib/test/test_os.py | 2 +- Lib/test/test_urllib.py | 2 +- Lib/test/test_weakref.py | 2 +- Lib/tkinter/ttk.py | 2 +- Lib/xmlrpc/client.py | 4 +- Misc/HISTORY | 30 +++++----- Misc/NEWS | 2 +- Modules/_ctypes/libffi/src/x86/darwin64.S | 2 +- Modules/_ctypes/libffi/src/x86/unix64.S | 2 +- Modules/_ctypes/libffi_osx/x86/darwin64.S | 2 +- Modules/_hashopenssl.c | 2 +- Modules/_io/_iomodule.c | 2 +- Modules/_io/textio.c | 4 +- Modules/_pickle.c | 16 ++-- Modules/atexitmodule.c | 2 +- Modules/audioop.c | 4 +- Modules/clinic/_pickle.c.h | 10 +- Modules/expat/pyexpatns.h | 2 +- Modules/hashlib.h | 2 +- Modules/readline.c | 2 +- Objects/abstract.c | 2 +- Objects/exceptions.c | 2 +- Python/compile.c | 2 +- Python/thread.c | 2 +- Tools/gdb/libpython.py | 4 +- 86 files changed, 136 insertions(+), 134 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -40,7 +40,7 @@ Simple objects such as :class:`bytes` and :class:`bytearray` expose their underlying buffer in byte-oriented form. Other forms are possible; for example, -the elements exposed by a :class:`array.array` can be multi-byte values. +the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -849,7 +849,7 @@ You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place -unicode data, try using a :class:`io.StringIO` object or the :mod:`array` +unicode data, try using an :class:`io.StringIO` object or the :mod:`array` module:: >>> import io diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -47,7 +47,7 @@ the :class:`Chunk` class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end of the file, creating a new -instance will fail with a :exc:`EOFError` exception. +instance will fail with an :exc:`EOFError` exception. .. class:: Chunk(file, align=True, bigendian=True, inclheader=False) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -81,7 +81,7 @@ ThreadPoolExecutor ------------------ -:class:`ThreadPoolExecutor` is a :class:`Executor` subclass that uses a pool of +:class:`ThreadPoolExecutor` is an :class:`Executor` subclass that uses a pool of threads to execute calls asynchronously. Deadlocks can occur when the callable associated with a :class:`Future` waits on @@ -285,7 +285,7 @@ Added callables are called in the order that they were added and are always called in a thread belonging to the process that added them. If - the callable raises a :exc:`Exception` subclass, it will be logged and + the callable raises an :exc:`Exception` subclass, it will be logged and ignored. If the callable raises a :exc:`BaseException` subclass, the behavior is undefined. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -39,7 +39,7 @@ convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`HRESULT` error code. The error -code is used to automatically raise a :class:`OSError` exception when the +code is used to automatically raise an :class:`OSError` exception when the function call fails. .. versionchanged:: 3.3 diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -269,7 +269,7 @@ generating the delta lines) in unified diff format. Unified diffs are a compact way of showing just the lines that have changed plus - a few lines of context. The changes are shown in a inline style (instead of + a few lines of context. The changes are shown in an inline style (instead of separate before/after blocks). The number of context lines is set by *n* which defaults to three. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -16,13 +16,13 @@ All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by -``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin`` +``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` itself, which provides a :meth:`~io.IOBase.fileno` that returns a genuine file descriptor. .. versionchanged:: 3.3 - Operations in this module used to raise a :exc:`IOError` where they now - raise a :exc:`OSError`. + Operations in this module used to raise an :exc:`IOError` where they now + raise an :exc:`OSError`. The module defines the following functions: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -287,9 +287,9 @@ .. method:: FTP.transfercmd(cmd, rest=None) - Initiate a transfer over the data connection. If the transfer is active, send a + Initiate a transfer over the data connection. If the transfer is active, send an ``EPRT`` or ``PORT`` command and the transfer command specified by *cmd*, and - accept the connection. If the server is passive, send a ``EPSV`` or ``PASV`` + accept the connection. If the server is passive, send an ``EPSV`` or ``PASV`` command, connect to it, and start the transfer command. Either way, return the socket for the connection. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1029,9 +1029,9 @@ :class:`io.TextIOBase` (specifically :class:`io.TextIOWrapper`). When used to open a file in a binary mode with buffering, the returned class is a subclass of :class:`io.BufferedIOBase`. The exact class varies: in read - binary mode, it returns a :class:`io.BufferedReader`; in write binary and - append binary modes, it returns a :class:`io.BufferedWriter`, and in - read/write mode, it returns a :class:`io.BufferedRandom`. When buffering is + binary mode, it returns an :class:`io.BufferedReader`; in write binary and + append binary modes, it returns an :class:`io.BufferedWriter`, and in + read/write mode, it returns an :class:`io.BufferedRandom`. When buffering is disabled, the raw stream, a subclass of :class:`io.RawIOBase`, :class:`io.FileIO`, is returned. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -100,7 +100,7 @@ Calling a :class:`GzipFile` object's :meth:`close` method does not close *fileobj*, since you might wish to append more material after the compressed - data. This also allows you to pass a :class:`io.BytesIO` object opened for + data. This also allows you to pass an :class:`io.BytesIO` object opened for writing as *fileobj*, and retrieve the resulting memory buffer using the :class:`io.BytesIO` object's :meth:`~io.BytesIO.getvalue` method. diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -176,7 +176,7 @@ The *response* object (usually the result of a call to :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info` - method, which returns a :class:`email.message.Message` instance. + method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) must support the methods :meth:`get_full_url`, :meth:`get_host`, diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -176,7 +176,7 @@ .. method:: handle_expect_100() - When a HTTP/1.1 compliant server receives a ``Expect: 100-continue`` + When a HTTP/1.1 compliant server receives an ``Expect: 100-continue`` request header it responds back with a ``100 Continue`` followed by ``200 OK`` headers. This method can be overridden to raise an error if the server does not @@ -210,7 +210,7 @@ are picked up from the :meth:`version_string` and :meth:`date_time_string` methods, respectively. If the server does not intend to send any other headers using the :meth:`send_header` method, - then :meth:`send_response` should be followed by a :meth:`end_headers` + then :meth:`send_response` should be followed by an :meth:`end_headers` call. .. versionchanged:: 3.3 diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -674,7 +674,7 @@ In Babyl mailboxes, the headers of a message are not stored contiguously with the body of the message. To generate a file-like representation, the - headers and body are copied together into a :class:`io.BytesIO` instance, + headers and body are copied together into an :class:`io.BytesIO` instance, which has an API identical to that of a file. As a result, the file-like object is truly independent of the underlying mailbox but does not save memory compared to a string diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1041,7 +1041,7 @@ readable. .. versionchanged:: 3.3 - This function used to raise a :exc:`IOError`, which is now an + This function used to raise :exc:`IOError`, which is now an alias of :exc:`OSError`. diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -341,7 +341,7 @@ .. method:: NNTP.over(message_spec, *, file=None) - Send a ``OVER`` command, or a ``XOVER`` command on legacy servers. + Send an ``OVER`` command, or an ``XOVER`` command on legacy servers. *message_spec* can be either a string representing a message id, or a ``(first, last)`` tuple of numbers indicating a range of articles in the current group, or a ``(first, None)`` tuple indicating a range of diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -1324,7 +1324,7 @@ the list of arguments to process (default: ``sys.argv[1:]``) ``values`` - a :class:`optparse.Values` object to store option arguments in (default: a + an :class:`optparse.Values` object to store option arguments in (default: a new instance of :class:`Values`) -- if you give an existing object, the option defaults will not be initialized on it diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -263,7 +263,7 @@ Return ``True`` if both pathname arguments refer to the same file or directory. This is determined by the device number and i-node number and raises an - exception if a :func:`os.stat` call on either pathname fails. + exception if an :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -221,7 +221,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file opened for - binary reading, a :class:`io.BytesIO` object, or any other custom object + binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -357,7 +357,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file object - opened for binary reading, a :class:`io.BytesIO` object, or any other + opened for binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -763,7 +763,7 @@ .. data:: XML_ERROR_UNDEFINED_ENTITY - A reference was made to a entity which was not defined. + A reference was made to an entity which was not defined. .. data:: XML_ERROR_UNKNOWN_ENCODING diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -206,8 +206,8 @@ and metadata of the linked files are copied to the new tree. When *symlinks* is false, if the file pointed by the symlink doesn't - exist, a exception will be added in the list of errors raised in - a :exc:`Error` exception at the end of the copy process. + exist, an exception will be added in the list of errors raised in + an :exc:`Error` exception at the end of the copy process. You can set the optional *ignore_dangling_symlinks* flag to true if you want to silence this exception. Notice that this option has no effect on platforms that don't support :func:`os.symlink`. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -22,7 +22,7 @@ .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) - A :class:`SMTP` instance encapsulates an SMTP connection. It has methods + An :class:`SMTP` instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP :meth:`connect` method is called with those parameters during initialization. If specified, @@ -65,7 +65,7 @@ certfile=None [, timeout], context=None, \ source_address=None) - A :class:`SMTP_SSL` instance behaves exactly the same as instances of + An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -693,7 +693,7 @@ Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the string *packed_ip* is not the correct length for the - specified address family, :exc:`ValueError` will be raised. A + specified address family, :exc:`ValueError` will be raised. :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. Availability: Unix (maybe not all platforms), Windows. @@ -969,7 +969,7 @@ interpreted the same way as by the built-in :func:`open` function. The socket must be in blocking mode; it can have a timeout, but the file - object's internal buffer may end up in a inconsistent state if a timeout + object's internal buffer may end up in an inconsistent state if a timeout occurs. Closing the file object returned by :meth:`makefile` won't close the diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -615,7 +615,7 @@ .. attribute:: lastrowid This read-only attribute provides the rowid of the last modified row. It is - only set if you issued a ``INSERT`` statement using the :meth:`execute` + only set if you issued an ``INSERT`` statement using the :meth:`execute` method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -951,7 +951,7 @@ runtime cost, you must switch to one of the alternatives below: * if concatenating :class:`str` objects, you can build a list and use - :meth:`str.join` at the end or else write to a :class:`io.StringIO` + :meth:`str.join` at the end or else write to an :class:`io.StringIO` instance and retrieve its value when complete * if concatenating :class:`bytes` objects, you can similarly use diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -54,8 +54,8 @@ Note that it does not allow read/write files. - A *mode* of ``'r'`` returns a :class:`AU_read` object, while a *mode* of ``'w'`` - or ``'wb'`` returns a :class:`AU_write` object. + A *mode* of ``'r'`` returns an :class:`AU_read` object, while a *mode* of ``'w'`` + or ``'wb'`` returns an :class:`AU_write` object. .. function:: openfp(file, mode) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -82,7 +82,7 @@ causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either a :class:`io.BytesIO` or :class:`io.StringIO` object (depending on + is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1105,7 +1105,7 @@ ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a :class:`io.StringIO` instance: +Another use case might be to replace an object with an :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -47,7 +47,7 @@ * :data:`PROCESSING_INSTRUCTION` * :data:`IGNORABLE_WHITESPACE` -``node`` is a object of type :class:`xml.dom.minidom.Document`, +``node`` is an object of type :class:`xml.dom.minidom.Document`, :class:`xml.dom.minidom.Element` or :class:`xml.dom.minidom.Text`. Since the document is treated as a "flat" stream of events, the document "tree" diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -336,7 +336,7 @@ A *finally clause* is always executed before leaving the :keyword:`try` statement, whether an exception has occurred or not. When an exception has occurred in the :keyword:`try` clause and has not been handled by an -:keyword:`except` clause (or it has occurred in a :keyword:`except` or +:keyword:`except` clause (or it has occurred in an :keyword:`except` or :keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has been executed. The :keyword:`finally` clause is also executed "on the way out" when any other clause of the :keyword:`try` statement is left via a diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -303,7 +303,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is 2. -Attempting to use a index that is too large will result in an error:: +Attempting to use an index that is too large will result in an error:: >>> word[42] # the word only has 6 characters Traceback (most recent call last): diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -555,7 +555,7 @@ and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a ``upload`` option that would automatically upload your +could support an ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -411,7 +411,7 @@ A new built-in function, :func:`enumerate`, will make certain loops a bit clearer. ``enumerate(thing)``, where *thing* is either an iterator or a -sequence, returns a iterator that will return ``(0, thing[0])``, ``(1, +sequence, returns an iterator that will return ``(0, thing[0])``, ``(1, thing[1])``, ``(2, thing[2])``, and so forth. A common idiom to change every element of a list looks like this:: diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -336,7 +336,7 @@ (Contributed by David Laban; :issue:`4739`.) * The :mod:`unittest` module now supports skipping individual tests or classes - of tests. And it supports marking a test as a expected failure, a test that + of tests. And it supports marking a test as an expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a TestResult:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -788,7 +788,7 @@ :issue:`8814`.) * To help write classes with rich comparison methods, a new decorator - :func:`functools.total_ordering` will use a existing equality and inequality + :func:`functools.total_ordering` will use existing equality and inequality methods to fill in the remaining methods. For example, supplying *__eq__* and *__lt__* will enable @@ -1399,7 +1399,7 @@ Also, the :class:`zipfile.ZipExtFile` class was reworked internally to represent files stored inside an archive. The new implementation is significantly faster -and can be wrapped in a :class:`io.BufferedReader` object for more speedups. It +and can be wrapped in an :class:`io.BufferedReader` object for more speedups. It also solves an issue where interleaved calls to *read* and *readline* gave the wrong results. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1421,7 +1421,7 @@ :class:`http.client.HTTPResponse` now has a :meth:`~http.client.HTTPResponse.readinto` method, which means it can be used -as a :class:`io.RawIOBase` class. (Contributed by John Kuhn in +as an :class:`io.RawIOBase` class. (Contributed by John Kuhn in :issue:`13464`.) diff --git a/Include/abstract.h b/Include/abstract.h --- a/Include/abstract.h +++ b/Include/abstract.h @@ -95,7 +95,7 @@ numeric, sequence, and mapping. Each protocol consists of a collection of related operations. If an operation that is not provided by a particular type is invoked, then a standard exception, - NotImplementedError is raised with a operation name as an argument. + NotImplementedError is raised with an operation name as an argument. In addition, for convenience this interface defines a set of constructors for building objects of built-in types. This is needed so new objects can be returned from C functions that otherwise treat diff --git a/Include/codecs.h b/Include/codecs.h --- a/Include/codecs.h +++ b/Include/codecs.h @@ -165,14 +165,14 @@ const char *encoding ); -/* Get a IncrementalEncoder object for the given encoding. */ +/* Get an IncrementalEncoder object for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( const char *encoding, const char *errors ); -/* Get a IncrementalDecoder object function for the given encoding. */ +/* Get an IncrementalDecoder object function for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( const char *encoding, diff --git a/Lib/_pyio.py b/Lib/_pyio.py --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -2101,7 +2101,7 @@ def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, - # that's a implementation detail. + # that's an implementation detail. return object.__repr__(self) @property diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -255,7 +255,7 @@ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol - # drain() expects that the reader has a exception() method + # drain() expects that the reader has an exception() method assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop diff --git a/Lib/calendar.py b/Lib/calendar.py --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -142,7 +142,7 @@ def iterweekdays(self): """ - Return a iterator for one week of weekday numbers starting with the + Return an iterator for one week of weekday numbers starting with the configured first one. """ for i in range(self.firstweekday, self.firstweekday + 7): diff --git a/Lib/chunk.py b/Lib/chunk.py --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -21,7 +21,7 @@ usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end -of the file, creating a new instance will fail with a EOFError +of the file, creating a new instance will fail with an EOFError exception. Usage: diff --git a/Lib/codecs.py b/Lib/codecs.py --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -256,7 +256,7 @@ """ def __init__(self, errors='strict'): """ - Create a IncrementalDecoder instance. + Create an IncrementalDecoder instance. The IncrementalDecoder may use different error handling schemes by providing the errors keyword argument. See the module docstring @@ -1007,7 +1007,7 @@ """ Encoding iterator. - Encodes the input strings from the iterator using a IncrementalEncoder. + Encodes the input strings from the iterator using an IncrementalEncoder. errors and kwargs are passed through to the IncrementalEncoder constructor. @@ -1025,7 +1025,7 @@ """ Decoding iterator. - Decodes the input strings from the iterator using a IncrementalDecoder. + Decodes the input strings from the iterator using an IncrementalDecoder. errors and kwargs are passed through to the IncrementalDecoder constructor. diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -518,7 +518,7 @@ raise NotImplementedError() def map(self, fn, *iterables, timeout=None): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/difflib.py b/Lib/difflib.py --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1469,7 +1469,7 @@ yield _make_line(lines,'-',0), None, True continue elif s.startswith(('--?+', '--+', '- ')): - # in delete block and see a intraline change or unchanged line + # in delete block and see an intraline change or unchanged line # coming: yield the delete line and then blanks from_line,to_line = _make_line(lines,'-',0), None num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py --- a/Lib/distutils/cygwinccompiler.py +++ b/Lib/distutils/cygwinccompiler.py @@ -10,9 +10,9 @@ # # * if you use a msvc compiled python version (1.5.2) # 1. you have to insert a __GNUC__ section in its config.h -# 2. you have to generate a import library for its dll +# 2. you have to generate an import library for its dll # - create a def-file for python??.dll -# - create a import library using +# - create an import library using # dlltool --dllname python15.dll --def python15.def \ # --output-lib libpython15.a # @@ -318,7 +318,7 @@ self.dll_libraries = get_msvcr() # Because these compilers aren't configured in Python's pyconfig.h file by -# default, we should at least warn the user if he is using a unmodified +# default, we should at least warn the user if he is using an unmodified # version. CONFIG_H_OK = "ok" diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -287,7 +287,7 @@ return self.voidcmd(cmd) def sendeprt(self, host, port): - '''Send a EPRT command with the current host and the given port number.''' + '''Send an EPRT command with the current host and the given port number.''' af = 0 if self.af == socket.AF_INET: af = 1 @@ -852,7 +852,7 @@ def parse229(resp, peer): - '''Parse the '229' response for a EPSV request. + '''Parse the '229' response for an EPSV request. Raises error_proto if it does not contain '(|||port|)' Return ('host.addr.as.numbers', port#) tuple.''' diff --git a/Lib/getopt.py b/Lib/getopt.py --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -28,7 +28,7 @@ # - RETURN_IN_ORDER option # - GNU extension with '-' as first character of option string # - optional arguments, specified by double colons -# - a option string with a W followed by semicolon should +# - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" __all__ = ["GetoptError","error","getopt","gnu_getopt"] diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1379,7 +1379,7 @@ text.see("insert") text.undo_block_stop() - # Our editwin provides a is_char_in_string function that works + # Our editwin provides an is_char_in_string function that works # with a Tk text index, but PyParse only knows about offsets into # a string. This builds a function for PyParse that accepts an # offset. diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -59,7 +59,7 @@ def default_command(self, event=None): if self.do_find(self.ok): if self.do_replace(): # Only find next match if replace succeeded. - # A bad re can cause a it to fail. + # A bad re can cause it to fail. self.do_find(0) def _replace_expand(self, m, repl): diff --git a/Lib/io.py b/Lib/io.py --- a/Lib/io.py +++ b/Lib/io.py @@ -19,7 +19,7 @@ Another IOBase subclass, TextIOBase, deals with the encoding and decoding of streams into text. TextIOWrapper, which extends it, is a buffered text interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO -is a in-memory stream for text. +is an in-memory stream for text. Argument names are not part of the specification, and only the arguments of open() are intended to be used as keyword arguments. diff --git a/Lib/lib2to3/fixes/fix_input.py b/Lib/lib2to3/fixes/fix_input.py --- a/Lib/lib2to3/fixes/fix_input.py +++ b/Lib/lib2to3/fixes/fix_input.py @@ -17,7 +17,7 @@ """ def transform(self, node, results): - # If we're already wrapped in a eval() call, we're done. + # If we're already wrapped in an eval() call, we're done. if context.match(node.parent.parent): return diff --git a/Lib/nntplib.py b/Lib/nntplib.py --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -201,7 +201,7 @@ return fmt def _parse_overview(lines, fmt, data_process_func=None): - """Parse the response to a OVER or XOVER command according to the + """Parse the response to an OVER or XOVER command according to the overview format `fmt`.""" n_defaults = len(_DEFAULT_OVERVIEW_FMT) overview = [] diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -362,7 +362,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for - binary writing, a io.BytesIO instance, or any other custom + binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and *protocol* is less than 3, pickle @@ -983,7 +983,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* - can be a binary file object opened for reading, a io.BytesIO + can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method diff --git a/Lib/test/decimaltestdata/fma.decTest b/Lib/test/decimaltestdata/fma.decTest --- a/Lib/test/decimaltestdata/fma.decTest +++ b/Lib/test/decimaltestdata/fma.decTest @@ -148,7 +148,7 @@ fmax2019 fma -9.999999 9.999999 0E+999999 -> -100.000 Inexact Rounded fmax2020 fma -9.999999 -9.999999 0E+999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 fmax2059 fma 999999999999 9765625 0E+999999 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/decimaltestdata/multiply.decTest b/Lib/test/decimaltestdata/multiply.decTest --- a/Lib/test/decimaltestdata/multiply.decTest +++ b/Lib/test/decimaltestdata/multiply.decTest @@ -49,7 +49,7 @@ mulx019 multiply -9.999999999 9.999999999 -> -100.000 Inexact Rounded mulx020 multiply -9.999999999 -9.999999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 mulx059 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py --- a/Lib/test/pystone.py +++ b/Lib/test/pystone.py @@ -35,7 +35,7 @@ Under Python 3 version 1.1 would use the normal division operator, resulting in some of the operations mistakenly yielding floats. Version 1.2 instead uses floor division - making the benchmark a integer benchmark again. + making the benchmark an integer benchmark again. """ diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -309,7 +309,7 @@ # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. - # Testing on a i7 at 4.3GHz shows that usually only 1 iteration is + # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -110,7 +110,7 @@ 5 12 19 6 13 - This is a interactive test, put some commands in the cmdqueue attribute + This is an interactive test, put some commands in the cmdqueue attribute and let it execute This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -97,7 +97,7 @@ self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - # do the check again, this time using a incremental decoder + # do the check again, this time using an incremental decoder d = codecs.getincrementaldecoder(self.encoding)() result = "" for (c, partialresult) in zip(input.encode(self.encoding), partialresults): diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3037,7 +3037,7 @@ # issue 1690608. email.utils.formataddr() should be rfc2047 aware. name = "H\u00e4ns W\u00fcrst" addr = 'person at dom.ain' - # A object without a header_encode method: + # An object without a header_encode method: bad_charset = object() self.assertRaises(AttributeError, utils.formataddr, (name, addr), bad_charset) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1160,7 +1160,7 @@ # test a /24 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1.1.1.0/24')) - # test an IPv4 range that isn't on a network byte boundary + # test an IPv4 range that isn't on a network byte boundary ip2 = ipaddress.ip_address('1.1.1.8') self.assertEqual(list(summarize(ip1, ip2)), [ipaddress.ip_network('1.1.1.0/29'), @@ -1173,7 +1173,7 @@ ip1 = ipaddress.ip_address('1::') ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - # test a IPv6 is sumamrized properly + # test an IPv6 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1::/16')) # test an IPv6 range that isn't on a network byte boundary diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1328,7 +1328,7 @@ except OSError as e: self.assertEqual(e.errno, errno.EBADF) else: - self.fail("%r didn't raise a OSError with a bad file descriptor" + self.fail("%r didn't raise an OSError with a bad file descriptor" % f) @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()') diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -523,7 +523,7 @@ result = urllib.request.urlretrieve("file:%s" % support.TESTFN) self.assertEqual(result[0], support.TESTFN) self.assertIsInstance(result[1], email.message.Message, - "did not get a email.message.Message instance " + "did not get an email.message.Message instance " "as second returned value") def test_copy(self): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -934,7 +934,7 @@ class WeakMethodTestCase(unittest.TestCase): def _subclass(self): - """Return a Object subclass overriding `some_method`.""" + """Return an Object subclass overriding `some_method`.""" class C(Object): def some_method(self): return 6 diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -289,7 +289,7 @@ """Format options then call Tk command with args and options and return the appropriate result. - If no option is specified, a dict is returned. If a option is + If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -831,7 +831,7 @@ raise ValueError("unexpected type in multicall result") class MultiCall: - """server -> a object used to boxcar method calls + """server -> an object used to boxcar method calls server should be a ServerProxy object. @@ -1184,7 +1184,7 @@ ## # Create parser. # - # @return A 2-tuple containing a parser and a unmarshaller. + # @return A 2-tuple containing a parser and an unmarshaller. def getparser(self): # get parser and unmarshaller diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1316,7 +1316,7 @@ import as they are meant for use by importlib. - Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. + while writing error message if the thread leaves an unhandled exception. - Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch by Suman Saha. @@ -1967,7 +1967,7 @@ - Issue #7732: Don't open a directory as a file anymore while importing a module. Ignore the directory if its name matches the module name (e.g. - "__init__.py") and raise a ImportError instead. + "__init__.py") and raise an ImportError instead. - Issue #13021: Missing decref on an error path. Thanks to Suman Saha for finding the bug and providing a patch. @@ -2019,7 +2019,7 @@ - Issue #10271: Allow warnings.showwarning() be any callable. -- Issue #11627: Fix segfault when __new__ on a exception returns a +- Issue #11627: Fix segfault when __new__ on an exception returns a non-exception class. - Issue #12149: Update the method cache after a type's dictionary gets @@ -2048,7 +2048,7 @@ with other data interleaved between marshalled objects. - Issue #12356: When required positional or keyword-only arguments are not - given, produce a informative error message which includes the name(s) of the + given, produce an informative error message which includes the name(s) of the missing arguments. - Issue #12370: Fix super with no arguments when __class__ is overriden in the @@ -2703,7 +2703,7 @@ - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and semicolons together. Patch by Ben Darnell and Petri Lehtinen. -- Issue #13227: functools.lru_cache() now has a option to distinguish +- Issue #13227: functools.lru_cache() now has an option to distinguish calls with different argument types. - Issue #6090: zipfile raises a ValueError when a document with a timestamp @@ -2981,7 +2981,7 @@ - Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. -- Issue #4376: ctypes now supports nested structures in a endian different than +- Issue #4376: ctypes now supports nested structures in an endian different than the parent structure. Patch by Vlad Riscutia. - Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a @@ -3002,7 +3002,7 @@ Linux for example, to have the same behaviour on all platforms. - Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie + Python scripts using an encoding different than UTF-8 (read the coding cookie of the script). - Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors @@ -5080,7 +5080,7 @@ ``MaybeEncodingError`` exception. - Issue #9244: The ``apply_async()`` and ``map_async()`` methods of - ``multiprocessing.Pool`` now accepts a ``error_callback`` argument. This can + ``multiprocessing.Pool`` now accepts an ``error_callback`` argument. This can be a callback with the signature ``callback(exc)``, which will be called if the target raises an exception. @@ -5177,7 +5177,7 @@ - Close file objects in modulefinder in a timely manner. -- Close a io.TextIOWrapper object in email.parser in a timely manner. +- Close an io.TextIOWrapper object in email.parser in a timely manner. - Close a file object in distutils.sysconfig in a timely manner. @@ -7275,7 +7275,7 @@ - Issue #7610: Reworked implementation of the internal ``zipfile.ZipExtFile`` class used to represent files stored inside an archive. The new implementation is significantly faster and can be wrapped in - a ``io.BufferedReader`` object for more speedups. It also solves an + an ``io.BufferedReader`` object for more speedups. It also solves an issue where interleaved calls to `read()` and `readline()` give wrong results. Patch by Nir Aides. @@ -8650,7 +8650,7 @@ - Issue #5624: Fix the _winreg module name still used in several modules. -- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. +- Issue #5628: Fix io.TextIOWrapper.read() with an unreadable buffer. - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. @@ -9616,7 +9616,7 @@ - Issue #4307: The named tuple that ``inspect.getfullargspec()`` returns now uses ``kwonlydefaults`` instead of ``kwdefaults``. -- Issue #4298: Fix a segfault when pickle.loads is passed a ill-formed input. +- Issue #4298: Fix a segfault when pickle.loads is passed ill-formed input. - Issue #4283: Fix a left-over "iteritems" call in distutils. @@ -11272,7 +11272,7 @@ ----------------- - Bug #1441486: The literal representation of -(sys.maxint - 1) - again evaluates to a int object, not a long. + again evaluates to an int object, not a long. - Bug #1501934: The scope of global variables that are locally assigned using augmented assignment is now correctly determined. @@ -15179,7 +15179,7 @@ interpreter executions, would fail. - "%c" % u"a" now returns a unicode string instead of raising a - TypeError. u"%c" % 0xffffffff now raises a OverflowError instead + TypeError. u"%c" % 0xffffffff now raises an OverflowError instead of a ValueError to be consistent with "%c" % 256. See SF patch #710127. Extension modules @@ -23072,7 +23072,7 @@ - The interfaces for the bind*() and unbind() widget methods have been redesigned; the bind*() methods now return the name of the Tcl command -created for the callback, and this can be passed as a optional +created for the callback, and this can be passed as an optional argument to unbind() in order to delete the command (normally, such commands are automatically unbound when the widget is destroyed, but for some applications this isn't enough). diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -616,7 +616,7 @@ Tests ----- -- Issue #25099: Make test_compileall not fail when a entry on sys.path cannot +- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). - Issue #24751: When running regrtest with the ``-w`` command line option, diff --git a/Modules/_ctypes/libffi/src/x86/darwin64.S b/Modules/_ctypes/libffi/src/x86/darwin64.S --- a/Modules/_ctypes/libffi/src/x86/darwin64.S +++ b/Modules/_ctypes/libffi/src/x86/darwin64.S @@ -350,7 +350,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi/src/x86/unix64.S b/Modules/_ctypes/libffi/src/x86/unix64.S --- a/Modules/_ctypes/libffi/src/x86/unix64.S +++ b/Modules/_ctypes/libffi/src/x86/unix64.S @@ -366,7 +366,7 @@ .byte 0x4 /* DW_CFA_advance_loc4 */ .long .LUW1-.LUW0 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -351,7 +351,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -706,7 +706,7 @@ if (openssl_obj_name == NULL) return; /* Ignore aliased names, they pollute the list and OpenSSL appears to - * have a its own definition of alias as the resulting list still + * have its own definition of alias as the resulting list still * contains duplicate and alternate names for several algorithms. */ if (openssl_obj_name->alias) return; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -75,7 +75,7 @@ "Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" "of streams into text. TextIOWrapper, which extends it, is a buffered text\n" "interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" +"is an in-memory stream for text.\n" "\n" "Argument names are not part of the specification, and only the arguments\n" "of open() are intended to be used as keyword arguments.\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -931,8 +931,8 @@ if (self->encoding == NULL) { catch_ImportError: /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a + Importing locale can raise an ImportError because of + _functools, and locale.getpreferredencoding can raise an ImportError if _locale is not available. These will happen during module building. */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4032,7 +4032,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -4042,7 +4042,7 @@ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=56e229f3b1f4332f input=b8cdeb7e3f5ee674]*/ +/*[clinic end generated code: output=56e229f3b1f4332f input=4faabdbc763c2389]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -6443,7 +6443,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -6458,7 +6458,7 @@ static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=b9ed1d84d315f3b5 input=30b4dc9e976b890c]*/ +/*[clinic end generated code: output=b9ed1d84d315f3b5 input=04ece661aa884837]*/ { _Py_IDENTIFIER(persistent_load); @@ -6877,7 +6877,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -6887,7 +6887,7 @@ static PyObject * _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=a606e626d553850d input=e9e5fdd48de92eae]*/ +/*[clinic end generated code: output=a606e626d553850d input=830f8a64cef6f042]*/ { PicklerObject *pickler = _Pickler_New(); @@ -6985,7 +6985,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -7000,7 +7000,7 @@ static PyObject * _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=568c61356c172654 input=da97372e38e510a6]*/ +/*[clinic end generated code: output=568c61356c172654 input=2df7c7a1e6742204]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -257,7 +257,7 @@ PyDoc_STRVAR(atexit_unregister__doc__, "unregister(func) -> None\n\ \n\ -Unregister a exit function which was previously registered using\n\ +Unregister an exit function which was previously registered using\n\ atexit.register\n\ \n\ func - function to be unregistered"); diff --git a/Modules/audioop.c b/Modules/audioop.c --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -112,7 +112,7 @@ /* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * @@ -218,7 +218,7 @@ /* * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 13-bits. * diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -77,7 +77,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -258,7 +258,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -366,7 +366,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -459,7 +459,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -542,4 +542,4 @@ exit: return return_value; } -/*[clinic end generated code: output=3aba79576e240c62 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=1ba210152e2261d8 input=a9049054013a1b77]*/ diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -21,7 +21,7 @@ * * * The Solution: - * Prefix all a exported symbols with "PyExpat_". This is similar to + * Prefix all exported symbols with "PyExpat_". This is similar to * what Mozilla does for some common libs: * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115 * diff --git a/Modules/hashlib.h b/Modules/hashlib.h --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -30,7 +30,7 @@ /* * Helper code to synchronize access to the hash object when the GIL is * released around a CPU consuming hashlib operation. All code paths that - * access a mutable part of obj must be enclosed in a ENTER_HASHLIB / + * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / * LEAVE_HASHLIB block or explicitly acquire and release the lock inside * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for * an operation. diff --git a/Modules/readline.c b/Modules/readline.c --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1195,7 +1195,7 @@ return NULL; } - /* We got an EOF, return a empty string. */ + /* We got an EOF, return an empty string. */ if (p == NULL) { p = PyMem_RawMalloc(1); if (p != NULL) diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1243,7 +1243,7 @@ if (truncated == NULL || PyLong_Check(truncated)) return truncated; /* __trunc__ is specified to return an Integral type, - but int() needs to return a int. */ + but int() needs to return an int. */ m = truncated->ob_type->tp_as_number; if (m == NULL || m->nb_int == NULL) { PyErr_Format( diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -867,7 +867,7 @@ static int oserror_use_init(PyTypeObject *type) { - /* When __init__ is defined in a OSError subclass, we want any + /* When __init__ is defined in an OSError subclass, we want any extraneous argument to __new__ to be ignored. The only reasonable solution, given __new__ takes a variable number of arguments, is to defer arg parsing and initialization to __init__. diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -549,7 +549,7 @@ return 0; } if (u->u_ste->ste_needs_class_closure) { - /* Cook up a implicit __class__ cell. */ + /* Cook up an implicit __class__ cell. */ _Py_IDENTIFIER(__class__); PyObject *tuple, *name, *zero; int res; diff --git a/Python/thread.c b/Python/thread.c --- a/Python/thread.c +++ b/Python/thread.c @@ -31,7 +31,7 @@ threads. This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on a ia64 system instead + a check of __ia64 to verify that we're running on an ia64 system instead of a pa-risc system. */ #ifdef __hpux diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -91,7 +91,7 @@ def safety_limit(val): - # Given a integer value from the process being debugged, limit it to some + # Given an integer value from the process being debugged, limit it to some # safety threshold so that arbitrary breakage within said process doesn't # break the gdb process too much (e.g. sizes of iterations, sizes of lists) return min(val, 1000) @@ -158,7 +158,7 @@ class PyObjectPtr(object): """ - Class wrapping a gdb.Value that's a either a (PyObject*) within the + Class wrapping a gdb.Value that's either a (PyObject*) within the inferior process, or some subclass pointer e.g. (PyBytesObject*) There will be a subclass for every refined PyObject type that we care -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 23:29:16 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 02 Nov 2015 04:29:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325523=3A_Merge_=22a=22_to_=22an=22_fixes_from_3=2E4_i?= =?utf-8?q?nto_3=2E5?= Message-ID: <20151102042916.74111.60149@psf.io> https://hg.python.org/cpython/rev/e279ab6753fd changeset: 98929:e279ab6753fd branch: 3.5 parent: 98925:321b34824020 parent: 98928:d8ff13414deb user: Martin Panter date: Mon Nov 02 04:04:57 2015 +0000 summary: Issue #25523: Merge "a" to "an" fixes from 3.4 into 3.5 files: Doc/c-api/buffer.rst | 2 +- Doc/faq/programming.rst | 2 +- Doc/library/chunk.rst | 2 +- Doc/library/concurrent.futures.rst | 4 +- Doc/library/ctypes.rst | 2 +- Doc/library/difflib.rst | 2 +- Doc/library/fcntl.rst | 6 +- Doc/library/ftplib.rst | 4 +- Doc/library/functions.rst | 6 +- Doc/library/gzip.rst | 2 +- Doc/library/http.cookiejar.rst | 2 +- Doc/library/http.server.rst | 4 +- Doc/library/mailbox.rst | 2 +- Doc/library/multiprocessing.rst | 2 +- Doc/library/nntplib.rst | 2 +- Doc/library/optparse.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/pickle.rst | 4 +- Doc/library/pyexpat.rst | 2 +- Doc/library/shutil.rst | 4 +- Doc/library/smtplib.rst | 4 +- Doc/library/socket.rst | 4 +- Doc/library/sqlite3.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sunau.rst | 4 +- Doc/library/tempfile.rst | 2 +- Doc/library/unittest.mock.rst | 2 +- Doc/library/xml.dom.pulldom.rst | 2 +- Doc/tutorial/errors.rst | 2 +- Doc/tutorial/introduction.rst | 2 +- Doc/whatsnew/2.1.rst | 2 +- Doc/whatsnew/2.3.rst | 2 +- Doc/whatsnew/3.1.rst | 2 +- Doc/whatsnew/3.2.rst | 4 +- Doc/whatsnew/3.3.rst | 2 +- Include/abstract.h | 2 +- Include/codecs.h | 4 +- Lib/_pyio.py | 2 +- Lib/asyncio/streams.py | 2 +- Lib/calendar.py | 2 +- Lib/chunk.py | 2 +- Lib/codecs.py | 6 +- Lib/concurrent/futures/_base.py | 2 +- Lib/difflib.py | 2 +- Lib/distutils/cygwinccompiler.py | 6 +- Lib/ftplib.py | 4 +- Lib/getopt.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/ReplaceDialog.py | 2 +- Lib/io.py | 2 +- Lib/lib2to3/fixes/fix_input.py | 2 +- Lib/nntplib.py | 2 +- Lib/pickle.py | 4 +- Lib/test/decimaltestdata/fma.decTest | 1 + Lib/test/decimaltestdata/multiply.decTest | 1 + Lib/test/pystone.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_cmd.py | 2 +- Lib/test/test_codecs.py | 2 +- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_ipaddress.py | 4 +- Lib/test/test_os.py | 2 +- Lib/test/test_urllib.py | 2 +- Lib/test/test_weakref.py | 2 +- Lib/tkinter/ttk.py | 2 +- Lib/xmlrpc/client.py | 4 +- Misc/HISTORY | 30 +++++----- Misc/NEWS | 2 +- Modules/_ctypes/libffi/src/x86/darwin64.S | 2 +- Modules/_ctypes/libffi/src/x86/unix64.S | 2 +- Modules/_ctypes/libffi_osx/x86/darwin64.S | 2 +- Modules/_hashopenssl.c | 2 +- Modules/_io/_iomodule.c | 2 +- Modules/_io/textio.c | 4 +- Modules/_pickle.c | 16 ++-- Modules/atexitmodule.c | 2 +- Modules/audioop.c | 4 +- Modules/clinic/_pickle.c.h | 10 +- Modules/expat/pyexpatns.h | 2 +- Modules/hashlib.h | 2 +- Modules/readline.c | 2 +- Objects/abstract.c | 2 +- Objects/exceptions.c | 2 +- Python/compile.c | 2 +- Python/thread.c | 2 +- Tools/gdb/libpython.py | 4 +- 86 files changed, 136 insertions(+), 134 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -40,7 +40,7 @@ Simple objects such as :class:`bytes` and :class:`bytearray` expose their underlying buffer in byte-oriented form. Other forms are possible; for example, -the elements exposed by a :class:`array.array` can be multi-byte values. +the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -849,7 +849,7 @@ You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place -unicode data, try using a :class:`io.StringIO` object or the :mod:`array` +unicode data, try using an :class:`io.StringIO` object or the :mod:`array` module:: >>> import io diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -47,7 +47,7 @@ the :class:`Chunk` class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end of the file, creating a new -instance will fail with a :exc:`EOFError` exception. +instance will fail with an :exc:`EOFError` exception. .. class:: Chunk(file, align=True, bigendian=True, inclheader=False) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -90,7 +90,7 @@ ThreadPoolExecutor ------------------ -:class:`ThreadPoolExecutor` is a :class:`Executor` subclass that uses a pool of +:class:`ThreadPoolExecutor` is an :class:`Executor` subclass that uses a pool of threads to execute calls asynchronously. Deadlocks can occur when the callable associated with a :class:`Future` waits on @@ -304,7 +304,7 @@ Added callables are called in the order that they were added and are always called in a thread belonging to the process that added them. If - the callable raises a :exc:`Exception` subclass, it will be logged and + the callable raises an :exc:`Exception` subclass, it will be logged and ignored. If the callable raises a :exc:`BaseException` subclass, the behavior is undefined. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -39,7 +39,7 @@ convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`HRESULT` error code. The error -code is used to automatically raise a :class:`OSError` exception when the +code is used to automatically raise an :class:`OSError` exception when the function call fails. .. versionchanged:: 3.3 diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -278,7 +278,7 @@ generating the delta lines) in unified diff format. Unified diffs are a compact way of showing just the lines that have changed plus - a few lines of context. The changes are shown in a inline style (instead of + a few lines of context. The changes are shown in an inline style (instead of separate before/after blocks). The number of context lines is set by *n* which defaults to three. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -16,13 +16,13 @@ All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by -``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin`` +``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` itself, which provides a :meth:`~io.IOBase.fileno` that returns a genuine file descriptor. .. versionchanged:: 3.3 - Operations in this module used to raise a :exc:`IOError` where they now - raise a :exc:`OSError`. + Operations in this module used to raise an :exc:`IOError` where they now + raise an :exc:`OSError`. The module defines the following functions: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -287,9 +287,9 @@ .. method:: FTP.transfercmd(cmd, rest=None) - Initiate a transfer over the data connection. If the transfer is active, send a + Initiate a transfer over the data connection. If the transfer is active, send an ``EPRT`` or ``PORT`` command and the transfer command specified by *cmd*, and - accept the connection. If the server is passive, send a ``EPSV`` or ``PASV`` + accept the connection. If the server is passive, send an ``EPSV`` or ``PASV`` command, connect to it, and start the transfer command. Either way, return the socket for the connection. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1032,9 +1032,9 @@ :class:`io.TextIOBase` (specifically :class:`io.TextIOWrapper`). When used to open a file in a binary mode with buffering, the returned class is a subclass of :class:`io.BufferedIOBase`. The exact class varies: in read - binary mode, it returns a :class:`io.BufferedReader`; in write binary and - append binary modes, it returns a :class:`io.BufferedWriter`, and in - read/write mode, it returns a :class:`io.BufferedRandom`. When buffering is + binary mode, it returns an :class:`io.BufferedReader`; in write binary and + append binary modes, it returns an :class:`io.BufferedWriter`, and in + read/write mode, it returns an :class:`io.BufferedRandom`. When buffering is disabled, the raw stream, a subclass of :class:`io.RawIOBase`, :class:`io.FileIO`, is returned. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -96,7 +96,7 @@ Calling a :class:`GzipFile` object's :meth:`close` method does not close *fileobj*, since you might wish to append more material after the compressed - data. This also allows you to pass a :class:`io.BytesIO` object opened for + data. This also allows you to pass an :class:`io.BytesIO` object opened for writing as *fileobj*, and retrieve the resulting memory buffer using the :class:`io.BytesIO` object's :meth:`~io.BytesIO.getvalue` method. diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -176,7 +176,7 @@ The *response* object (usually the result of a call to :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info` - method, which returns a :class:`email.message.Message` instance. + method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) must support the methods :meth:`get_full_url`, :meth:`get_host`, diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -176,7 +176,7 @@ .. method:: handle_expect_100() - When a HTTP/1.1 compliant server receives a ``Expect: 100-continue`` + When a HTTP/1.1 compliant server receives an ``Expect: 100-continue`` request header it responds back with a ``100 Continue`` followed by ``200 OK`` headers. This method can be overridden to raise an error if the server does not @@ -210,7 +210,7 @@ are picked up from the :meth:`version_string` and :meth:`date_time_string` methods, respectively. If the server does not intend to send any other headers using the :meth:`send_header` method, - then :meth:`send_response` should be followed by a :meth:`end_headers` + then :meth:`send_response` should be followed by an :meth:`end_headers` call. .. versionchanged:: 3.3 diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -674,7 +674,7 @@ In Babyl mailboxes, the headers of a message are not stored contiguously with the body of the message. To generate a file-like representation, the - headers and body are copied together into a :class:`io.BytesIO` instance, + headers and body are copied together into an :class:`io.BytesIO` instance, which has an API identical to that of a file. As a result, the file-like object is truly independent of the underlying mailbox but does not save memory compared to a string diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1041,7 +1041,7 @@ readable. .. versionchanged:: 3.3 - This function used to raise a :exc:`IOError`, which is now an + This function used to raise :exc:`IOError`, which is now an alias of :exc:`OSError`. diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -341,7 +341,7 @@ .. method:: NNTP.over(message_spec, *, file=None) - Send a ``OVER`` command, or a ``XOVER`` command on legacy servers. + Send an ``OVER`` command, or an ``XOVER`` command on legacy servers. *message_spec* can be either a string representing a message id, or a ``(first, last)`` tuple of numbers indicating a range of articles in the current group, or a ``(first, None)`` tuple indicating a range of diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -1324,7 +1324,7 @@ the list of arguments to process (default: ``sys.argv[1:]``) ``values`` - a :class:`optparse.Values` object to store option arguments in (default: a + an :class:`optparse.Values` object to store option arguments in (default: a new instance of :class:`Values`) -- if you give an existing object, the option defaults will not be initialized on it diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -289,7 +289,7 @@ Return ``True`` if both pathname arguments refer to the same file or directory. This is determined by the device number and i-node number and raises an - exception if a :func:`os.stat` call on either pathname fails. + exception if an :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -221,7 +221,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file opened for - binary reading, a :class:`io.BytesIO` object, or any other custom object + binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -357,7 +357,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file object - opened for binary reading, a :class:`io.BytesIO` object, or any other + opened for binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -763,7 +763,7 @@ .. data:: XML_ERROR_UNDEFINED_ENTITY - A reference was made to a entity which was not defined. + A reference was made to an entity which was not defined. .. data:: XML_ERROR_UNKNOWN_ENCODING diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -207,8 +207,8 @@ and metadata of the linked files are copied to the new tree. When *symlinks* is false, if the file pointed by the symlink doesn't - exist, a exception will be added in the list of errors raised in - a :exc:`Error` exception at the end of the copy process. + exist, an exception will be added in the list of errors raised in + an :exc:`Error` exception at the end of the copy process. You can set the optional *ignore_dangling_symlinks* flag to true if you want to silence this exception. Notice that this option has no effect on platforms that don't support :func:`os.symlink`. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -22,7 +22,7 @@ .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) - A :class:`SMTP` instance encapsulates an SMTP connection. It has methods + An :class:`SMTP` instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP :meth:`connect` method is called with those parameters during initialization. If specified, @@ -69,7 +69,7 @@ certfile=None [, timeout], context=None, \ source_address=None) - A :class:`SMTP_SSL` instance behaves exactly the same as instances of + An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -715,7 +715,7 @@ Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the bytes object *packed_ip* is not the correct length for the specified address family, :exc:`ValueError` will be raised. - A :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. + :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. Availability: Unix (maybe not all platforms), Windows. @@ -1014,7 +1014,7 @@ interpreted the same way as by the built-in :func:`open` function. The socket must be in blocking mode; it can have a timeout, but the file - object's internal buffer may end up in a inconsistent state if a timeout + object's internal buffer may end up in an inconsistent state if a timeout occurs. Closing the file object returned by :meth:`makefile` won't close the diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -615,7 +615,7 @@ .. attribute:: lastrowid This read-only attribute provides the rowid of the last modified row. It is - only set if you issued a ``INSERT`` statement using the :meth:`execute` + only set if you issued an ``INSERT`` statement using the :meth:`execute` method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -951,7 +951,7 @@ runtime cost, you must switch to one of the alternatives below: * if concatenating :class:`str` objects, you can build a list and use - :meth:`str.join` at the end or else write to a :class:`io.StringIO` + :meth:`str.join` at the end or else write to an :class:`io.StringIO` instance and retrieve its value when complete * if concatenating :class:`bytes` objects, you can similarly use diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -54,8 +54,8 @@ Note that it does not allow read/write files. - A *mode* of ``'r'`` returns a :class:`AU_read` object, while a *mode* of ``'w'`` - or ``'wb'`` returns a :class:`AU_write` object. + A *mode* of ``'r'`` returns an :class:`AU_read` object, while a *mode* of ``'w'`` + or ``'wb'`` returns an :class:`AU_write` object. .. function:: openfp(file, mode) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -96,7 +96,7 @@ causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either a :class:`io.BytesIO` or :class:`io.StringIO` object (depending on + is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1131,7 +1131,7 @@ ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a :class:`io.StringIO` instance: +Another use case might be to replace an object with an :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -47,7 +47,7 @@ * :data:`PROCESSING_INSTRUCTION` * :data:`IGNORABLE_WHITESPACE` -``node`` is a object of type :class:`xml.dom.minidom.Document`, +``node`` is an object of type :class:`xml.dom.minidom.Document`, :class:`xml.dom.minidom.Element` or :class:`xml.dom.minidom.Text`. Since the document is treated as a "flat" stream of events, the document "tree" diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -336,7 +336,7 @@ A *finally clause* is always executed before leaving the :keyword:`try` statement, whether an exception has occurred or not. When an exception has occurred in the :keyword:`try` clause and has not been handled by an -:keyword:`except` clause (or it has occurred in a :keyword:`except` or +:keyword:`except` clause (or it has occurred in an :keyword:`except` or :keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has been executed. The :keyword:`finally` clause is also executed "on the way out" when any other clause of the :keyword:`try` statement is left via a diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -303,7 +303,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is 2. -Attempting to use a index that is too large will result in an error:: +Attempting to use an index that is too large will result in an error:: >>> word[42] # the word only has 6 characters Traceback (most recent call last): diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -555,7 +555,7 @@ and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a ``upload`` option that would automatically upload your +could support an ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -411,7 +411,7 @@ A new built-in function, :func:`enumerate`, will make certain loops a bit clearer. ``enumerate(thing)``, where *thing* is either an iterator or a -sequence, returns a iterator that will return ``(0, thing[0])``, ``(1, +sequence, returns an iterator that will return ``(0, thing[0])``, ``(1, thing[1])``, ``(2, thing[2])``, and so forth. A common idiom to change every element of a list looks like this:: diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -336,7 +336,7 @@ (Contributed by David Laban; :issue:`4739`.) * The :mod:`unittest` module now supports skipping individual tests or classes - of tests. And it supports marking a test as a expected failure, a test that + of tests. And it supports marking a test as an expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a TestResult:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -788,7 +788,7 @@ :issue:`8814`.) * To help write classes with rich comparison methods, a new decorator - :func:`functools.total_ordering` will use a existing equality and inequality + :func:`functools.total_ordering` will use existing equality and inequality methods to fill in the remaining methods. For example, supplying *__eq__* and *__lt__* will enable @@ -1399,7 +1399,7 @@ Also, the :class:`zipfile.ZipExtFile` class was reworked internally to represent files stored inside an archive. The new implementation is significantly faster -and can be wrapped in a :class:`io.BufferedReader` object for more speedups. It +and can be wrapped in an :class:`io.BufferedReader` object for more speedups. It also solves an issue where interleaved calls to *read* and *readline* gave the wrong results. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1421,7 +1421,7 @@ :class:`http.client.HTTPResponse` now has a :meth:`~http.client.HTTPResponse.readinto` method, which means it can be used -as a :class:`io.RawIOBase` class. (Contributed by John Kuhn in +as an :class:`io.RawIOBase` class. (Contributed by John Kuhn in :issue:`13464`.) diff --git a/Include/abstract.h b/Include/abstract.h --- a/Include/abstract.h +++ b/Include/abstract.h @@ -95,7 +95,7 @@ numeric, sequence, and mapping. Each protocol consists of a collection of related operations. If an operation that is not provided by a particular type is invoked, then a standard exception, - NotImplementedError is raised with a operation name as an argument. + NotImplementedError is raised with an operation name as an argument. In addition, for convenience this interface defines a set of constructors for building objects of built-in types. This is needed so new objects can be returned from C functions that otherwise treat diff --git a/Include/codecs.h b/Include/codecs.h --- a/Include/codecs.h +++ b/Include/codecs.h @@ -165,14 +165,14 @@ const char *encoding ); -/* Get a IncrementalEncoder object for the given encoding. */ +/* Get an IncrementalEncoder object for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( const char *encoding, const char *errors ); -/* Get a IncrementalDecoder object function for the given encoding. */ +/* Get an IncrementalDecoder object function for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( const char *encoding, diff --git a/Lib/_pyio.py b/Lib/_pyio.py --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -2512,7 +2512,7 @@ def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, - # that's a implementation detail. + # that's an implementation detail. return object.__repr__(self) @property diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -255,7 +255,7 @@ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol - # drain() expects that the reader has a exception() method + # drain() expects that the reader has an exception() method assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop diff --git a/Lib/calendar.py b/Lib/calendar.py --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -142,7 +142,7 @@ def iterweekdays(self): """ - Return a iterator for one week of weekday numbers starting with the + Return an iterator for one week of weekday numbers starting with the configured first one. """ for i in range(self.firstweekday, self.firstweekday + 7): diff --git a/Lib/chunk.py b/Lib/chunk.py --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -21,7 +21,7 @@ usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end -of the file, creating a new instance will fail with a EOFError +of the file, creating a new instance will fail with an EOFError exception. Usage: diff --git a/Lib/codecs.py b/Lib/codecs.py --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -258,7 +258,7 @@ """ def __init__(self, errors='strict'): """ - Create a IncrementalDecoder instance. + Create an IncrementalDecoder instance. The IncrementalDecoder may use different error handling schemes by providing the errors keyword argument. See the module docstring @@ -1011,7 +1011,7 @@ """ Encoding iterator. - Encodes the input strings from the iterator using a IncrementalEncoder. + Encodes the input strings from the iterator using an IncrementalEncoder. errors and kwargs are passed through to the IncrementalEncoder constructor. @@ -1029,7 +1029,7 @@ """ Decoding iterator. - Decodes the input strings from the iterator using a IncrementalDecoder. + Decodes the input strings from the iterator using an IncrementalDecoder. errors and kwargs are passed through to the IncrementalDecoder constructor. diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -521,7 +521,7 @@ raise NotImplementedError() def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/difflib.py b/Lib/difflib.py --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1515,7 +1515,7 @@ yield _make_line(lines,'-',0), None, True continue elif s.startswith(('--?+', '--+', '- ')): - # in delete block and see a intraline change or unchanged line + # in delete block and see an intraline change or unchanged line # coming: yield the delete line and then blanks from_line,to_line = _make_line(lines,'-',0), None num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py --- a/Lib/distutils/cygwinccompiler.py +++ b/Lib/distutils/cygwinccompiler.py @@ -10,9 +10,9 @@ # # * if you use a msvc compiled python version (1.5.2) # 1. you have to insert a __GNUC__ section in its config.h -# 2. you have to generate a import library for its dll +# 2. you have to generate an import library for its dll # - create a def-file for python??.dll -# - create a import library using +# - create an import library using # dlltool --dllname python15.dll --def python15.def \ # --output-lib libpython15.a # @@ -318,7 +318,7 @@ self.dll_libraries = get_msvcr() # Because these compilers aren't configured in Python's pyconfig.h file by -# default, we should at least warn the user if he is using a unmodified +# default, we should at least warn the user if he is using an unmodified # version. CONFIG_H_OK = "ok" diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -287,7 +287,7 @@ return self.voidcmd(cmd) def sendeprt(self, host, port): - '''Send a EPRT command with the current host and the given port number.''' + '''Send an EPRT command with the current host and the given port number.''' af = 0 if self.af == socket.AF_INET: af = 1 @@ -852,7 +852,7 @@ def parse229(resp, peer): - '''Parse the '229' response for a EPSV request. + '''Parse the '229' response for an EPSV request. Raises error_proto if it does not contain '(|||port|)' Return ('host.addr.as.numbers', port#) tuple.''' diff --git a/Lib/getopt.py b/Lib/getopt.py --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -28,7 +28,7 @@ # - RETURN_IN_ORDER option # - GNU extension with '-' as first character of option string # - optional arguments, specified by double colons -# - a option string with a W followed by semicolon should +# - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" __all__ = ["GetoptError","error","getopt","gnu_getopt"] diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1379,7 +1379,7 @@ text.see("insert") text.undo_block_stop() - # Our editwin provides a is_char_in_string function that works + # Our editwin provides an is_char_in_string function that works # with a Tk text index, but PyParse only knows about offsets into # a string. This builds a function for PyParse that accepts an # offset. diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -59,7 +59,7 @@ def default_command(self, event=None): if self.do_find(self.ok): if self.do_replace(): # Only find next match if replace succeeded. - # A bad re can cause a it to fail. + # A bad re can cause it to fail. self.do_find(0) def _replace_expand(self, m, repl): diff --git a/Lib/io.py b/Lib/io.py --- a/Lib/io.py +++ b/Lib/io.py @@ -19,7 +19,7 @@ Another IOBase subclass, TextIOBase, deals with the encoding and decoding of streams into text. TextIOWrapper, which extends it, is a buffered text interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO -is a in-memory stream for text. +is an in-memory stream for text. Argument names are not part of the specification, and only the arguments of open() are intended to be used as keyword arguments. diff --git a/Lib/lib2to3/fixes/fix_input.py b/Lib/lib2to3/fixes/fix_input.py --- a/Lib/lib2to3/fixes/fix_input.py +++ b/Lib/lib2to3/fixes/fix_input.py @@ -17,7 +17,7 @@ """ def transform(self, node, results): - # If we're already wrapped in a eval() call, we're done. + # If we're already wrapped in an eval() call, we're done. if context.match(node.parent.parent): return diff --git a/Lib/nntplib.py b/Lib/nntplib.py --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -201,7 +201,7 @@ return fmt def _parse_overview(lines, fmt, data_process_func=None): - """Parse the response to a OVER or XOVER command according to the + """Parse the response to an OVER or XOVER command according to the overview format `fmt`.""" n_defaults = len(_DEFAULT_OVERVIEW_FMT) overview = [] diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -358,7 +358,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for - binary writing, a io.BytesIO instance, or any other custom + binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and *protocol* is less than 3, pickle @@ -984,7 +984,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* - can be a binary file object opened for reading, a io.BytesIO + can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method diff --git a/Lib/test/decimaltestdata/fma.decTest b/Lib/test/decimaltestdata/fma.decTest --- a/Lib/test/decimaltestdata/fma.decTest +++ b/Lib/test/decimaltestdata/fma.decTest @@ -148,7 +148,7 @@ fmax2019 fma -9.999999 9.999999 0E+999999 -> -100.000 Inexact Rounded fmax2020 fma -9.999999 -9.999999 0E+999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 fmax2059 fma 999999999999 9765625 0E+999999 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/decimaltestdata/multiply.decTest b/Lib/test/decimaltestdata/multiply.decTest --- a/Lib/test/decimaltestdata/multiply.decTest +++ b/Lib/test/decimaltestdata/multiply.decTest @@ -49,7 +49,7 @@ mulx019 multiply -9.999999999 9.999999999 -> -100.000 Inexact Rounded mulx020 multiply -9.999999999 -9.999999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 mulx059 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py --- a/Lib/test/pystone.py +++ b/Lib/test/pystone.py @@ -35,7 +35,7 @@ Under Python 3 version 1.1 would use the normal division operator, resulting in some of the operations mistakenly yielding floats. Version 1.2 instead uses floor division - making the benchmark a integer benchmark again. + making the benchmark an integer benchmark again. """ diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -309,7 +309,7 @@ # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. - # Testing on a i7 at 4.3GHz shows that usually only 1 iteration is + # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -110,7 +110,7 @@ 5 12 19 6 13 - This is a interactive test, put some commands in the cmdqueue attribute + This is an interactive test, put some commands in the cmdqueue attribute and let it execute This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -97,7 +97,7 @@ self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - # do the check again, this time using a incremental decoder + # do the check again, this time using an incremental decoder d = codecs.getincrementaldecoder(self.encoding)() result = "" for (c, partialresult) in zip(input.encode(self.encoding), partialresults): diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3052,7 +3052,7 @@ # issue 1690608. email.utils.formataddr() should be rfc2047 aware. name = "H\u00e4ns W\u00fcrst" addr = 'person at dom.ain' - # A object without a header_encode method: + # An object without a header_encode method: bad_charset = object() self.assertRaises(AttributeError, utils.formataddr, (name, addr), bad_charset) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1302,7 +1302,7 @@ # test a /24 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1.1.1.0/24')) - # test an IPv4 range that isn't on a network byte boundary + # test an IPv4 range that isn't on a network byte boundary ip2 = ipaddress.ip_address('1.1.1.8') self.assertEqual(list(summarize(ip1, ip2)), [ipaddress.ip_network('1.1.1.0/29'), @@ -1315,7 +1315,7 @@ ip1 = ipaddress.ip_address('1::') ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - # test a IPv6 is sumamrized properly + # test an IPv6 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1::/16')) # test an IPv6 range that isn't on a network byte boundary diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1449,7 +1449,7 @@ except OSError as e: self.assertEqual(e.errno, errno.EBADF) else: - self.fail("%r didn't raise a OSError with a bad file descriptor" + self.fail("%r didn't raise an OSError with a bad file descriptor" % f) @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()') diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -527,7 +527,7 @@ result = urllib.request.urlretrieve("file:%s" % support.TESTFN) self.assertEqual(result[0], support.TESTFN) self.assertIsInstance(result[1], email.message.Message, - "did not get a email.message.Message instance " + "did not get an email.message.Message instance " "as second returned value") def test_copy(self): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -947,7 +947,7 @@ class WeakMethodTestCase(unittest.TestCase): def _subclass(self): - """Return a Object subclass overriding `some_method`.""" + """Return an Object subclass overriding `some_method`.""" class C(Object): def some_method(self): return 6 diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -289,7 +289,7 @@ """Format options then call Tk command with args and options and return the appropriate result. - If no option is specified, a dict is returned. If a option is + If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -823,7 +823,7 @@ raise ValueError("unexpected type in multicall result") class MultiCall: - """server -> a object used to boxcar method calls + """server -> an object used to boxcar method calls server should be a ServerProxy object. @@ -1170,7 +1170,7 @@ ## # Create parser. # - # @return A 2-tuple containing a parser and a unmarshaller. + # @return A 2-tuple containing a parser and an unmarshaller. def getparser(self): # get parser and unmarshaller diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1331,7 +1331,7 @@ import as they are meant for use by importlib. - Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. + while writing error message if the thread leaves an unhandled exception. - Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch by Suman Saha. @@ -1969,7 +1969,7 @@ - Issue #7732: Don't open a directory as a file anymore while importing a module. Ignore the directory if its name matches the module name (e.g. - "__init__.py") and raise a ImportError instead. + "__init__.py") and raise an ImportError instead. - Issue #13021: Missing decref on an error path. Thanks to Suman Saha for finding the bug and providing a patch. @@ -2021,7 +2021,7 @@ - Issue #10271: Allow warnings.showwarning() be any callable. -- Issue #11627: Fix segfault when __new__ on a exception returns a +- Issue #11627: Fix segfault when __new__ on an exception returns a non-exception class. - Issue #12149: Update the method cache after a type's dictionary gets @@ -2050,7 +2050,7 @@ with other data interleaved between marshalled objects. - Issue #12356: When required positional or keyword-only arguments are not - given, produce a informative error message which includes the name(s) of the + given, produce an informative error message which includes the name(s) of the missing arguments. - Issue #12370: Fix super with no arguments when __class__ is overriden in the @@ -2651,7 +2651,7 @@ - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and semicolons together. Patch by Ben Darnell and Petri Lehtinen. -- Issue #13227: functools.lru_cache() now has a option to distinguish +- Issue #13227: functools.lru_cache() now has an option to distinguish calls with different argument types. - Issue #6090: zipfile raises a ValueError when a document with a timestamp @@ -2914,7 +2914,7 @@ - Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. -- Issue #4376: ctypes now supports nested structures in a endian different than +- Issue #4376: ctypes now supports nested structures in an endian different than the parent structure. Patch by Vlad Riscutia. - Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a @@ -2935,7 +2935,7 @@ Linux for example, to have the same behaviour on all platforms. - Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie + Python scripts using an encoding different than UTF-8 (read the coding cookie of the script). - Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors @@ -5113,7 +5113,7 @@ ``MaybeEncodingError`` exception. - Issue #9244: The ``apply_async()`` and ``map_async()`` methods of - ``multiprocessing.Pool`` now accepts a ``error_callback`` argument. This can + ``multiprocessing.Pool`` now accepts an ``error_callback`` argument. This can be a callback with the signature ``callback(exc)``, which will be called if the target raises an exception. @@ -5210,7 +5210,7 @@ - Close file objects in modulefinder in a timely manner. -- Close a io.TextIOWrapper object in email.parser in a timely manner. +- Close an io.TextIOWrapper object in email.parser in a timely manner. - Close a file object in distutils.sysconfig in a timely manner. @@ -7308,7 +7308,7 @@ - Issue #7610: Reworked implementation of the internal ``zipfile.ZipExtFile`` class used to represent files stored inside an archive. The new implementation is significantly faster and can be wrapped in - a ``io.BufferedReader`` object for more speedups. It also solves an + an ``io.BufferedReader`` object for more speedups. It also solves an issue where interleaved calls to `read()` and `readline()` give wrong results. Patch by Nir Aides. @@ -8683,7 +8683,7 @@ - Issue #5624: Fix the _winreg module name still used in several modules. -- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. +- Issue #5628: Fix io.TextIOWrapper.read() with an unreadable buffer. - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. @@ -9649,7 +9649,7 @@ - Issue #4307: The named tuple that ``inspect.getfullargspec()`` returns now uses ``kwonlydefaults`` instead of ``kwdefaults``. -- Issue #4298: Fix a segfault when pickle.loads is passed a ill-formed input. +- Issue #4298: Fix a segfault when pickle.loads is passed ill-formed input. - Issue #4283: Fix a left-over "iteritems" call in distutils. @@ -11305,7 +11305,7 @@ ----------------- - Bug #1441486: The literal representation of -(sys.maxint - 1) - again evaluates to a int object, not a long. + again evaluates to an int object, not a long. - Bug #1501934: The scope of global variables that are locally assigned using augmented assignment is now correctly determined. @@ -15212,7 +15212,7 @@ interpreter executions, would fail. - "%c" % u"a" now returns a unicode string instead of raising a - TypeError. u"%c" % 0xffffffff now raises a OverflowError instead + TypeError. u"%c" % 0xffffffff now raises an OverflowError instead of a ValueError to be consistent with "%c" % 256. See SF patch #710127. Extension modules @@ -23105,7 +23105,7 @@ - The interfaces for the bind*() and unbind() widget methods have been redesigned; the bind*() methods now return the name of the Tcl command -created for the callback, and this can be passed as a optional +created for the callback, and this can be passed as an optional argument to unbind() in order to delete the command (normally, such commands are automatically unbound when the widget is destroyed, but for some applications this isn't enough). diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -333,7 +333,7 @@ Tests ----- -- Issue #25099: Make test_compileall not fail when a entry on sys.path cannot +- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). - Issue #23919: Prevents assert dialogs appearing in the test suite. diff --git a/Modules/_ctypes/libffi/src/x86/darwin64.S b/Modules/_ctypes/libffi/src/x86/darwin64.S --- a/Modules/_ctypes/libffi/src/x86/darwin64.S +++ b/Modules/_ctypes/libffi/src/x86/darwin64.S @@ -350,7 +350,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi/src/x86/unix64.S b/Modules/_ctypes/libffi/src/x86/unix64.S --- a/Modules/_ctypes/libffi/src/x86/unix64.S +++ b/Modules/_ctypes/libffi/src/x86/unix64.S @@ -366,7 +366,7 @@ .byte 0x4 /* DW_CFA_advance_loc4 */ .long .LUW1-.LUW0 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -351,7 +351,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -684,7 +684,7 @@ if (openssl_obj_name == NULL) return; /* Ignore aliased names, they pollute the list and OpenSSL appears to - * have a its own definition of alias as the resulting list still + * have its own definition of alias as the resulting list still * contains duplicate and alternate names for several algorithms. */ if (openssl_obj_name->alias) return; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -75,7 +75,7 @@ "Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" "of streams into text. TextIOWrapper, which extends it, is a buffered text\n" "interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" +"is an in-memory stream for text.\n" "\n" "Argument names are not part of the specification, and only the arguments\n" "of open() are intended to be used as keyword arguments.\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -905,8 +905,8 @@ if (self->encoding == NULL) { catch_ImportError: /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a + Importing locale can raise an ImportError because of + _functools, and locale.getpreferredencoding can raise an ImportError if _locale is not available. These will happen during module building. */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4100,7 +4100,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -4111,7 +4111,7 @@ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=b5f31078dab17fb0 input=b8cdeb7e3f5ee674]*/ +/*[clinic end generated code: output=b5f31078dab17fb0 input=4faabdbc763c2389]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -6514,7 +6514,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -6531,7 +6531,7 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=e2c8ce748edc57b0 input=30b4dc9e976b890c]*/ +/*[clinic end generated code: output=e2c8ce748edc57b0 input=04ece661aa884837]*/ { _Py_IDENTIFIER(persistent_load); @@ -6950,7 +6950,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -6961,7 +6961,7 @@ static PyObject * _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=0de7dff89c406816 input=e9e5fdd48de92eae]*/ +/*[clinic end generated code: output=0de7dff89c406816 input=830f8a64cef6f042]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7060,7 +7060,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -7076,7 +7076,7 @@ static PyObject * _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=798f1c57cb2b4eb1 input=da97372e38e510a6]*/ +/*[clinic end generated code: output=798f1c57cb2b4eb1 input=2df7c7a1e6742204]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -257,7 +257,7 @@ PyDoc_STRVAR(atexit_unregister__doc__, "unregister(func) -> None\n\ \n\ -Unregister a exit function which was previously registered using\n\ +Unregister an exit function which was previously registered using\n\ atexit.register\n\ \n\ func - function to be unregistered"); diff --git a/Modules/audioop.c b/Modules/audioop.c --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -112,7 +112,7 @@ /* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * @@ -218,7 +218,7 @@ /* * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 13-bits. * diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -77,7 +77,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -260,7 +260,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -369,7 +369,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -462,7 +462,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -545,4 +545,4 @@ exit: return return_value; } -/*[clinic end generated code: output=06f3a5233298448e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aecd61660d1cf31d input=a9049054013a1b77]*/ diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -21,7 +21,7 @@ * * * The Solution: - * Prefix all a exported symbols with "PyExpat_". This is similar to + * Prefix all exported symbols with "PyExpat_". This is similar to * what Mozilla does for some common libs: * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115 * diff --git a/Modules/hashlib.h b/Modules/hashlib.h --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -30,7 +30,7 @@ /* * Helper code to synchronize access to the hash object when the GIL is * released around a CPU consuming hashlib operation. All code paths that - * access a mutable part of obj must be enclosed in a ENTER_HASHLIB / + * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / * LEAVE_HASHLIB block or explicitly acquire and release the lock inside * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for * an operation. diff --git a/Modules/readline.c b/Modules/readline.c --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1236,7 +1236,7 @@ return NULL; } - /* We got an EOF, return a empty string. */ + /* We got an EOF, return an empty string. */ if (p == NULL) { p = PyMem_RawMalloc(1); if (p != NULL) diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1288,7 +1288,7 @@ if (truncated == NULL || PyLong_Check(truncated)) return truncated; /* __trunc__ is specified to return an Integral type, - but int() needs to return a int. */ + but int() needs to return an int. */ m = truncated->ob_type->tp_as_number; if (m == NULL || m->nb_int == NULL) { PyErr_Format( diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -874,7 +874,7 @@ static int oserror_use_init(PyTypeObject *type) { - /* When __init__ is defined in a OSError subclass, we want any + /* When __init__ is defined in an OSError subclass, we want any extraneous argument to __new__ to be ignored. The only reasonable solution, given __new__ takes a variable number of arguments, is to defer arg parsing and initialization to __init__. diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -548,7 +548,7 @@ return 0; } if (u->u_ste->ste_needs_class_closure) { - /* Cook up a implicit __class__ cell. */ + /* Cook up an implicit __class__ cell. */ _Py_IDENTIFIER(__class__); PyObject *tuple, *name, *zero; int res; diff --git a/Python/thread.c b/Python/thread.c --- a/Python/thread.c +++ b/Python/thread.c @@ -31,7 +31,7 @@ threads. This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on a ia64 system instead + a check of __ia64 to verify that we're running on an ia64 system instead of a pa-risc system. */ #ifdef __hpux diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -91,7 +91,7 @@ def safety_limit(val): - # Given a integer value from the process being debugged, limit it to some + # Given an integer value from the process being debugged, limit it to some # safety threshold so that arbitrary breakage within said process doesn't # break the gdb process too much (e.g. sizes of iterations, sizes of lists) return min(val, 1000) @@ -158,7 +158,7 @@ class PyObjectPtr(object): """ - Class wrapping a gdb.Value that's a either a (PyObject*) within the + Class wrapping a gdb.Value that's either a (PyObject*) within the inferior process, or some subclass pointer e.g. (PyBytesObject*) There will be a subclass for every refined PyObject type that we care -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 1 23:29:17 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 02 Nov 2015 04:29:17 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325523=3A_Merge_a-to-an_corrections_from_3=2E5?= Message-ID: <20151102042917.100250.26155@psf.io> https://hg.python.org/cpython/rev/96e61bb7f6e9 changeset: 98931:96e61bb7f6e9 parent: 98927:9f8b5053e30d parent: 98930:2347271172b3 user: Martin Panter date: Mon Nov 02 04:27:17 2015 +0000 summary: Issue #25523: Merge a-to-an corrections from 3.5 files: Doc/c-api/buffer.rst | 2 +- Doc/faq/programming.rst | 2 +- Doc/library/argparse.rst | 2 +- Doc/library/chunk.rst | 2 +- Doc/library/concurrent.futures.rst | 4 +- Doc/library/ctypes.rst | 2 +- Doc/library/difflib.rst | 2 +- Doc/library/fcntl.rst | 6 +- Doc/library/ftplib.rst | 4 +- Doc/library/functions.rst | 6 +- Doc/library/gzip.rst | 2 +- Doc/library/http.cookiejar.rst | 2 +- Doc/library/http.server.rst | 4 +- Doc/library/mailbox.rst | 2 +- Doc/library/multiprocessing.rst | 2 +- Doc/library/nntplib.rst | 2 +- Doc/library/optparse.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/pickle.rst | 4 +- Doc/library/pyexpat.rst | 2 +- Doc/library/shutil.rst | 4 +- Doc/library/smtplib.rst | 4 +- Doc/library/socket.rst | 4 +- Doc/library/sqlite3.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sunau.rst | 4 +- Doc/library/tempfile.rst | 2 +- Doc/library/unittest.mock.rst | 2 +- Doc/library/xml.dom.pulldom.rst | 2 +- Doc/reference/datamodel.rst | 4 +- Doc/tutorial/errors.rst | 2 +- Doc/tutorial/introduction.rst | 2 +- Doc/whatsnew/2.1.rst | 2 +- Doc/whatsnew/2.3.rst | 2 +- Doc/whatsnew/3.1.rst | 2 +- Doc/whatsnew/3.2.rst | 4 +- Doc/whatsnew/3.3.rst | 2 +- Doc/whatsnew/3.5.rst | 2 +- Include/abstract.h | 2 +- Include/codecs.h | 4 +- Lib/_pyio.py | 2 +- Lib/asyncio/streams.py | 2 +- Lib/calendar.py | 2 +- Lib/chunk.py | 2 +- Lib/codecs.py | 6 +- Lib/concurrent/futures/_base.py | 2 +- Lib/concurrent/futures/process.py | 2 +- Lib/difflib.py | 2 +- Lib/distutils/cygwinccompiler.py | 6 +- Lib/ftplib.py | 4 +- Lib/getopt.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/ReplaceDialog.py | 2 +- Lib/io.py | 2 +- Lib/lib2to3/fixes/fix_input.py | 2 +- Lib/nntplib.py | 2 +- Lib/pickle.py | 4 +- Lib/signal.py | 2 +- Lib/test/decimaltestdata/fma.decTest | 1 + Lib/test/decimaltestdata/multiply.decTest | 1 + Lib/test/pystone.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_cmd.py | 2 +- Lib/test/test_codecs.py | 2 +- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_ipaddress.py | 4 +- Lib/test/test_os.py | 2 +- Lib/test/test_urllib.py | 2 +- Lib/test/test_weakref.py | 2 +- Lib/tkinter/ttk.py | 2 +- Lib/unittest/test/test_discovery.py | 4 +- Lib/xmlrpc/client.py | 4 +- Misc/HISTORY | 30 +++++----- Misc/NEWS | 4 +- Modules/_collectionsmodule.c | 2 +- Modules/_ctypes/libffi/src/x86/darwin64.S | 2 +- Modules/_ctypes/libffi/src/x86/unix64.S | 2 +- Modules/_ctypes/libffi_osx/x86/darwin64.S | 2 +- Modules/_hashopenssl.c | 2 +- Modules/_io/_iomodule.c | 2 +- Modules/_io/textio.c | 4 +- Modules/_pickle.c | 16 ++-- Modules/atexitmodule.c | 2 +- Modules/audioop.c | 4 +- Modules/clinic/_pickle.c.h | 10 +- Modules/expat/pyexpatns.h | 2 +- Modules/hashlib.h | 2 +- Modules/readline.c | 2 +- Objects/abstract.c | 2 +- Objects/exceptions.c | 2 +- Python/compile.c | 2 +- Python/thread.c | 2 +- Tools/gdb/libpython.py | 4 +- 93 files changed, 146 insertions(+), 144 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -40,7 +40,7 @@ Simple objects such as :class:`bytes` and :class:`bytearray` expose their underlying buffer in byte-oriented form. Other forms are possible; for example, -the elements exposed by a :class:`array.array` can be multi-byte values. +the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -849,7 +849,7 @@ You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place -unicode data, try using a :class:`io.StringIO` object or the :mod:`array` +unicode data, try using an :class:`io.StringIO` object or the :mod:`array` module:: >>> import io diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -530,7 +530,7 @@ ^^^^^^^^^^^^ Normally, when you pass an argument list to the -:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`, +:meth:`~ArgumentParser.parse_args` method of an :class:`ArgumentParser`, it :ref:`recognizes abbreviations ` of long options. This feature can be disabled by setting ``allow_abbrev`` to ``False``:: diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -47,7 +47,7 @@ the :class:`Chunk` class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end of the file, creating a new -instance will fail with a :exc:`EOFError` exception. +instance will fail with an :exc:`EOFError` exception. .. class:: Chunk(file, align=True, bigendian=True, inclheader=False) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -90,7 +90,7 @@ ThreadPoolExecutor ------------------ -:class:`ThreadPoolExecutor` is a :class:`Executor` subclass that uses a pool of +:class:`ThreadPoolExecutor` is an :class:`Executor` subclass that uses a pool of threads to execute calls asynchronously. Deadlocks can occur when the callable associated with a :class:`Future` waits on @@ -304,7 +304,7 @@ Added callables are called in the order that they were added and are always called in a thread belonging to the process that added them. If - the callable raises a :exc:`Exception` subclass, it will be logged and + the callable raises an :exc:`Exception` subclass, it will be logged and ignored. If the callable raises a :exc:`BaseException` subclass, the behavior is undefined. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -39,7 +39,7 @@ convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`HRESULT` error code. The error -code is used to automatically raise a :class:`OSError` exception when the +code is used to automatically raise an :class:`OSError` exception when the function call fails. .. versionchanged:: 3.3 diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -278,7 +278,7 @@ generating the delta lines) in unified diff format. Unified diffs are a compact way of showing just the lines that have changed plus - a few lines of context. The changes are shown in a inline style (instead of + a few lines of context. The changes are shown in an inline style (instead of separate before/after blocks). The number of context lines is set by *n* which defaults to three. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -16,13 +16,13 @@ All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by -``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin`` +``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` itself, which provides a :meth:`~io.IOBase.fileno` that returns a genuine file descriptor. .. versionchanged:: 3.3 - Operations in this module used to raise a :exc:`IOError` where they now - raise a :exc:`OSError`. + Operations in this module used to raise an :exc:`IOError` where they now + raise an :exc:`OSError`. The module defines the following functions: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -287,9 +287,9 @@ .. method:: FTP.transfercmd(cmd, rest=None) - Initiate a transfer over the data connection. If the transfer is active, send a + Initiate a transfer over the data connection. If the transfer is active, send an ``EPRT`` or ``PORT`` command and the transfer command specified by *cmd*, and - accept the connection. If the server is passive, send a ``EPSV`` or ``PASV`` + accept the connection. If the server is passive, send an ``EPSV`` or ``PASV`` command, connect to it, and start the transfer command. Either way, return the socket for the connection. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1032,9 +1032,9 @@ :class:`io.TextIOBase` (specifically :class:`io.TextIOWrapper`). When used to open a file in a binary mode with buffering, the returned class is a subclass of :class:`io.BufferedIOBase`. The exact class varies: in read - binary mode, it returns a :class:`io.BufferedReader`; in write binary and - append binary modes, it returns a :class:`io.BufferedWriter`, and in - read/write mode, it returns a :class:`io.BufferedRandom`. When buffering is + binary mode, it returns an :class:`io.BufferedReader`; in write binary and + append binary modes, it returns an :class:`io.BufferedWriter`, and in + read/write mode, it returns an :class:`io.BufferedRandom`. When buffering is disabled, the raw stream, a subclass of :class:`io.RawIOBase`, :class:`io.FileIO`, is returned. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -96,7 +96,7 @@ Calling a :class:`GzipFile` object's :meth:`close` method does not close *fileobj*, since you might wish to append more material after the compressed - data. This also allows you to pass a :class:`io.BytesIO` object opened for + data. This also allows you to pass an :class:`io.BytesIO` object opened for writing as *fileobj*, and retrieve the resulting memory buffer using the :class:`io.BytesIO` object's :meth:`~io.BytesIO.getvalue` method. diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -176,7 +176,7 @@ The *response* object (usually the result of a call to :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info` - method, which returns a :class:`email.message.Message` instance. + method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) must support the methods :meth:`get_full_url`, :meth:`get_host`, diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -176,7 +176,7 @@ .. method:: handle_expect_100() - When a HTTP/1.1 compliant server receives a ``Expect: 100-continue`` + When a HTTP/1.1 compliant server receives an ``Expect: 100-continue`` request header it responds back with a ``100 Continue`` followed by ``200 OK`` headers. This method can be overridden to raise an error if the server does not @@ -210,7 +210,7 @@ are picked up from the :meth:`version_string` and :meth:`date_time_string` methods, respectively. If the server does not intend to send any other headers using the :meth:`send_header` method, - then :meth:`send_response` should be followed by a :meth:`end_headers` + then :meth:`send_response` should be followed by an :meth:`end_headers` call. .. versionchanged:: 3.3 diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -674,7 +674,7 @@ In Babyl mailboxes, the headers of a message are not stored contiguously with the body of the message. To generate a file-like representation, the - headers and body are copied together into a :class:`io.BytesIO` instance, + headers and body are copied together into an :class:`io.BytesIO` instance, which has an API identical to that of a file. As a result, the file-like object is truly independent of the underlying mailbox but does not save memory compared to a string diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1046,7 +1046,7 @@ readable. .. versionchanged:: 3.3 - This function used to raise a :exc:`IOError`, which is now an + This function used to raise :exc:`IOError`, which is now an alias of :exc:`OSError`. diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -341,7 +341,7 @@ .. method:: NNTP.over(message_spec, *, file=None) - Send a ``OVER`` command, or a ``XOVER`` command on legacy servers. + Send an ``OVER`` command, or an ``XOVER`` command on legacy servers. *message_spec* can be either a string representing a message id, or a ``(first, last)`` tuple of numbers indicating a range of articles in the current group, or a ``(first, None)`` tuple indicating a range of diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -1324,7 +1324,7 @@ the list of arguments to process (default: ``sys.argv[1:]``) ``values`` - a :class:`optparse.Values` object to store option arguments in (default: a + an :class:`optparse.Values` object to store option arguments in (default: a new instance of :class:`Values`) -- if you give an existing object, the option defaults will not be initialized on it diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -289,7 +289,7 @@ Return ``True`` if both pathname arguments refer to the same file or directory. This is determined by the device number and i-node number and raises an - exception if a :func:`os.stat` call on either pathname fails. + exception if an :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -221,7 +221,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file opened for - binary reading, a :class:`io.BytesIO` object, or any other custom object + binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -357,7 +357,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file object - opened for binary reading, a :class:`io.BytesIO` object, or any other + opened for binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -763,7 +763,7 @@ .. data:: XML_ERROR_UNDEFINED_ENTITY - A reference was made to a entity which was not defined. + A reference was made to an entity which was not defined. .. data:: XML_ERROR_UNKNOWN_ENCODING diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -207,8 +207,8 @@ and metadata of the linked files are copied to the new tree. When *symlinks* is false, if the file pointed by the symlink doesn't - exist, a exception will be added in the list of errors raised in - a :exc:`Error` exception at the end of the copy process. + exist, an exception will be added in the list of errors raised in + an :exc:`Error` exception at the end of the copy process. You can set the optional *ignore_dangling_symlinks* flag to true if you want to silence this exception. Notice that this option has no effect on platforms that don't support :func:`os.symlink`. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -22,7 +22,7 @@ .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) - A :class:`SMTP` instance encapsulates an SMTP connection. It has methods + An :class:`SMTP` instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP :meth:`connect` method is called with those parameters during initialization. If specified, @@ -69,7 +69,7 @@ certfile=None [, timeout], context=None, \ source_address=None) - A :class:`SMTP_SSL` instance behaves exactly the same as instances of + An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -715,7 +715,7 @@ Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the bytes object *packed_ip* is not the correct length for the specified address family, :exc:`ValueError` will be raised. - A :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. + :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. Availability: Unix (maybe not all platforms), Windows. @@ -1014,7 +1014,7 @@ interpreted the same way as by the built-in :func:`open` function. The socket must be in blocking mode; it can have a timeout, but the file - object's internal buffer may end up in a inconsistent state if a timeout + object's internal buffer may end up in an inconsistent state if a timeout occurs. Closing the file object returned by :meth:`makefile` won't close the diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -615,7 +615,7 @@ .. attribute:: lastrowid This read-only attribute provides the rowid of the last modified row. It is - only set if you issued a ``INSERT`` statement using the :meth:`execute` + only set if you issued an ``INSERT`` statement using the :meth:`execute` method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -951,7 +951,7 @@ runtime cost, you must switch to one of the alternatives below: * if concatenating :class:`str` objects, you can build a list and use - :meth:`str.join` at the end or else write to a :class:`io.StringIO` + :meth:`str.join` at the end or else write to an :class:`io.StringIO` instance and retrieve its value when complete * if concatenating :class:`bytes` objects, you can similarly use diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -54,8 +54,8 @@ Note that it does not allow read/write files. - A *mode* of ``'r'`` returns a :class:`AU_read` object, while a *mode* of ``'w'`` - or ``'wb'`` returns a :class:`AU_write` object. + A *mode* of ``'r'`` returns an :class:`AU_read` object, while a *mode* of ``'w'`` + or ``'wb'`` returns an :class:`AU_write` object. .. function:: openfp(file, mode) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -96,7 +96,7 @@ causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either a :class:`io.BytesIO` or :class:`io.StringIO` object (depending on + is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1131,7 +1131,7 @@ ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a :class:`io.StringIO` instance: +Another use case might be to replace an object with an :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -47,7 +47,7 @@ * :data:`PROCESSING_INSTRUCTION` * :data:`IGNORABLE_WHITESPACE` -``node`` is a object of type :class:`xml.dom.minidom.Document`, +``node`` is an object of type :class:`xml.dom.minidom.Document`, :class:`xml.dom.minidom.Element` or :class:`xml.dom.minidom.Text`. Since the document is treated as a "flat" stream of events, the document "tree" diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2358,7 +2358,7 @@ ``__aiter__`` implementation, and an *asynchronous iterator* can call asynchronous code in its ``__anext__`` method. -Asynchronous iterators can be used in a :keyword:`async for` statement. +Asynchronous iterators can be used in an :keyword:`async for` statement. .. method:: object.__aiter__(self) @@ -2393,7 +2393,7 @@ An *asynchronous context manager* is a *context manager* that is able to suspend execution in its ``__aenter__`` and ``__aexit__`` methods. -Asynchronous context managers can be used in a :keyword:`async with` statement. +Asynchronous context managers can be used in an :keyword:`async with` statement. .. method:: object.__aenter__(self) diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -336,7 +336,7 @@ A *finally clause* is always executed before leaving the :keyword:`try` statement, whether an exception has occurred or not. When an exception has occurred in the :keyword:`try` clause and has not been handled by an -:keyword:`except` clause (or it has occurred in a :keyword:`except` or +:keyword:`except` clause (or it has occurred in an :keyword:`except` or :keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has been executed. The :keyword:`finally` clause is also executed "on the way out" when any other clause of the :keyword:`try` statement is left via a diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -303,7 +303,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is 2. -Attempting to use a index that is too large will result in an error:: +Attempting to use an index that is too large will result in an error:: >>> word[42] # the word only has 6 characters Traceback (most recent call last): diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -555,7 +555,7 @@ and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a ``upload`` option that would automatically upload your +could support an ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -411,7 +411,7 @@ A new built-in function, :func:`enumerate`, will make certain loops a bit clearer. ``enumerate(thing)``, where *thing* is either an iterator or a -sequence, returns a iterator that will return ``(0, thing[0])``, ``(1, +sequence, returns an iterator that will return ``(0, thing[0])``, ``(1, thing[1])``, ``(2, thing[2])``, and so forth. A common idiom to change every element of a list looks like this:: diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -336,7 +336,7 @@ (Contributed by David Laban; :issue:`4739`.) * The :mod:`unittest` module now supports skipping individual tests or classes - of tests. And it supports marking a test as a expected failure, a test that + of tests. And it supports marking a test as an expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a TestResult:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -788,7 +788,7 @@ :issue:`8814`.) * To help write classes with rich comparison methods, a new decorator - :func:`functools.total_ordering` will use a existing equality and inequality + :func:`functools.total_ordering` will use existing equality and inequality methods to fill in the remaining methods. For example, supplying *__eq__* and *__lt__* will enable @@ -1399,7 +1399,7 @@ Also, the :class:`zipfile.ZipExtFile` class was reworked internally to represent files stored inside an archive. The new implementation is significantly faster -and can be wrapped in a :class:`io.BufferedReader` object for more speedups. It +and can be wrapped in an :class:`io.BufferedReader` object for more speedups. It also solves an issue where interleaved calls to *read* and *readline* gave the wrong results. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1421,7 +1421,7 @@ :class:`http.client.HTTPResponse` now has a :meth:`~http.client.HTTPResponse.readinto` method, which means it can be used -as a :class:`io.RawIOBase` class. (Contributed by John Kuhn in +as an :class:`io.RawIOBase` class. (Contributed by John Kuhn in :issue:`13464`.) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -465,7 +465,7 @@ PEP 475: Retry system calls failing with EINTR ---------------------------------------------- -A :py:data:`errno.EINTR` error code is returned whenever a system call, that +An :py:data:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would raise :exc:`InterruptedError` in such case. This meant that, when writing a Python application, the developer had two choices: diff --git a/Include/abstract.h b/Include/abstract.h --- a/Include/abstract.h +++ b/Include/abstract.h @@ -95,7 +95,7 @@ numeric, sequence, and mapping. Each protocol consists of a collection of related operations. If an operation that is not provided by a particular type is invoked, then a standard exception, - NotImplementedError is raised with a operation name as an argument. + NotImplementedError is raised with an operation name as an argument. In addition, for convenience this interface defines a set of constructors for building objects of built-in types. This is needed so new objects can be returned from C functions that otherwise treat diff --git a/Include/codecs.h b/Include/codecs.h --- a/Include/codecs.h +++ b/Include/codecs.h @@ -165,14 +165,14 @@ const char *encoding ); -/* Get a IncrementalEncoder object for the given encoding. */ +/* Get an IncrementalEncoder object for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( const char *encoding, const char *errors ); -/* Get a IncrementalDecoder object function for the given encoding. */ +/* Get an IncrementalDecoder object function for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( const char *encoding, diff --git a/Lib/_pyio.py b/Lib/_pyio.py --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -2512,7 +2512,7 @@ def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, - # that's a implementation detail. + # that's an implementation detail. return object.__repr__(self) @property diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -255,7 +255,7 @@ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol - # drain() expects that the reader has a exception() method + # drain() expects that the reader has an exception() method assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop diff --git a/Lib/calendar.py b/Lib/calendar.py --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -142,7 +142,7 @@ def iterweekdays(self): """ - Return a iterator for one week of weekday numbers starting with the + Return an iterator for one week of weekday numbers starting with the configured first one. """ for i in range(self.firstweekday, self.firstweekday + 7): diff --git a/Lib/chunk.py b/Lib/chunk.py --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -21,7 +21,7 @@ usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end -of the file, creating a new instance will fail with a EOFError +of the file, creating a new instance will fail with an EOFError exception. Usage: diff --git a/Lib/codecs.py b/Lib/codecs.py --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -258,7 +258,7 @@ """ def __init__(self, errors='strict'): """ - Create a IncrementalDecoder instance. + Create an IncrementalDecoder instance. The IncrementalDecoder may use different error handling schemes by providing the errors keyword argument. See the module docstring @@ -1011,7 +1011,7 @@ """ Encoding iterator. - Encodes the input strings from the iterator using a IncrementalEncoder. + Encodes the input strings from the iterator using an IncrementalEncoder. errors and kwargs are passed through to the IncrementalEncoder constructor. @@ -1029,7 +1029,7 @@ """ Decoding iterator. - Decodes the input strings from the iterator using a IncrementalDecoder. + Decodes the input strings from the iterator using an IncrementalDecoder. errors and kwargs are passed through to the IncrementalDecoder constructor. diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -521,7 +521,7 @@ raise NotImplementedError() def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -456,7 +456,7 @@ submit.__doc__ = _base.Executor.submit.__doc__ def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/difflib.py b/Lib/difflib.py --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1515,7 +1515,7 @@ yield _make_line(lines,'-',0), None, True continue elif s.startswith(('--?+', '--+', '- ')): - # in delete block and see a intraline change or unchanged line + # in delete block and see an intraline change or unchanged line # coming: yield the delete line and then blanks from_line,to_line = _make_line(lines,'-',0), None num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py --- a/Lib/distutils/cygwinccompiler.py +++ b/Lib/distutils/cygwinccompiler.py @@ -10,9 +10,9 @@ # # * if you use a msvc compiled python version (1.5.2) # 1. you have to insert a __GNUC__ section in its config.h -# 2. you have to generate a import library for its dll +# 2. you have to generate an import library for its dll # - create a def-file for python??.dll -# - create a import library using +# - create an import library using # dlltool --dllname python15.dll --def python15.def \ # --output-lib libpython15.a # @@ -318,7 +318,7 @@ self.dll_libraries = get_msvcr() # Because these compilers aren't configured in Python's pyconfig.h file by -# default, we should at least warn the user if he is using a unmodified +# default, we should at least warn the user if he is using an unmodified # version. CONFIG_H_OK = "ok" diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -287,7 +287,7 @@ return self.voidcmd(cmd) def sendeprt(self, host, port): - '''Send a EPRT command with the current host and the given port number.''' + '''Send an EPRT command with the current host and the given port number.''' af = 0 if self.af == socket.AF_INET: af = 1 @@ -852,7 +852,7 @@ def parse229(resp, peer): - '''Parse the '229' response for a EPSV request. + '''Parse the '229' response for an EPSV request. Raises error_proto if it does not contain '(|||port|)' Return ('host.addr.as.numbers', port#) tuple.''' diff --git a/Lib/getopt.py b/Lib/getopt.py --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -28,7 +28,7 @@ # - RETURN_IN_ORDER option # - GNU extension with '-' as first character of option string # - optional arguments, specified by double colons -# - a option string with a W followed by semicolon should +# - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" __all__ = ["GetoptError","error","getopt","gnu_getopt"] diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1379,7 +1379,7 @@ text.see("insert") text.undo_block_stop() - # Our editwin provides a is_char_in_string function that works + # Our editwin provides an is_char_in_string function that works # with a Tk text index, but PyParse only knows about offsets into # a string. This builds a function for PyParse that accepts an # offset. diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -59,7 +59,7 @@ def default_command(self, event=None): if self.do_find(self.ok): if self.do_replace(): # Only find next match if replace succeeded. - # A bad re can cause a it to fail. + # A bad re can cause it to fail. self.do_find(0) def _replace_expand(self, m, repl): diff --git a/Lib/io.py b/Lib/io.py --- a/Lib/io.py +++ b/Lib/io.py @@ -19,7 +19,7 @@ Another IOBase subclass, TextIOBase, deals with the encoding and decoding of streams into text. TextIOWrapper, which extends it, is a buffered text interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO -is a in-memory stream for text. +is an in-memory stream for text. Argument names are not part of the specification, and only the arguments of open() are intended to be used as keyword arguments. diff --git a/Lib/lib2to3/fixes/fix_input.py b/Lib/lib2to3/fixes/fix_input.py --- a/Lib/lib2to3/fixes/fix_input.py +++ b/Lib/lib2to3/fixes/fix_input.py @@ -17,7 +17,7 @@ """ def transform(self, node, results): - # If we're already wrapped in a eval() call, we're done. + # If we're already wrapped in an eval() call, we're done. if context.match(node.parent.parent): return diff --git a/Lib/nntplib.py b/Lib/nntplib.py --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -201,7 +201,7 @@ return fmt def _parse_overview(lines, fmt, data_process_func=None): - """Parse the response to a OVER or XOVER command according to the + """Parse the response to an OVER or XOVER command according to the overview format `fmt`.""" n_defaults = len(_DEFAULT_OVERVIEW_FMT) overview = [] diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -359,7 +359,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for - binary writing, a io.BytesIO instance, or any other custom + binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and *protocol* is less than 3, pickle @@ -991,7 +991,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* - can be a binary file object opened for reading, a io.BytesIO + can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method diff --git a/Lib/signal.py b/Lib/signal.py --- a/Lib/signal.py +++ b/Lib/signal.py @@ -34,7 +34,7 @@ def _enum_to_int(value): """Convert an IntEnum member to a numeric value. - If it's not a IntEnum member return the value itself. + If it's not an IntEnum member return the value itself. """ try: return int(value) diff --git a/Lib/test/decimaltestdata/fma.decTest b/Lib/test/decimaltestdata/fma.decTest --- a/Lib/test/decimaltestdata/fma.decTest +++ b/Lib/test/decimaltestdata/fma.decTest @@ -148,7 +148,7 @@ fmax2019 fma -9.999999 9.999999 0E+999999 -> -100.000 Inexact Rounded fmax2020 fma -9.999999 -9.999999 0E+999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 fmax2059 fma 999999999999 9765625 0E+999999 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/decimaltestdata/multiply.decTest b/Lib/test/decimaltestdata/multiply.decTest --- a/Lib/test/decimaltestdata/multiply.decTest +++ b/Lib/test/decimaltestdata/multiply.decTest @@ -49,7 +49,7 @@ mulx019 multiply -9.999999999 9.999999999 -> -100.000 Inexact Rounded mulx020 multiply -9.999999999 -9.999999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 mulx059 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py --- a/Lib/test/pystone.py +++ b/Lib/test/pystone.py @@ -35,7 +35,7 @@ Under Python 3 version 1.1 would use the normal division operator, resulting in some of the operations mistakenly yielding floats. Version 1.2 instead uses floor division - making the benchmark a integer benchmark again. + making the benchmark an integer benchmark again. """ diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -309,7 +309,7 @@ # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. - # Testing on a i7 at 4.3GHz shows that usually only 1 iteration is + # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -110,7 +110,7 @@ 5 12 19 6 13 - This is a interactive test, put some commands in the cmdqueue attribute + This is an interactive test, put some commands in the cmdqueue attribute and let it execute This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -100,7 +100,7 @@ self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - # do the check again, this time using a incremental decoder + # do the check again, this time using an incremental decoder d = codecs.getincrementaldecoder(self.encoding)() result = "" for (c, partialresult) in zip(input.encode(self.encoding), partialresults): diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3052,7 +3052,7 @@ # issue 1690608. email.utils.formataddr() should be rfc2047 aware. name = "H\u00e4ns W\u00fcrst" addr = 'person at dom.ain' - # A object without a header_encode method: + # An object without a header_encode method: bad_charset = object() self.assertRaises(AttributeError, utils.formataddr, (name, addr), bad_charset) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1302,7 +1302,7 @@ # test a /24 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1.1.1.0/24')) - # test an IPv4 range that isn't on a network byte boundary + # test an IPv4 range that isn't on a network byte boundary ip2 = ipaddress.ip_address('1.1.1.8') self.assertEqual(list(summarize(ip1, ip2)), [ipaddress.ip_network('1.1.1.0/29'), @@ -1315,7 +1315,7 @@ ip1 = ipaddress.ip_address('1::') ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - # test a IPv6 is sumamrized properly + # test an IPv6 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1::/16')) # test an IPv6 range that isn't on a network byte boundary diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1448,7 +1448,7 @@ except OSError as e: self.assertEqual(e.errno, errno.EBADF) else: - self.fail("%r didn't raise a OSError with a bad file descriptor" + self.fail("%r didn't raise an OSError with a bad file descriptor" % f) @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()') diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -527,7 +527,7 @@ result = urllib.request.urlretrieve("file:%s" % support.TESTFN) self.assertEqual(result[0], support.TESTFN) self.assertIsInstance(result[1], email.message.Message, - "did not get a email.message.Message instance " + "did not get an email.message.Message instance " "as second returned value") def test_copy(self): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -947,7 +947,7 @@ class WeakMethodTestCase(unittest.TestCase): def _subclass(self): - """Return a Object subclass overriding `some_method`.""" + """Return an Object subclass overriding `some_method`.""" class C(Object): def some_method(self): return 6 diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -289,7 +289,7 @@ """Format options then call Tk command with args and options and return the appropriate result. - If no option is specified, a dict is returned. If a option is + If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -255,12 +255,12 @@ self.addCleanup(sys.path.remove, abspath('/foo')) # Test data: we expect the following: - # a listdir to find our package, and a isfile and isdir check on it. + # a listdir to find our package, and isfile and isdir checks on it. # a module-from-name call to turn that into a module # followed by load_tests. # then our load_tests will call discover() which is messy # but that finally chains into find_tests again for the child dir - - # which is why we don't have a infinite loop. + # which is why we don't have an infinite loop. # We expect to see: # the module load tests for both package and plain module called, # and the plain module result nested by the package module load_tests diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -823,7 +823,7 @@ raise ValueError("unexpected type in multicall result") class MultiCall: - """server -> a object used to boxcar method calls + """server -> an object used to boxcar method calls server should be a ServerProxy object. @@ -1170,7 +1170,7 @@ ## # Create parser. # - # @return A 2-tuple containing a parser and a unmarshaller. + # @return A 2-tuple containing a parser and an unmarshaller. def getparser(self): # get parser and unmarshaller diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1331,7 +1331,7 @@ import as they are meant for use by importlib. - Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. + while writing error message if the thread leaves an unhandled exception. - Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch by Suman Saha. @@ -1969,7 +1969,7 @@ - Issue #7732: Don't open a directory as a file anymore while importing a module. Ignore the directory if its name matches the module name (e.g. - "__init__.py") and raise a ImportError instead. + "__init__.py") and raise an ImportError instead. - Issue #13021: Missing decref on an error path. Thanks to Suman Saha for finding the bug and providing a patch. @@ -2021,7 +2021,7 @@ - Issue #10271: Allow warnings.showwarning() be any callable. -- Issue #11627: Fix segfault when __new__ on a exception returns a +- Issue #11627: Fix segfault when __new__ on an exception returns a non-exception class. - Issue #12149: Update the method cache after a type's dictionary gets @@ -2050,7 +2050,7 @@ with other data interleaved between marshalled objects. - Issue #12356: When required positional or keyword-only arguments are not - given, produce a informative error message which includes the name(s) of the + given, produce an informative error message which includes the name(s) of the missing arguments. - Issue #12370: Fix super with no arguments when __class__ is overriden in the @@ -2651,7 +2651,7 @@ - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and semicolons together. Patch by Ben Darnell and Petri Lehtinen. -- Issue #13227: functools.lru_cache() now has a option to distinguish +- Issue #13227: functools.lru_cache() now has an option to distinguish calls with different argument types. - Issue #6090: zipfile raises a ValueError when a document with a timestamp @@ -2914,7 +2914,7 @@ - Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. -- Issue #4376: ctypes now supports nested structures in a endian different than +- Issue #4376: ctypes now supports nested structures in an endian different than the parent structure. Patch by Vlad Riscutia. - Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a @@ -2935,7 +2935,7 @@ Linux for example, to have the same behaviour on all platforms. - Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie + Python scripts using an encoding different than UTF-8 (read the coding cookie of the script). - Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors @@ -5113,7 +5113,7 @@ ``MaybeEncodingError`` exception. - Issue #9244: The ``apply_async()`` and ``map_async()`` methods of - ``multiprocessing.Pool`` now accepts a ``error_callback`` argument. This can + ``multiprocessing.Pool`` now accepts an ``error_callback`` argument. This can be a callback with the signature ``callback(exc)``, which will be called if the target raises an exception. @@ -5210,7 +5210,7 @@ - Close file objects in modulefinder in a timely manner. -- Close a io.TextIOWrapper object in email.parser in a timely manner. +- Close an io.TextIOWrapper object in email.parser in a timely manner. - Close a file object in distutils.sysconfig in a timely manner. @@ -7308,7 +7308,7 @@ - Issue #7610: Reworked implementation of the internal ``zipfile.ZipExtFile`` class used to represent files stored inside an archive. The new implementation is significantly faster and can be wrapped in - a ``io.BufferedReader`` object for more speedups. It also solves an + an ``io.BufferedReader`` object for more speedups. It also solves an issue where interleaved calls to `read()` and `readline()` give wrong results. Patch by Nir Aides. @@ -8683,7 +8683,7 @@ - Issue #5624: Fix the _winreg module name still used in several modules. -- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. +- Issue #5628: Fix io.TextIOWrapper.read() with an unreadable buffer. - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. @@ -9649,7 +9649,7 @@ - Issue #4307: The named tuple that ``inspect.getfullargspec()`` returns now uses ``kwonlydefaults`` instead of ``kwdefaults``. -- Issue #4298: Fix a segfault when pickle.loads is passed a ill-formed input. +- Issue #4298: Fix a segfault when pickle.loads is passed ill-formed input. - Issue #4283: Fix a left-over "iteritems" call in distutils. @@ -11305,7 +11305,7 @@ ----------------- - Bug #1441486: The literal representation of -(sys.maxint - 1) - again evaluates to a int object, not a long. + again evaluates to an int object, not a long. - Bug #1501934: The scope of global variables that are locally assigned using augmented assignment is now correctly determined. @@ -15212,7 +15212,7 @@ interpreter executions, would fail. - "%c" % u"a" now returns a unicode string instead of raising a - TypeError. u"%c" % 0xffffffff now raises a OverflowError instead + TypeError. u"%c" % 0xffffffff now raises an OverflowError instead of a ValueError to be consistent with "%c" % 256. See SF patch #710127. Extension modules @@ -23105,7 +23105,7 @@ - The interfaces for the bind*() and unbind() widget methods have been redesigned; the bind*() methods now return the name of the Tcl command -created for the callback, and this can be passed as a optional +created for the callback, and this can be passed as an optional argument to unbind() in order to delete the command (normally, such commands are automatically unbound when the widget is destroyed, but for some applications this isn't enough). diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -506,7 +506,7 @@ Tests ----- -- Issue #25099: Make test_compileall not fail when a entry on sys.path cannot +- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). - Issue #23919: Prevents assert dialogs appearing in the test suite. @@ -2158,7 +2158,7 @@ - Issue #23132: Improve performance and introspection support of comparison methods created by functool.total_ordering. -- Issue #19776: Add a expanduser() method on Path objects. +- Issue #19776: Add an expanduser() method on Path objects. - Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and fragment when it redirects to add a trailing slash. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -742,7 +742,7 @@ Conceptually, a rotate by one is equivalent to a pop on one side and an append on the other. However, a pop/append pair is unnecessarily slow -because it requires a incref/decref pair for an object located randomly +because it requires an incref/decref pair for an object located randomly in memory. It is better to just move the object pointer from one block to the next without changing the reference count. diff --git a/Modules/_ctypes/libffi/src/x86/darwin64.S b/Modules/_ctypes/libffi/src/x86/darwin64.S --- a/Modules/_ctypes/libffi/src/x86/darwin64.S +++ b/Modules/_ctypes/libffi/src/x86/darwin64.S @@ -350,7 +350,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi/src/x86/unix64.S b/Modules/_ctypes/libffi/src/x86/unix64.S --- a/Modules/_ctypes/libffi/src/x86/unix64.S +++ b/Modules/_ctypes/libffi/src/x86/unix64.S @@ -366,7 +366,7 @@ .byte 0x4 /* DW_CFA_advance_loc4 */ .long .LUW1-.LUW0 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -351,7 +351,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -684,7 +684,7 @@ if (openssl_obj_name == NULL) return; /* Ignore aliased names, they pollute the list and OpenSSL appears to - * have a its own definition of alias as the resulting list still + * have its own definition of alias as the resulting list still * contains duplicate and alternate names for several algorithms. */ if (openssl_obj_name->alias) return; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -75,7 +75,7 @@ "Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" "of streams into text. TextIOWrapper, which extends it, is a buffered text\n" "interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" +"is an in-memory stream for text.\n" "\n" "Argument names are not part of the specification, and only the arguments\n" "of open() are intended to be used as keyword arguments.\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -905,8 +905,8 @@ if (self->encoding == NULL) { catch_ImportError: /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a + Importing locale can raise an ImportError because of + _functools, and locale.getpreferredencoding can raise an ImportError if _locale is not available. These will happen during module building. */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4162,7 +4162,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -4173,7 +4173,7 @@ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=b5f31078dab17fb0 input=b8cdeb7e3f5ee674]*/ +/*[clinic end generated code: output=b5f31078dab17fb0 input=4faabdbc763c2389]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -6576,7 +6576,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -6593,7 +6593,7 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=e2c8ce748edc57b0 input=30b4dc9e976b890c]*/ +/*[clinic end generated code: output=e2c8ce748edc57b0 input=04ece661aa884837]*/ { _Py_IDENTIFIER(persistent_load); @@ -7012,7 +7012,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -7023,7 +7023,7 @@ static PyObject * _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=0de7dff89c406816 input=e9e5fdd48de92eae]*/ +/*[clinic end generated code: output=0de7dff89c406816 input=830f8a64cef6f042]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7122,7 +7122,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -7138,7 +7138,7 @@ static PyObject * _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=798f1c57cb2b4eb1 input=da97372e38e510a6]*/ +/*[clinic end generated code: output=798f1c57cb2b4eb1 input=2df7c7a1e6742204]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -257,7 +257,7 @@ PyDoc_STRVAR(atexit_unregister__doc__, "unregister(func) -> None\n\ \n\ -Unregister a exit function which was previously registered using\n\ +Unregister an exit function which was previously registered using\n\ atexit.register\n\ \n\ func - function to be unregistered"); diff --git a/Modules/audioop.c b/Modules/audioop.c --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -112,7 +112,7 @@ /* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * @@ -218,7 +218,7 @@ /* * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 13-bits. * diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -77,7 +77,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -260,7 +260,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -369,7 +369,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -462,7 +462,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -545,4 +545,4 @@ exit: return return_value; } -/*[clinic end generated code: output=06f3a5233298448e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aecd61660d1cf31d input=a9049054013a1b77]*/ diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -21,7 +21,7 @@ * * * The Solution: - * Prefix all a exported symbols with "PyExpat_". This is similar to + * Prefix all exported symbols with "PyExpat_". This is similar to * what Mozilla does for some common libs: * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115 * diff --git a/Modules/hashlib.h b/Modules/hashlib.h --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -30,7 +30,7 @@ /* * Helper code to synchronize access to the hash object when the GIL is * released around a CPU consuming hashlib operation. All code paths that - * access a mutable part of obj must be enclosed in a ENTER_HASHLIB / + * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / * LEAVE_HASHLIB block or explicitly acquire and release the lock inside * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for * an operation. diff --git a/Modules/readline.c b/Modules/readline.c --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1236,7 +1236,7 @@ return NULL; } - /* We got an EOF, return a empty string. */ + /* We got an EOF, return an empty string. */ if (p == NULL) { p = PyMem_RawMalloc(1); if (p != NULL) diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1288,7 +1288,7 @@ if (truncated == NULL || PyLong_Check(truncated)) return truncated; /* __trunc__ is specified to return an Integral type, - but int() needs to return a int. */ + but int() needs to return an int. */ m = truncated->ob_type->tp_as_number; if (m == NULL || m->nb_int == NULL) { PyErr_Format( diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -874,7 +874,7 @@ static int oserror_use_init(PyTypeObject *type) { - /* When __init__ is defined in a OSError subclass, we want any + /* When __init__ is defined in an OSError subclass, we want any extraneous argument to __new__ to be ignored. The only reasonable solution, given __new__ takes a variable number of arguments, is to defer arg parsing and initialization to __init__. diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -548,7 +548,7 @@ return 0; } if (u->u_ste->ste_needs_class_closure) { - /* Cook up a implicit __class__ cell. */ + /* Cook up an implicit __class__ cell. */ _Py_IDENTIFIER(__class__); PyObject *tuple, *name, *zero; int res; diff --git a/Python/thread.c b/Python/thread.c --- a/Python/thread.c +++ b/Python/thread.c @@ -31,7 +31,7 @@ threads. This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on a ia64 system instead + a check of __ia64 to verify that we're running on an ia64 system instead of a pa-risc system. */ #ifdef __hpux diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -91,7 +91,7 @@ def safety_limit(val): - # Given a integer value from the process being debugged, limit it to some + # Given an integer value from the process being debugged, limit it to some # safety threshold so that arbitrary breakage within said process doesn't # break the gdb process too much (e.g. sizes of iterations, sizes of lists) return min(val, 1000) @@ -158,7 +158,7 @@ class PyObjectPtr(object): """ - Class wrapping a gdb.Value that's a either a (PyObject*) within the + Class wrapping a gdb.Value that's either a (PyObject*) within the inferior process, or some subclass pointer e.g. (PyBytesObject*) There will be a subclass for every refined PyObject type that we care -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 00:04:59 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 02 Nov 2015 05:04:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Move_the_initial_start-sea?= =?utf-8?q?rch_out_of_the_main_loop_so_it_can_be_factored-out?= Message-ID: <20151102050459.59793.66294@psf.io> https://hg.python.org/cpython/rev/9d7848bd2302 changeset: 98932:9d7848bd2302 parent: 98927:9f8b5053e30d user: Raymond Hettinger date: Sun Nov 01 23:57:37 2015 -0500 summary: Move the initial start-search out of the main loop so it can be factored-out later. files: Modules/_collectionsmodule.c | 43 +++++++++++++++-------- 1 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1017,11 +1017,12 @@ static PyObject * deque_index(dequeobject *deque, PyObject *args) { - Py_ssize_t i, start=0, stop=Py_SIZE(deque); + Py_ssize_t i, n, start=0, stop=Py_SIZE(deque); PyObject *v, *item; block *b = deque->leftblock; Py_ssize_t index = deque->leftindex; size_t start_state = deque->state; + int cmp; if (!PyArg_ParseTuple(args, "O|O&O&:index", &v, _PyEval_SliceIndex, &start, @@ -1039,22 +1040,32 @@ } if (stop > Py_SIZE(deque)) stop = Py_SIZE(deque); + if (start > stop) + start = stop; + assert(0 <= start && start <= stop && stop <= Py_SIZE(deque)); - for (i=0 ; i= start) { - int cmp; - CHECK_NOT_END(b); - item = b->data[index]; - cmp = PyObject_RichCompareBool(item, v, Py_EQ); - if (cmp > 0) - return PyLong_FromSsize_t(i); - else if (cmp < 0) - return NULL; - if (start_state != deque->state) { - PyErr_SetString(PyExc_RuntimeError, - "deque mutated during iteration"); - return NULL; - } + /* XXX Replace this loop with faster code from deque_item() */ + for (i=0 ; irightlink; + index = 0; + } + } + + n = stop - i; + while (n--) { + CHECK_NOT_END(b); + item = b->data[index]; + cmp = PyObject_RichCompareBool(item, v, Py_EQ); + if (cmp > 0) + return PyLong_FromSsize_t(stop - (n + 1)); + else if (cmp < 0) + return NULL; + if (start_state != deque->state) { + PyErr_SetString(PyExc_RuntimeError, + "deque mutated during iteration"); + return NULL; } index++; if (index == BLOCKLEN) { -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 00:04:59 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 02 Nov 2015 05:04:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_default_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151102050459.59803.91676@psf.io> https://hg.python.org/cpython/rev/db778ec197a5 changeset: 98933:db778ec197a5 parent: 98932:9d7848bd2302 parent: 98931:96e61bb7f6e9 user: Raymond Hettinger date: Mon Nov 02 00:04:46 2015 -0500 summary: merge files: Doc/c-api/buffer.rst | 2 +- Doc/faq/programming.rst | 2 +- Doc/library/argparse.rst | 2 +- Doc/library/chunk.rst | 2 +- Doc/library/concurrent.futures.rst | 4 +- Doc/library/ctypes.rst | 2 +- Doc/library/difflib.rst | 2 +- Doc/library/fcntl.rst | 6 +- Doc/library/ftplib.rst | 4 +- Doc/library/functions.rst | 6 +- Doc/library/gzip.rst | 2 +- Doc/library/http.cookiejar.rst | 2 +- Doc/library/http.server.rst | 4 +- Doc/library/mailbox.rst | 2 +- Doc/library/multiprocessing.rst | 2 +- Doc/library/nntplib.rst | 2 +- Doc/library/optparse.rst | 2 +- Doc/library/os.path.rst | 2 +- Doc/library/pickle.rst | 4 +- Doc/library/pyexpat.rst | 2 +- Doc/library/shutil.rst | 4 +- Doc/library/smtplib.rst | 4 +- Doc/library/socket.rst | 4 +- Doc/library/sqlite3.rst | 2 +- Doc/library/stdtypes.rst | 2 +- Doc/library/sunau.rst | 4 +- Doc/library/tempfile.rst | 2 +- Doc/library/unittest.mock.rst | 2 +- Doc/library/xml.dom.pulldom.rst | 2 +- Doc/reference/datamodel.rst | 4 +- Doc/tutorial/errors.rst | 2 +- Doc/tutorial/introduction.rst | 2 +- Doc/whatsnew/2.1.rst | 2 +- Doc/whatsnew/2.3.rst | 2 +- Doc/whatsnew/3.1.rst | 2 +- Doc/whatsnew/3.2.rst | 4 +- Doc/whatsnew/3.3.rst | 2 +- Doc/whatsnew/3.5.rst | 2 +- Include/abstract.h | 2 +- Include/codecs.h | 4 +- Lib/_pyio.py | 2 +- Lib/asyncio/streams.py | 2 +- Lib/calendar.py | 2 +- Lib/chunk.py | 2 +- Lib/codecs.py | 6 +- Lib/concurrent/futures/_base.py | 2 +- Lib/concurrent/futures/process.py | 2 +- Lib/difflib.py | 2 +- Lib/distutils/cygwinccompiler.py | 6 +- Lib/ftplib.py | 4 +- Lib/getopt.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/ReplaceDialog.py | 2 +- Lib/io.py | 2 +- Lib/lib2to3/fixes/fix_input.py | 2 +- Lib/nntplib.py | 2 +- Lib/pickle.py | 4 +- Lib/signal.py | 2 +- Lib/test/decimaltestdata/fma.decTest | 1 + Lib/test/decimaltestdata/multiply.decTest | 1 + Lib/test/pystone.py | 2 +- Lib/test/support/__init__.py | 2 +- Lib/test/test_cmd.py | 2 +- Lib/test/test_codecs.py | 2 +- Lib/test/test_email/test_email.py | 2 +- Lib/test/test_ipaddress.py | 4 +- Lib/test/test_os.py | 2 +- Lib/test/test_urllib.py | 2 +- Lib/test/test_weakref.py | 2 +- Lib/tkinter/ttk.py | 2 +- Lib/unittest/test/test_discovery.py | 4 +- Lib/xmlrpc/client.py | 4 +- Misc/HISTORY | 30 +++++----- Misc/NEWS | 4 +- Modules/_collectionsmodule.c | 2 +- Modules/_ctypes/libffi/src/x86/darwin64.S | 2 +- Modules/_ctypes/libffi/src/x86/unix64.S | 2 +- Modules/_ctypes/libffi_osx/x86/darwin64.S | 2 +- Modules/_hashopenssl.c | 2 +- Modules/_io/_iomodule.c | 2 +- Modules/_io/textio.c | 4 +- Modules/_pickle.c | 16 ++-- Modules/atexitmodule.c | 2 +- Modules/audioop.c | 4 +- Modules/clinic/_pickle.c.h | 10 +- Modules/expat/pyexpatns.h | 2 +- Modules/hashlib.h | 2 +- Modules/readline.c | 2 +- Objects/abstract.c | 2 +- Objects/exceptions.c | 2 +- Python/compile.c | 2 +- Python/thread.c | 2 +- Tools/gdb/libpython.py | 4 +- 93 files changed, 146 insertions(+), 144 deletions(-) diff --git a/Doc/c-api/buffer.rst b/Doc/c-api/buffer.rst --- a/Doc/c-api/buffer.rst +++ b/Doc/c-api/buffer.rst @@ -40,7 +40,7 @@ Simple objects such as :class:`bytes` and :class:`bytearray` expose their underlying buffer in byte-oriented form. Other forms are possible; for example, -the elements exposed by a :class:`array.array` can be multi-byte values. +the elements exposed by an :class:`array.array` can be multi-byte values. An example consumer of the buffer interface is the :meth:`~io.BufferedIOBase.write` method of file objects: any object that can export a series of bytes through diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -849,7 +849,7 @@ You can't, because strings are immutable. In most situations, you should simply construct a new string from the various parts you want to assemble it from. However, if you need an object with the ability to modify in-place -unicode data, try using a :class:`io.StringIO` object or the :mod:`array` +unicode data, try using an :class:`io.StringIO` object or the :mod:`array` module:: >>> import io diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst --- a/Doc/library/argparse.rst +++ b/Doc/library/argparse.rst @@ -530,7 +530,7 @@ ^^^^^^^^^^^^ Normally, when you pass an argument list to the -:meth:`~ArgumentParser.parse_args` method of a :class:`ArgumentParser`, +:meth:`~ArgumentParser.parse_args` method of an :class:`ArgumentParser`, it :ref:`recognizes abbreviations ` of long options. This feature can be disabled by setting ``allow_abbrev`` to ``False``:: diff --git a/Doc/library/chunk.rst b/Doc/library/chunk.rst --- a/Doc/library/chunk.rst +++ b/Doc/library/chunk.rst @@ -47,7 +47,7 @@ the :class:`Chunk` class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end of the file, creating a new -instance will fail with a :exc:`EOFError` exception. +instance will fail with an :exc:`EOFError` exception. .. class:: Chunk(file, align=True, bigendian=True, inclheader=False) diff --git a/Doc/library/concurrent.futures.rst b/Doc/library/concurrent.futures.rst --- a/Doc/library/concurrent.futures.rst +++ b/Doc/library/concurrent.futures.rst @@ -90,7 +90,7 @@ ThreadPoolExecutor ------------------ -:class:`ThreadPoolExecutor` is a :class:`Executor` subclass that uses a pool of +:class:`ThreadPoolExecutor` is an :class:`Executor` subclass that uses a pool of threads to execute calls asynchronously. Deadlocks can occur when the callable associated with a :class:`Future` waits on @@ -304,7 +304,7 @@ Added callables are called in the order that they were added and are always called in a thread belonging to the process that added them. If - the callable raises a :exc:`Exception` subclass, it will be logged and + the callable raises an :exc:`Exception` subclass, it will be logged and ignored. If the callable raises a :exc:`BaseException` subclass, the behavior is undefined. diff --git a/Doc/library/ctypes.rst b/Doc/library/ctypes.rst --- a/Doc/library/ctypes.rst +++ b/Doc/library/ctypes.rst @@ -39,7 +39,7 @@ convention, while *windll* libraries call functions using the ``stdcall`` calling convention. *oledll* also uses the ``stdcall`` calling convention, and assumes the functions return a Windows :c:type:`HRESULT` error code. The error -code is used to automatically raise a :class:`OSError` exception when the +code is used to automatically raise an :class:`OSError` exception when the function call fails. .. versionchanged:: 3.3 diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -278,7 +278,7 @@ generating the delta lines) in unified diff format. Unified diffs are a compact way of showing just the lines that have changed plus - a few lines of context. The changes are shown in a inline style (instead of + a few lines of context. The changes are shown in an inline style (instead of separate before/after blocks). The number of context lines is set by *n* which defaults to three. diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -16,13 +16,13 @@ All functions in this module take a file descriptor *fd* as their first argument. This can be an integer file descriptor, such as returned by -``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin`` +``sys.stdin.fileno()``, or an :class:`io.IOBase` object, such as ``sys.stdin`` itself, which provides a :meth:`~io.IOBase.fileno` that returns a genuine file descriptor. .. versionchanged:: 3.3 - Operations in this module used to raise a :exc:`IOError` where they now - raise a :exc:`OSError`. + Operations in this module used to raise an :exc:`IOError` where they now + raise an :exc:`OSError`. The module defines the following functions: diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -287,9 +287,9 @@ .. method:: FTP.transfercmd(cmd, rest=None) - Initiate a transfer over the data connection. If the transfer is active, send a + Initiate a transfer over the data connection. If the transfer is active, send an ``EPRT`` or ``PORT`` command and the transfer command specified by *cmd*, and - accept the connection. If the server is passive, send a ``EPSV`` or ``PASV`` + accept the connection. If the server is passive, send an ``EPSV`` or ``PASV`` command, connect to it, and start the transfer command. Either way, return the socket for the connection. diff --git a/Doc/library/functions.rst b/Doc/library/functions.rst --- a/Doc/library/functions.rst +++ b/Doc/library/functions.rst @@ -1032,9 +1032,9 @@ :class:`io.TextIOBase` (specifically :class:`io.TextIOWrapper`). When used to open a file in a binary mode with buffering, the returned class is a subclass of :class:`io.BufferedIOBase`. The exact class varies: in read - binary mode, it returns a :class:`io.BufferedReader`; in write binary and - append binary modes, it returns a :class:`io.BufferedWriter`, and in - read/write mode, it returns a :class:`io.BufferedRandom`. When buffering is + binary mode, it returns an :class:`io.BufferedReader`; in write binary and + append binary modes, it returns an :class:`io.BufferedWriter`, and in + read/write mode, it returns an :class:`io.BufferedRandom`. When buffering is disabled, the raw stream, a subclass of :class:`io.RawIOBase`, :class:`io.FileIO`, is returned. diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -96,7 +96,7 @@ Calling a :class:`GzipFile` object's :meth:`close` method does not close *fileobj*, since you might wish to append more material after the compressed - data. This also allows you to pass a :class:`io.BytesIO` object opened for + data. This also allows you to pass an :class:`io.BytesIO` object opened for writing as *fileobj*, and retrieve the resulting memory buffer using the :class:`io.BytesIO` object's :meth:`~io.BytesIO.getvalue` method. diff --git a/Doc/library/http.cookiejar.rst b/Doc/library/http.cookiejar.rst --- a/Doc/library/http.cookiejar.rst +++ b/Doc/library/http.cookiejar.rst @@ -176,7 +176,7 @@ The *response* object (usually the result of a call to :meth:`urllib.request.urlopen`, or similar) should support an :meth:`info` - method, which returns a :class:`email.message.Message` instance. + method, which returns an :class:`email.message.Message` instance. The *request* object (usually a :class:`urllib.request.Request` instance) must support the methods :meth:`get_full_url`, :meth:`get_host`, diff --git a/Doc/library/http.server.rst b/Doc/library/http.server.rst --- a/Doc/library/http.server.rst +++ b/Doc/library/http.server.rst @@ -176,7 +176,7 @@ .. method:: handle_expect_100() - When a HTTP/1.1 compliant server receives a ``Expect: 100-continue`` + When a HTTP/1.1 compliant server receives an ``Expect: 100-continue`` request header it responds back with a ``100 Continue`` followed by ``200 OK`` headers. This method can be overridden to raise an error if the server does not @@ -210,7 +210,7 @@ are picked up from the :meth:`version_string` and :meth:`date_time_string` methods, respectively. If the server does not intend to send any other headers using the :meth:`send_header` method, - then :meth:`send_response` should be followed by a :meth:`end_headers` + then :meth:`send_response` should be followed by an :meth:`end_headers` call. .. versionchanged:: 3.3 diff --git a/Doc/library/mailbox.rst b/Doc/library/mailbox.rst --- a/Doc/library/mailbox.rst +++ b/Doc/library/mailbox.rst @@ -674,7 +674,7 @@ In Babyl mailboxes, the headers of a message are not stored contiguously with the body of the message. To generate a file-like representation, the - headers and body are copied together into a :class:`io.BytesIO` instance, + headers and body are copied together into an :class:`io.BytesIO` instance, which has an API identical to that of a file. As a result, the file-like object is truly independent of the underlying mailbox but does not save memory compared to a string diff --git a/Doc/library/multiprocessing.rst b/Doc/library/multiprocessing.rst --- a/Doc/library/multiprocessing.rst +++ b/Doc/library/multiprocessing.rst @@ -1046,7 +1046,7 @@ readable. .. versionchanged:: 3.3 - This function used to raise a :exc:`IOError`, which is now an + This function used to raise :exc:`IOError`, which is now an alias of :exc:`OSError`. diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -341,7 +341,7 @@ .. method:: NNTP.over(message_spec, *, file=None) - Send a ``OVER`` command, or a ``XOVER`` command on legacy servers. + Send an ``OVER`` command, or an ``XOVER`` command on legacy servers. *message_spec* can be either a string representing a message id, or a ``(first, last)`` tuple of numbers indicating a range of articles in the current group, or a ``(first, None)`` tuple indicating a range of diff --git a/Doc/library/optparse.rst b/Doc/library/optparse.rst --- a/Doc/library/optparse.rst +++ b/Doc/library/optparse.rst @@ -1324,7 +1324,7 @@ the list of arguments to process (default: ``sys.argv[1:]``) ``values`` - a :class:`optparse.Values` object to store option arguments in (default: a + an :class:`optparse.Values` object to store option arguments in (default: a new instance of :class:`Values`) -- if you give an existing object, the option defaults will not be initialized on it diff --git a/Doc/library/os.path.rst b/Doc/library/os.path.rst --- a/Doc/library/os.path.rst +++ b/Doc/library/os.path.rst @@ -289,7 +289,7 @@ Return ``True`` if both pathname arguments refer to the same file or directory. This is determined by the device number and i-node number and raises an - exception if a :func:`os.stat` call on either pathname fails. + exception if an :func:`os.stat` call on either pathname fails. Availability: Unix, Windows. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -221,7 +221,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file opened for - binary reading, a :class:`io.BytesIO` object, or any other custom object + binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -357,7 +357,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be an on-disk file object - opened for binary reading, a :class:`io.BytesIO` object, or any other + opened for binary reading, an :class:`io.BytesIO` object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, diff --git a/Doc/library/pyexpat.rst b/Doc/library/pyexpat.rst --- a/Doc/library/pyexpat.rst +++ b/Doc/library/pyexpat.rst @@ -763,7 +763,7 @@ .. data:: XML_ERROR_UNDEFINED_ENTITY - A reference was made to a entity which was not defined. + A reference was made to an entity which was not defined. .. data:: XML_ERROR_UNKNOWN_ENCODING diff --git a/Doc/library/shutil.rst b/Doc/library/shutil.rst --- a/Doc/library/shutil.rst +++ b/Doc/library/shutil.rst @@ -207,8 +207,8 @@ and metadata of the linked files are copied to the new tree. When *symlinks* is false, if the file pointed by the symlink doesn't - exist, a exception will be added in the list of errors raised in - a :exc:`Error` exception at the end of the copy process. + exist, an exception will be added in the list of errors raised in + an :exc:`Error` exception at the end of the copy process. You can set the optional *ignore_dangling_symlinks* flag to true if you want to silence this exception. Notice that this option has no effect on platforms that don't support :func:`os.symlink`. diff --git a/Doc/library/smtplib.rst b/Doc/library/smtplib.rst --- a/Doc/library/smtplib.rst +++ b/Doc/library/smtplib.rst @@ -22,7 +22,7 @@ .. class:: SMTP(host='', port=0, local_hostname=None[, timeout], source_address=None) - A :class:`SMTP` instance encapsulates an SMTP connection. It has methods + An :class:`SMTP` instance encapsulates an SMTP connection. It has methods that support a full repertoire of SMTP and ESMTP operations. If the optional host and port parameters are given, the SMTP :meth:`connect` method is called with those parameters during initialization. If specified, @@ -69,7 +69,7 @@ certfile=None [, timeout], context=None, \ source_address=None) - A :class:`SMTP_SSL` instance behaves exactly the same as instances of + An :class:`SMTP_SSL` instance behaves exactly the same as instances of :class:`SMTP`. :class:`SMTP_SSL` should be used for situations where SSL is required from the beginning of the connection and using :meth:`starttls` is not appropriate. If *host* is not specified, the local host is used. If diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -715,7 +715,7 @@ Supported values for *address_family* are currently :const:`AF_INET` and :const:`AF_INET6`. If the bytes object *packed_ip* is not the correct length for the specified address family, :exc:`ValueError` will be raised. - A :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. + :exc:`OSError` is raised for errors from the call to :func:`inet_ntop`. Availability: Unix (maybe not all platforms), Windows. @@ -1014,7 +1014,7 @@ interpreted the same way as by the built-in :func:`open` function. The socket must be in blocking mode; it can have a timeout, but the file - object's internal buffer may end up in a inconsistent state if a timeout + object's internal buffer may end up in an inconsistent state if a timeout occurs. Closing the file object returned by :meth:`makefile` won't close the diff --git a/Doc/library/sqlite3.rst b/Doc/library/sqlite3.rst --- a/Doc/library/sqlite3.rst +++ b/Doc/library/sqlite3.rst @@ -615,7 +615,7 @@ .. attribute:: lastrowid This read-only attribute provides the rowid of the last modified row. It is - only set if you issued a ``INSERT`` statement using the :meth:`execute` + only set if you issued an ``INSERT`` statement using the :meth:`execute` method. For operations other than ``INSERT`` or when :meth:`executemany` is called, :attr:`lastrowid` is set to :const:`None`. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -951,7 +951,7 @@ runtime cost, you must switch to one of the alternatives below: * if concatenating :class:`str` objects, you can build a list and use - :meth:`str.join` at the end or else write to a :class:`io.StringIO` + :meth:`str.join` at the end or else write to an :class:`io.StringIO` instance and retrieve its value when complete * if concatenating :class:`bytes` objects, you can similarly use diff --git a/Doc/library/sunau.rst b/Doc/library/sunau.rst --- a/Doc/library/sunau.rst +++ b/Doc/library/sunau.rst @@ -54,8 +54,8 @@ Note that it does not allow read/write files. - A *mode* of ``'r'`` returns a :class:`AU_read` object, while a *mode* of ``'w'`` - or ``'wb'`` returns a :class:`AU_write` object. + A *mode* of ``'r'`` returns an :class:`AU_read` object, while a *mode* of ``'w'`` + or ``'wb'`` returns an :class:`AU_write` object. .. function:: openfp(file, mode) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -96,7 +96,7 @@ causes the file to roll over to an on-disk file regardless of its size. The returned object is a file-like object whose :attr:`_file` attribute - is either a :class:`io.BytesIO` or :class:`io.StringIO` object (depending on + is either an :class:`io.BytesIO` or :class:`io.StringIO` object (depending on whether binary or text *mode* was specified) or a true file object, depending on whether :func:`rollover` has been called. This file-like object can be used in a :keyword:`with` statement, just like diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -1131,7 +1131,7 @@ ... TypeError: 'NonCallableMock' object is not callable -Another use case might be to replace an object with a :class:`io.StringIO` instance: +Another use case might be to replace an object with an :class:`io.StringIO` instance: >>> from io import StringIO >>> def foo(): diff --git a/Doc/library/xml.dom.pulldom.rst b/Doc/library/xml.dom.pulldom.rst --- a/Doc/library/xml.dom.pulldom.rst +++ b/Doc/library/xml.dom.pulldom.rst @@ -47,7 +47,7 @@ * :data:`PROCESSING_INSTRUCTION` * :data:`IGNORABLE_WHITESPACE` -``node`` is a object of type :class:`xml.dom.minidom.Document`, +``node`` is an object of type :class:`xml.dom.minidom.Document`, :class:`xml.dom.minidom.Element` or :class:`xml.dom.minidom.Text`. Since the document is treated as a "flat" stream of events, the document "tree" diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -2358,7 +2358,7 @@ ``__aiter__`` implementation, and an *asynchronous iterator* can call asynchronous code in its ``__anext__`` method. -Asynchronous iterators can be used in a :keyword:`async for` statement. +Asynchronous iterators can be used in an :keyword:`async for` statement. .. method:: object.__aiter__(self) @@ -2393,7 +2393,7 @@ An *asynchronous context manager* is a *context manager* that is able to suspend execution in its ``__aenter__`` and ``__aexit__`` methods. -Asynchronous context managers can be used in a :keyword:`async with` statement. +Asynchronous context managers can be used in an :keyword:`async with` statement. .. method:: object.__aenter__(self) diff --git a/Doc/tutorial/errors.rst b/Doc/tutorial/errors.rst --- a/Doc/tutorial/errors.rst +++ b/Doc/tutorial/errors.rst @@ -336,7 +336,7 @@ A *finally clause* is always executed before leaving the :keyword:`try` statement, whether an exception has occurred or not. When an exception has occurred in the :keyword:`try` clause and has not been handled by an -:keyword:`except` clause (or it has occurred in a :keyword:`except` or +:keyword:`except` clause (or it has occurred in an :keyword:`except` or :keyword:`else` clause), it is re-raised after the :keyword:`finally` clause has been executed. The :keyword:`finally` clause is also executed "on the way out" when any other clause of the :keyword:`try` statement is left via a diff --git a/Doc/tutorial/introduction.rst b/Doc/tutorial/introduction.rst --- a/Doc/tutorial/introduction.rst +++ b/Doc/tutorial/introduction.rst @@ -303,7 +303,7 @@ indices, if both are within bounds. For example, the length of ``word[1:3]`` is 2. -Attempting to use a index that is too large will result in an error:: +Attempting to use an index that is too large will result in an error:: >>> word[42] # the word only has 6 characters Traceback (most recent call last): diff --git a/Doc/whatsnew/2.1.rst b/Doc/whatsnew/2.1.rst --- a/Doc/whatsnew/2.1.rst +++ b/Doc/whatsnew/2.1.rst @@ -555,7 +555,7 @@ and experiment with them. With the result experience, perhaps it'll be possible to design a really good catalog and then build support for it into Python 2.2. For example, the Distutils :command:`sdist` and :command:`bdist_\*` commands -could support a ``upload`` option that would automatically upload your +could support an ``upload`` option that would automatically upload your package to a catalog server. You can start creating packages containing :file:`PKG-INFO` even if you're not diff --git a/Doc/whatsnew/2.3.rst b/Doc/whatsnew/2.3.rst --- a/Doc/whatsnew/2.3.rst +++ b/Doc/whatsnew/2.3.rst @@ -411,7 +411,7 @@ A new built-in function, :func:`enumerate`, will make certain loops a bit clearer. ``enumerate(thing)``, where *thing* is either an iterator or a -sequence, returns a iterator that will return ``(0, thing[0])``, ``(1, +sequence, returns an iterator that will return ``(0, thing[0])``, ``(1, thing[1])``, ``(2, thing[2])``, and so forth. A common idiom to change every element of a list looks like this:: diff --git a/Doc/whatsnew/3.1.rst b/Doc/whatsnew/3.1.rst --- a/Doc/whatsnew/3.1.rst +++ b/Doc/whatsnew/3.1.rst @@ -336,7 +336,7 @@ (Contributed by David Laban; :issue:`4739`.) * The :mod:`unittest` module now supports skipping individual tests or classes - of tests. And it supports marking a test as a expected failure, a test that + of tests. And it supports marking a test as an expected failure, a test that is known to be broken, but shouldn't be counted as a failure on a TestResult:: diff --git a/Doc/whatsnew/3.2.rst b/Doc/whatsnew/3.2.rst --- a/Doc/whatsnew/3.2.rst +++ b/Doc/whatsnew/3.2.rst @@ -788,7 +788,7 @@ :issue:`8814`.) * To help write classes with rich comparison methods, a new decorator - :func:`functools.total_ordering` will use a existing equality and inequality + :func:`functools.total_ordering` will use existing equality and inequality methods to fill in the remaining methods. For example, supplying *__eq__* and *__lt__* will enable @@ -1399,7 +1399,7 @@ Also, the :class:`zipfile.ZipExtFile` class was reworked internally to represent files stored inside an archive. The new implementation is significantly faster -and can be wrapped in a :class:`io.BufferedReader` object for more speedups. It +and can be wrapped in an :class:`io.BufferedReader` object for more speedups. It also solves an issue where interleaved calls to *read* and *readline* gave the wrong results. diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -1421,7 +1421,7 @@ :class:`http.client.HTTPResponse` now has a :meth:`~http.client.HTTPResponse.readinto` method, which means it can be used -as a :class:`io.RawIOBase` class. (Contributed by John Kuhn in +as an :class:`io.RawIOBase` class. (Contributed by John Kuhn in :issue:`13464`.) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -465,7 +465,7 @@ PEP 475: Retry system calls failing with EINTR ---------------------------------------------- -A :py:data:`errno.EINTR` error code is returned whenever a system call, that +An :py:data:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would raise :exc:`InterruptedError` in such case. This meant that, when writing a Python application, the developer had two choices: diff --git a/Include/abstract.h b/Include/abstract.h --- a/Include/abstract.h +++ b/Include/abstract.h @@ -95,7 +95,7 @@ numeric, sequence, and mapping. Each protocol consists of a collection of related operations. If an operation that is not provided by a particular type is invoked, then a standard exception, - NotImplementedError is raised with a operation name as an argument. + NotImplementedError is raised with an operation name as an argument. In addition, for convenience this interface defines a set of constructors for building objects of built-in types. This is needed so new objects can be returned from C functions that otherwise treat diff --git a/Include/codecs.h b/Include/codecs.h --- a/Include/codecs.h +++ b/Include/codecs.h @@ -165,14 +165,14 @@ const char *encoding ); -/* Get a IncrementalEncoder object for the given encoding. */ +/* Get an IncrementalEncoder object for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalEncoder( const char *encoding, const char *errors ); -/* Get a IncrementalDecoder object function for the given encoding. */ +/* Get an IncrementalDecoder object function for the given encoding. */ PyAPI_FUNC(PyObject *) PyCodec_IncrementalDecoder( const char *encoding, diff --git a/Lib/_pyio.py b/Lib/_pyio.py --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -2512,7 +2512,7 @@ def __repr__(self): # TextIOWrapper tells the encoding in its repr. In StringIO, - # that's a implementation detail. + # that's an implementation detail. return object.__repr__(self) @property diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -255,7 +255,7 @@ def __init__(self, transport, protocol, reader, loop): self._transport = transport self._protocol = protocol - # drain() expects that the reader has a exception() method + # drain() expects that the reader has an exception() method assert reader is None or isinstance(reader, StreamReader) self._reader = reader self._loop = loop diff --git a/Lib/calendar.py b/Lib/calendar.py --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -142,7 +142,7 @@ def iterweekdays(self): """ - Return a iterator for one week of weekday numbers starting with the + Return an iterator for one week of weekday numbers starting with the configured first one. """ for i in range(self.firstweekday, self.firstweekday + 7): diff --git a/Lib/chunk.py b/Lib/chunk.py --- a/Lib/chunk.py +++ b/Lib/chunk.py @@ -21,7 +21,7 @@ usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end -of the file, creating a new instance will fail with a EOFError +of the file, creating a new instance will fail with an EOFError exception. Usage: diff --git a/Lib/codecs.py b/Lib/codecs.py --- a/Lib/codecs.py +++ b/Lib/codecs.py @@ -258,7 +258,7 @@ """ def __init__(self, errors='strict'): """ - Create a IncrementalDecoder instance. + Create an IncrementalDecoder instance. The IncrementalDecoder may use different error handling schemes by providing the errors keyword argument. See the module docstring @@ -1011,7 +1011,7 @@ """ Encoding iterator. - Encodes the input strings from the iterator using a IncrementalEncoder. + Encodes the input strings from the iterator using an IncrementalEncoder. errors and kwargs are passed through to the IncrementalEncoder constructor. @@ -1029,7 +1029,7 @@ """ Decoding iterator. - Decodes the input strings from the iterator using a IncrementalDecoder. + Decodes the input strings from the iterator using an IncrementalDecoder. errors and kwargs are passed through to the IncrementalDecoder constructor. diff --git a/Lib/concurrent/futures/_base.py b/Lib/concurrent/futures/_base.py --- a/Lib/concurrent/futures/_base.py +++ b/Lib/concurrent/futures/_base.py @@ -521,7 +521,7 @@ raise NotImplementedError() def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -456,7 +456,7 @@ submit.__doc__ = _base.Executor.submit.__doc__ def map(self, fn, *iterables, timeout=None, chunksize=1): - """Returns a iterator equivalent to map(fn, iter). + """Returns an iterator equivalent to map(fn, iter). Args: fn: A callable that will take as many arguments as there are diff --git a/Lib/difflib.py b/Lib/difflib.py --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -1515,7 +1515,7 @@ yield _make_line(lines,'-',0), None, True continue elif s.startswith(('--?+', '--+', '- ')): - # in delete block and see a intraline change or unchanged line + # in delete block and see an intraline change or unchanged line # coming: yield the delete line and then blanks from_line,to_line = _make_line(lines,'-',0), None num_blanks_to_yield,num_blanks_pending = num_blanks_pending-1,0 diff --git a/Lib/distutils/cygwinccompiler.py b/Lib/distutils/cygwinccompiler.py --- a/Lib/distutils/cygwinccompiler.py +++ b/Lib/distutils/cygwinccompiler.py @@ -10,9 +10,9 @@ # # * if you use a msvc compiled python version (1.5.2) # 1. you have to insert a __GNUC__ section in its config.h -# 2. you have to generate a import library for its dll +# 2. you have to generate an import library for its dll # - create a def-file for python??.dll -# - create a import library using +# - create an import library using # dlltool --dllname python15.dll --def python15.def \ # --output-lib libpython15.a # @@ -318,7 +318,7 @@ self.dll_libraries = get_msvcr() # Because these compilers aren't configured in Python's pyconfig.h file by -# default, we should at least warn the user if he is using a unmodified +# default, we should at least warn the user if he is using an unmodified # version. CONFIG_H_OK = "ok" diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -287,7 +287,7 @@ return self.voidcmd(cmd) def sendeprt(self, host, port): - '''Send a EPRT command with the current host and the given port number.''' + '''Send an EPRT command with the current host and the given port number.''' af = 0 if self.af == socket.AF_INET: af = 1 @@ -852,7 +852,7 @@ def parse229(resp, peer): - '''Parse the '229' response for a EPSV request. + '''Parse the '229' response for an EPSV request. Raises error_proto if it does not contain '(|||port|)' Return ('host.addr.as.numbers', port#) tuple.''' diff --git a/Lib/getopt.py b/Lib/getopt.py --- a/Lib/getopt.py +++ b/Lib/getopt.py @@ -28,7 +28,7 @@ # - RETURN_IN_ORDER option # - GNU extension with '-' as first character of option string # - optional arguments, specified by double colons -# - a option string with a W followed by semicolon should +# - an option string with a W followed by semicolon should # treat "-W foo" as "--foo" __all__ = ["GetoptError","error","getopt","gnu_getopt"] diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -1379,7 +1379,7 @@ text.see("insert") text.undo_block_stop() - # Our editwin provides a is_char_in_string function that works + # Our editwin provides an is_char_in_string function that works # with a Tk text index, but PyParse only knows about offsets into # a string. This builds a function for PyParse that accepts an # offset. diff --git a/Lib/idlelib/ReplaceDialog.py b/Lib/idlelib/ReplaceDialog.py --- a/Lib/idlelib/ReplaceDialog.py +++ b/Lib/idlelib/ReplaceDialog.py @@ -59,7 +59,7 @@ def default_command(self, event=None): if self.do_find(self.ok): if self.do_replace(): # Only find next match if replace succeeded. - # A bad re can cause a it to fail. + # A bad re can cause it to fail. self.do_find(0) def _replace_expand(self, m, repl): diff --git a/Lib/io.py b/Lib/io.py --- a/Lib/io.py +++ b/Lib/io.py @@ -19,7 +19,7 @@ Another IOBase subclass, TextIOBase, deals with the encoding and decoding of streams into text. TextIOWrapper, which extends it, is a buffered text interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO -is a in-memory stream for text. +is an in-memory stream for text. Argument names are not part of the specification, and only the arguments of open() are intended to be used as keyword arguments. diff --git a/Lib/lib2to3/fixes/fix_input.py b/Lib/lib2to3/fixes/fix_input.py --- a/Lib/lib2to3/fixes/fix_input.py +++ b/Lib/lib2to3/fixes/fix_input.py @@ -17,7 +17,7 @@ """ def transform(self, node, results): - # If we're already wrapped in a eval() call, we're done. + # If we're already wrapped in an eval() call, we're done. if context.match(node.parent.parent): return diff --git a/Lib/nntplib.py b/Lib/nntplib.py --- a/Lib/nntplib.py +++ b/Lib/nntplib.py @@ -201,7 +201,7 @@ return fmt def _parse_overview(lines, fmt, data_process_func=None): - """Parse the response to a OVER or XOVER command according to the + """Parse the response to an OVER or XOVER command according to the overview format `fmt`.""" n_defaults = len(_DEFAULT_OVERVIEW_FMT) overview = [] diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -359,7 +359,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for - binary writing, a io.BytesIO instance, or any other custom + binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and *protocol* is less than 3, pickle @@ -991,7 +991,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* - can be a binary file object opened for reading, a io.BytesIO + can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. The file-like object must have two methods, a read() method diff --git a/Lib/signal.py b/Lib/signal.py --- a/Lib/signal.py +++ b/Lib/signal.py @@ -34,7 +34,7 @@ def _enum_to_int(value): """Convert an IntEnum member to a numeric value. - If it's not a IntEnum member return the value itself. + If it's not an IntEnum member return the value itself. """ try: return int(value) diff --git a/Lib/test/decimaltestdata/fma.decTest b/Lib/test/decimaltestdata/fma.decTest --- a/Lib/test/decimaltestdata/fma.decTest +++ b/Lib/test/decimaltestdata/fma.decTest @@ -148,7 +148,7 @@ fmax2019 fma -9.999999 9.999999 0E+999999 -> -100.000 Inexact Rounded fmax2020 fma -9.999999 -9.999999 0E+999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 fmax2059 fma 999999999999 9765625 0E+999999 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/decimaltestdata/multiply.decTest b/Lib/test/decimaltestdata/multiply.decTest --- a/Lib/test/decimaltestdata/multiply.decTest +++ b/Lib/test/decimaltestdata/multiply.decTest @@ -49,7 +49,7 @@ mulx019 multiply -9.999999999 9.999999999 -> -100.000 Inexact Rounded mulx020 multiply -9.999999999 -9.999999999 -> 100.000 Inexact Rounded --- 1999.12.21: next one is a edge case if intermediate longs are used +-- 1999.12.21: next one is an edge case if intermediate longs are used precision: 15 mulx059 multiply 999999999999 9765625 -> 9.76562499999023E+18 Inexact Rounded precision: 30 diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py --- a/Lib/test/pystone.py +++ b/Lib/test/pystone.py @@ -35,7 +35,7 @@ Under Python 3 version 1.1 would use the normal division operator, resulting in some of the operations mistakenly yielding floats. Version 1.2 instead uses floor division - making the benchmark a integer benchmark again. + making the benchmark an integer benchmark again. """ diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -309,7 +309,7 @@ # The exponential backoff of the timeout amounts to a total # of ~1 second after which the deletion is probably an error # anyway. - # Testing on a i7 at 4.3GHz shows that usually only 1 iteration is + # Testing on an i7 at 4.3GHz shows that usually only 1 iteration is # required when contention occurs. timeout = 0.001 while timeout < 1.0: diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -110,7 +110,7 @@ 5 12 19 6 13 - This is a interactive test, put some commands in the cmdqueue attribute + This is an interactive test, put some commands in the cmdqueue attribute and let it execute This test includes the preloop(), postloop(), default(), emptyline(), parseline(), do_help() functions diff --git a/Lib/test/test_codecs.py b/Lib/test/test_codecs.py --- a/Lib/test/test_codecs.py +++ b/Lib/test/test_codecs.py @@ -100,7 +100,7 @@ self.assertEqual(r.read(), "") self.assertEqual(r.bytebuffer, b"") - # do the check again, this time using a incremental decoder + # do the check again, this time using an incremental decoder d = codecs.getincrementaldecoder(self.encoding)() result = "" for (c, partialresult) in zip(input.encode(self.encoding), partialresults): diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3052,7 +3052,7 @@ # issue 1690608. email.utils.formataddr() should be rfc2047 aware. name = "H\u00e4ns W\u00fcrst" addr = 'person at dom.ain' - # A object without a header_encode method: + # An object without a header_encode method: bad_charset = object() self.assertRaises(AttributeError, utils.formataddr, (name, addr), bad_charset) diff --git a/Lib/test/test_ipaddress.py b/Lib/test/test_ipaddress.py --- a/Lib/test/test_ipaddress.py +++ b/Lib/test/test_ipaddress.py @@ -1302,7 +1302,7 @@ # test a /24 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1.1.1.0/24')) - # test an IPv4 range that isn't on a network byte boundary + # test an IPv4 range that isn't on a network byte boundary ip2 = ipaddress.ip_address('1.1.1.8') self.assertEqual(list(summarize(ip1, ip2)), [ipaddress.ip_network('1.1.1.0/29'), @@ -1315,7 +1315,7 @@ ip1 = ipaddress.ip_address('1::') ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff') - # test a IPv6 is sumamrized properly + # test an IPv6 is summarized properly self.assertEqual(list(summarize(ip1, ip2))[0], ipaddress.ip_network('1::/16')) # test an IPv6 range that isn't on a network byte boundary diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1448,7 +1448,7 @@ except OSError as e: self.assertEqual(e.errno, errno.EBADF) else: - self.fail("%r didn't raise a OSError with a bad file descriptor" + self.fail("%r didn't raise an OSError with a bad file descriptor" % f) @unittest.skipUnless(hasattr(os, 'isatty'), 'test needs os.isatty()') diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py --- a/Lib/test/test_urllib.py +++ b/Lib/test/test_urllib.py @@ -527,7 +527,7 @@ result = urllib.request.urlretrieve("file:%s" % support.TESTFN) self.assertEqual(result[0], support.TESTFN) self.assertIsInstance(result[1], email.message.Message, - "did not get a email.message.Message instance " + "did not get an email.message.Message instance " "as second returned value") def test_copy(self): diff --git a/Lib/test/test_weakref.py b/Lib/test/test_weakref.py --- a/Lib/test/test_weakref.py +++ b/Lib/test/test_weakref.py @@ -947,7 +947,7 @@ class WeakMethodTestCase(unittest.TestCase): def _subclass(self): - """Return a Object subclass overriding `some_method`.""" + """Return an Object subclass overriding `some_method`.""" class C(Object): def some_method(self): return 6 diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -289,7 +289,7 @@ """Format options then call Tk command with args and options and return the appropriate result. - If no option is specified, a dict is returned. If a option is + If no option is specified, a dict is returned. If an option is specified with the None value, the value for that option is returned. Otherwise, the function just sets the passed options and the caller shouldn't be expecting a return value anyway.""" diff --git a/Lib/unittest/test/test_discovery.py b/Lib/unittest/test/test_discovery.py --- a/Lib/unittest/test/test_discovery.py +++ b/Lib/unittest/test/test_discovery.py @@ -255,12 +255,12 @@ self.addCleanup(sys.path.remove, abspath('/foo')) # Test data: we expect the following: - # a listdir to find our package, and a isfile and isdir check on it. + # a listdir to find our package, and isfile and isdir checks on it. # a module-from-name call to turn that into a module # followed by load_tests. # then our load_tests will call discover() which is messy # but that finally chains into find_tests again for the child dir - - # which is why we don't have a infinite loop. + # which is why we don't have an infinite loop. # We expect to see: # the module load tests for both package and plain module called, # and the plain module result nested by the package module load_tests diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -823,7 +823,7 @@ raise ValueError("unexpected type in multicall result") class MultiCall: - """server -> a object used to boxcar method calls + """server -> an object used to boxcar method calls server should be a ServerProxy object. @@ -1170,7 +1170,7 @@ ## # Create parser. # - # @return A 2-tuple containing a parser and a unmarshaller. + # @return A 2-tuple containing a parser and an unmarshaller. def getparser(self): # get parser and unmarshaller diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1331,7 +1331,7 @@ import as they are meant for use by importlib. - Issue #14474: Save and restore exception state in thread.start_new_thread() - while writing error message if the thread leaves a unhandled exception. + while writing error message if the thread leaves an unhandled exception. - Issue #13019: Fix potential reference leaks in bytearray.extend(). Patch by Suman Saha. @@ -1969,7 +1969,7 @@ - Issue #7732: Don't open a directory as a file anymore while importing a module. Ignore the directory if its name matches the module name (e.g. - "__init__.py") and raise a ImportError instead. + "__init__.py") and raise an ImportError instead. - Issue #13021: Missing decref on an error path. Thanks to Suman Saha for finding the bug and providing a patch. @@ -2021,7 +2021,7 @@ - Issue #10271: Allow warnings.showwarning() be any callable. -- Issue #11627: Fix segfault when __new__ on a exception returns a +- Issue #11627: Fix segfault when __new__ on an exception returns a non-exception class. - Issue #12149: Update the method cache after a type's dictionary gets @@ -2050,7 +2050,7 @@ with other data interleaved between marshalled objects. - Issue #12356: When required positional or keyword-only arguments are not - given, produce a informative error message which includes the name(s) of the + given, produce an informative error message which includes the name(s) of the missing arguments. - Issue #12370: Fix super with no arguments when __class__ is overriden in the @@ -2651,7 +2651,7 @@ - Issue #12529: fix cgi.parse_header issue on strings with double-quotes and semicolons together. Patch by Ben Darnell and Petri Lehtinen. -- Issue #13227: functools.lru_cache() now has a option to distinguish +- Issue #13227: functools.lru_cache() now has an option to distinguish calls with different argument types. - Issue #6090: zipfile raises a ValueError when a document with a timestamp @@ -2914,7 +2914,7 @@ - Issue #12502: asyncore: fix polling loop with AF_UNIX sockets. -- Issue #4376: ctypes now supports nested structures in a endian different than +- Issue #4376: ctypes now supports nested structures in an endian different than the parent structure. Patch by Vlad Riscutia. - Raise ValueError when attempting to set the _CHUNK_SIZE attribute of a @@ -2935,7 +2935,7 @@ Linux for example, to have the same behaviour on all platforms. - Issue #12451: pydoc: html_getfile() now uses tokenize.open() to support - Python scripts using a encoding different than UTF-8 (read the coding cookie + Python scripts using an encoding different than UTF-8 (read the coding cookie of the script). - Issue #12493: subprocess: Popen.communicate() now also handles EINTR errors @@ -5113,7 +5113,7 @@ ``MaybeEncodingError`` exception. - Issue #9244: The ``apply_async()`` and ``map_async()`` methods of - ``multiprocessing.Pool`` now accepts a ``error_callback`` argument. This can + ``multiprocessing.Pool`` now accepts an ``error_callback`` argument. This can be a callback with the signature ``callback(exc)``, which will be called if the target raises an exception. @@ -5210,7 +5210,7 @@ - Close file objects in modulefinder in a timely manner. -- Close a io.TextIOWrapper object in email.parser in a timely manner. +- Close an io.TextIOWrapper object in email.parser in a timely manner. - Close a file object in distutils.sysconfig in a timely manner. @@ -7308,7 +7308,7 @@ - Issue #7610: Reworked implementation of the internal ``zipfile.ZipExtFile`` class used to represent files stored inside an archive. The new implementation is significantly faster and can be wrapped in - a ``io.BufferedReader`` object for more speedups. It also solves an + an ``io.BufferedReader`` object for more speedups. It also solves an issue where interleaved calls to `read()` and `readline()` give wrong results. Patch by Nir Aides. @@ -8683,7 +8683,7 @@ - Issue #5624: Fix the _winreg module name still used in several modules. -- Issue #5628: Fix io.TextIOWrapper.read() with a unreadable buffer. +- Issue #5628: Fix io.TextIOWrapper.read() with an unreadable buffer. - Issue #5619: Multiprocessing children disobey the debug flag and causes popups on windows buildbots. Patch applied to work around this issue. @@ -9649,7 +9649,7 @@ - Issue #4307: The named tuple that ``inspect.getfullargspec()`` returns now uses ``kwonlydefaults`` instead of ``kwdefaults``. -- Issue #4298: Fix a segfault when pickle.loads is passed a ill-formed input. +- Issue #4298: Fix a segfault when pickle.loads is passed ill-formed input. - Issue #4283: Fix a left-over "iteritems" call in distutils. @@ -11305,7 +11305,7 @@ ----------------- - Bug #1441486: The literal representation of -(sys.maxint - 1) - again evaluates to a int object, not a long. + again evaluates to an int object, not a long. - Bug #1501934: The scope of global variables that are locally assigned using augmented assignment is now correctly determined. @@ -15212,7 +15212,7 @@ interpreter executions, would fail. - "%c" % u"a" now returns a unicode string instead of raising a - TypeError. u"%c" % 0xffffffff now raises a OverflowError instead + TypeError. u"%c" % 0xffffffff now raises an OverflowError instead of a ValueError to be consistent with "%c" % 256. See SF patch #710127. Extension modules @@ -23105,7 +23105,7 @@ - The interfaces for the bind*() and unbind() widget methods have been redesigned; the bind*() methods now return the name of the Tcl command -created for the callback, and this can be passed as a optional +created for the callback, and this can be passed as an optional argument to unbind() in order to delete the command (normally, such commands are automatically unbound when the widget is destroyed, but for some applications this isn't enough). diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -506,7 +506,7 @@ Tests ----- -- Issue #25099: Make test_compileall not fail when a entry on sys.path cannot +- Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). - Issue #23919: Prevents assert dialogs appearing in the test suite. @@ -2158,7 +2158,7 @@ - Issue #23132: Improve performance and introspection support of comparison methods created by functool.total_ordering. -- Issue #19776: Add a expanduser() method on Path objects. +- Issue #19776: Add an expanduser() method on Path objects. - Issue #23112: Fix SimpleHTTPServer to correctly carry the query string and fragment when it redirects to add a trailing slash. diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -742,7 +742,7 @@ Conceptually, a rotate by one is equivalent to a pop on one side and an append on the other. However, a pop/append pair is unnecessarily slow -because it requires a incref/decref pair for an object located randomly +because it requires an incref/decref pair for an object located randomly in memory. It is better to just move the object pointer from one block to the next without changing the reference count. diff --git a/Modules/_ctypes/libffi/src/x86/darwin64.S b/Modules/_ctypes/libffi/src/x86/darwin64.S --- a/Modules/_ctypes/libffi/src/x86/darwin64.S +++ b/Modules/_ctypes/libffi/src/x86/darwin64.S @@ -350,7 +350,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi/src/x86/unix64.S b/Modules/_ctypes/libffi/src/x86/unix64.S --- a/Modules/_ctypes/libffi/src/x86/unix64.S +++ b/Modules/_ctypes/libffi/src/x86/unix64.S @@ -366,7 +366,7 @@ .byte 0x4 /* DW_CFA_advance_loc4 */ .long .LUW1-.LUW0 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_ctypes/libffi_osx/x86/darwin64.S b/Modules/_ctypes/libffi_osx/x86/darwin64.S --- a/Modules/_ctypes/libffi_osx/x86/darwin64.S +++ b/Modules/_ctypes/libffi_osx/x86/darwin64.S @@ -351,7 +351,7 @@ .set L$set$3,LUW1-LUW0 .long L$set$3 - /* New stack frame based off rbp. This is a itty bit of unwind + /* New stack frame based off rbp. This is an itty bit of unwind trickery in that the CFA *has* changed. There is no easy way to describe it correctly on entry to the function. Fortunately, it doesn't matter too much since at all points we can correctly diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c --- a/Modules/_hashopenssl.c +++ b/Modules/_hashopenssl.c @@ -684,7 +684,7 @@ if (openssl_obj_name == NULL) return; /* Ignore aliased names, they pollute the list and OpenSSL appears to - * have a its own definition of alias as the resulting list still + * have its own definition of alias as the resulting list still * contains duplicate and alternate names for several algorithms. */ if (openssl_obj_name->alias) return; diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -75,7 +75,7 @@ "Another IOBase subclass, TextIOBase, deals with the encoding and decoding\n" "of streams into text. TextIOWrapper, which extends it, is a buffered text\n" "interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO\n" -"is a in-memory stream for text.\n" +"is an in-memory stream for text.\n" "\n" "Argument names are not part of the specification, and only the arguments\n" "of open() are intended to be used as keyword arguments.\n" diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -905,8 +905,8 @@ if (self->encoding == NULL) { catch_ImportError: /* - Importing locale can raise a ImportError because of - _functools, and locale.getpreferredencoding can raise a + Importing locale can raise an ImportError because of + _functools, and locale.getpreferredencoding can raise an ImportError if _locale is not available. These will happen during module building. */ diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4162,7 +4162,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -4173,7 +4173,7 @@ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=b5f31078dab17fb0 input=b8cdeb7e3f5ee674]*/ +/*[clinic end generated code: output=b5f31078dab17fb0 input=4faabdbc763c2389]*/ { _Py_IDENTIFIER(persistent_id); _Py_IDENTIFIER(dispatch_table); @@ -6576,7 +6576,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -6593,7 +6593,7 @@ _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=e2c8ce748edc57b0 input=30b4dc9e976b890c]*/ +/*[clinic end generated code: output=e2c8ce748edc57b0 input=04ece661aa884837]*/ { _Py_IDENTIFIER(persistent_load); @@ -7012,7 +7012,7 @@ The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary -writing, a io.BytesIO instance, or any other custom object that meets +writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try @@ -7023,7 +7023,7 @@ static PyObject * _pickle_dump_impl(PyModuleDef *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports) -/*[clinic end generated code: output=0de7dff89c406816 input=e9e5fdd48de92eae]*/ +/*[clinic end generated code: output=0de7dff89c406816 input=830f8a64cef6f042]*/ { PicklerObject *pickler = _Pickler_New(); @@ -7122,7 +7122,7 @@ The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a -binary file object opened for reading, a io.BytesIO object, or any +binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, @@ -7138,7 +7138,7 @@ static PyObject * _pickle_load_impl(PyModuleDef *module, PyObject *file, int fix_imports, const char *encoding, const char *errors) -/*[clinic end generated code: output=798f1c57cb2b4eb1 input=da97372e38e510a6]*/ +/*[clinic end generated code: output=798f1c57cb2b4eb1 input=2df7c7a1e6742204]*/ { PyObject *result; UnpicklerObject *unpickler = _Unpickler_New(); diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c --- a/Modules/atexitmodule.c +++ b/Modules/atexitmodule.c @@ -257,7 +257,7 @@ PyDoc_STRVAR(atexit_unregister__doc__, "unregister(func) -> None\n\ \n\ -Unregister a exit function which was previously registered using\n\ +Unregister an exit function which was previously registered using\n\ atexit.register\n\ \n\ func - function to be unregistered"); diff --git a/Modules/audioop.c b/Modules/audioop.c --- a/Modules/audioop.c +++ b/Modules/audioop.c @@ -112,7 +112,7 @@ /* * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 14-bits. * @@ -218,7 +218,7 @@ /* * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data - * stored in a unsigned char. This function should only be called with + * stored in an unsigned char. This function should only be called with * the data shifted such that it only contains information in the lower * 13-bits. * diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h --- a/Modules/clinic/_pickle.c.h +++ b/Modules/clinic/_pickle.c.h @@ -77,7 +77,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -260,7 +260,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -369,7 +369,7 @@ "\n" "The *file* argument must have a write() method that accepts a single\n" "bytes argument. It can thus be a file object opened for binary\n" -"writing, a io.BytesIO instance, or any other custom object that meets\n" +"writing, an io.BytesIO instance, or any other custom object that meets\n" "this interface.\n" "\n" "If *fix_imports* is True and protocol is less than 3, pickle will try\n" @@ -462,7 +462,7 @@ "The argument *file* must have two methods, a read() method that takes\n" "an integer argument, and a readline() method that requires no\n" "arguments. Both methods should return bytes. Thus *file* can be a\n" -"binary file object opened for reading, a io.BytesIO object, or any\n" +"binary file object opened for reading, an io.BytesIO object, or any\n" "other custom object that meets this interface.\n" "\n" "Optional keyword arguments are *fix_imports*, *encoding* and *errors*,\n" @@ -545,4 +545,4 @@ exit: return return_value; } -/*[clinic end generated code: output=06f3a5233298448e input=a9049054013a1b77]*/ +/*[clinic end generated code: output=aecd61660d1cf31d input=a9049054013a1b77]*/ diff --git a/Modules/expat/pyexpatns.h b/Modules/expat/pyexpatns.h --- a/Modules/expat/pyexpatns.h +++ b/Modules/expat/pyexpatns.h @@ -21,7 +21,7 @@ * * * The Solution: - * Prefix all a exported symbols with "PyExpat_". This is similar to + * Prefix all exported symbols with "PyExpat_". This is similar to * what Mozilla does for some common libs: * http://lxr.mozilla.org/seamonkey/source/modules/libimg/png/mozpngconf.h#115 * diff --git a/Modules/hashlib.h b/Modules/hashlib.h --- a/Modules/hashlib.h +++ b/Modules/hashlib.h @@ -30,7 +30,7 @@ /* * Helper code to synchronize access to the hash object when the GIL is * released around a CPU consuming hashlib operation. All code paths that - * access a mutable part of obj must be enclosed in a ENTER_HASHLIB / + * access a mutable part of obj must be enclosed in an ENTER_HASHLIB / * LEAVE_HASHLIB block or explicitly acquire and release the lock inside * a PY_BEGIN / END_ALLOW_THREADS block if they wish to release the GIL for * an operation. diff --git a/Modules/readline.c b/Modules/readline.c --- a/Modules/readline.c +++ b/Modules/readline.c @@ -1236,7 +1236,7 @@ return NULL; } - /* We got an EOF, return a empty string. */ + /* We got an EOF, return an empty string. */ if (p == NULL) { p = PyMem_RawMalloc(1); if (p != NULL) diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1288,7 +1288,7 @@ if (truncated == NULL || PyLong_Check(truncated)) return truncated; /* __trunc__ is specified to return an Integral type, - but int() needs to return a int. */ + but int() needs to return an int. */ m = truncated->ob_type->tp_as_number; if (m == NULL || m->nb_int == NULL) { PyErr_Format( diff --git a/Objects/exceptions.c b/Objects/exceptions.c --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -874,7 +874,7 @@ static int oserror_use_init(PyTypeObject *type) { - /* When __init__ is defined in a OSError subclass, we want any + /* When __init__ is defined in an OSError subclass, we want any extraneous argument to __new__ to be ignored. The only reasonable solution, given __new__ takes a variable number of arguments, is to defer arg parsing and initialization to __init__. diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -548,7 +548,7 @@ return 0; } if (u->u_ste->ste_needs_class_closure) { - /* Cook up a implicit __class__ cell. */ + /* Cook up an implicit __class__ cell. */ _Py_IDENTIFIER(__class__); PyObject *tuple, *name, *zero; int res; diff --git a/Python/thread.c b/Python/thread.c --- a/Python/thread.c +++ b/Python/thread.c @@ -31,7 +31,7 @@ threads. This is valid for HP-UX 11.23 running on an ia64 system. If needed, add - a check of __ia64 to verify that we're running on a ia64 system instead + a check of __ia64 to verify that we're running on an ia64 system instead of a pa-risc system. */ #ifdef __hpux diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -91,7 +91,7 @@ def safety_limit(val): - # Given a integer value from the process being debugged, limit it to some + # Given an integer value from the process being debugged, limit it to some # safety threshold so that arbitrary breakage within said process doesn't # break the gdb process too much (e.g. sizes of iterations, sizes of lists) return min(val, 1000) @@ -158,7 +158,7 @@ class PyObjectPtr(object): """ - Class wrapping a gdb.Value that's a either a (PyObject*) within the + Class wrapping a gdb.Value that's either a (PyObject*) within the inferior process, or some subclass pointer e.g. (PyBytesObject*) There will be a subclass for every refined PyObject type that we care -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 00:40:00 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 02 Nov 2015 05:40:00 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2324379=3A__Revert_?= =?utf-8?q?the_operator=2Esubscript_patch_=28dccc4e63aef5=29_pending?= Message-ID: <20151102054000.74099.33449@psf.io> https://hg.python.org/cpython/rev/83fa2e9b0038 changeset: 98934:83fa2e9b0038 user: Raymond Hettinger date: Mon Nov 02 00:39:56 2015 -0500 summary: Issue #24379: Revert the operator.subscript patch (dccc4e63aef5) pending resolution of the related refcnt leak. files: Doc/library/operator.rst | 15 ------------ Doc/whatsnew/3.6.rst | 8 ------ Lib/operator.py | 28 +---------------------- Lib/test/test_operator.py | 33 --------------------------- 4 files changed, 1 insertions(+), 83 deletions(-) diff --git a/Doc/library/operator.rst b/Doc/library/operator.rst --- a/Doc/library/operator.rst +++ b/Doc/library/operator.rst @@ -333,21 +333,6 @@ [('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)] -.. data:: subscript - - A helper to turn subscript notation into indexing objects. This can be - used to create item access patterns ahead of time to pass them into - various subscriptable objects. - - For example: - - * ``subscript[5] == 5`` - * ``subscript[3:7:2] == slice(3, 7, 2)`` - * ``subscript[5, 8] == (5, 8)`` - - .. versionadded:: 3.6 - - .. function:: methodcaller(name[, args...]) Return a callable object that calls the method *name* on its operand. If diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -104,14 +104,6 @@ (Contributed by Ashley Anderson in :issue:`12006`.) -operator --------- - -New object :data:`operator.subscript` makes it easier to create complex -indexers. For example: ``subscript[0:10:2] == slice(0, 10, 2)`` -(Contributed by Joe Jevnik in :issue:`24379`.) - - pickle ------ diff --git a/Lib/operator.py b/Lib/operator.py --- a/Lib/operator.py +++ b/Lib/operator.py @@ -17,7 +17,7 @@ 'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', 'length_hint', 'lshift', 'lt', 'matmul', 'methodcaller', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', - 'setitem', 'sub', 'subscript', 'truediv', 'truth', 'xor'] + 'setitem', 'sub', 'truediv', 'truth', 'xor'] from builtins import abs as _abs @@ -408,32 +408,6 @@ return a - at object.__new__ # create a singleton instance -class subscript: - """ - A helper to turn subscript notation into indexing objects. This can be - used to create item access patterns ahead of time to pass them into - various subscriptable objects. - - For example: - subscript[5] == 5 - subscript[3:7:2] == slice(3, 7, 2) - subscript[5, 8] == (5, 8) - """ - __slots__ = () - - def __new__(cls): - raise TypeError("cannot create '{}' instances".format(cls.__name__)) - - @staticmethod - def __getitem__(key): - return key - - @staticmethod - def __reduce__(): - return 'subscript' - - try: from _operator import * except ImportError: diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py --- a/Lib/test/test_operator.py +++ b/Lib/test/test_operator.py @@ -596,38 +596,5 @@ module2 = c_operator -class SubscriptTestCase: - def test_subscript(self): - subscript = self.module.subscript - self.assertIsNone(subscript[None]) - self.assertEqual(subscript[0], 0) - self.assertEqual(subscript[0:1:2], slice(0, 1, 2)) - self.assertEqual( - subscript[0, ..., :2, ...], - (0, Ellipsis, slice(2), Ellipsis), - ) - - def test_pickle(self): - from operator import subscript - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - self.assertIs( - pickle.loads(pickle.dumps(subscript, proto)), - subscript, - ) - - def test_singleton(self): - with self.assertRaises(TypeError): - type(self.module.subscript)() - - def test_immutable(self): - with self.assertRaises(AttributeError): - self.module.subscript.attr = None - - -class PySubscriptTestCase(SubscriptTestCase, PyOperatorTestCase): - pass - - if __name__ == "__main__": unittest.main() -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Mon Nov 2 03:42:25 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 02 Nov 2015 08:42:25 +0000 Subject: [Python-checkins] Daily reference leaks (83fa2e9b0038): sum=7 Message-ID: <20151102084225.80202.96531@psf.io> results for 83fa2e9b0038 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogtO7O39', '--timeout', '7200'] From python-checkins at python.org Mon Nov 2 07:27:49 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 02 Nov 2015 12:27:49 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Minor_cleanup=2E?= Message-ID: <20151102122745.8593.88360@psf.io> https://hg.python.org/cpython/rev/ef4b50e333a5 changeset: 98935:ef4b50e333a5 user: Raymond Hettinger date: Mon Nov 02 07:27:40 2015 -0500 summary: Minor cleanup. files: Modules/_collectionsmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1060,7 +1060,7 @@ cmp = PyObject_RichCompareBool(item, v, Py_EQ); if (cmp > 0) return PyLong_FromSsize_t(stop - (n + 1)); - else if (cmp < 0) + if (cmp < 0) return NULL; if (start_state != deque->state) { PyErr_SetString(PyExc_RuntimeError, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 08:07:07 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 02 Nov 2015 13:07:07 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325523=3A_Merge_a-to-an_corrections_from_3=2E4=2E?= Message-ID: <20151102130707.21937.12221@psf.io> https://hg.python.org/cpython/rev/68edc7baeef7 changeset: 98937:68edc7baeef7 branch: 3.5 parent: 98930:2347271172b3 parent: 98936:75df8b0a2cd1 user: Serhiy Storchaka date: Mon Nov 02 14:39:05 2015 +0200 summary: Issue #25523: Merge a-to-an corrections from 3.4. files: Doc/distutils/packageindex.rst | 2 +- Doc/howto/descriptor.rst | 2 +- Doc/install/index.rst | 2 +- Doc/library/asyncio-protocol.rst | 2 +- Doc/library/contextlib.rst | 2 +- Doc/library/email.parser.rst | 4 ++-- Doc/library/gzip.rst | 2 +- Doc/library/pickle.rst | 4 ++-- Doc/library/socket.rst | 4 ++-- Doc/library/tokenize.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/library/xml.dom.minidom.rst | 2 +- Doc/library/zlib.rst | 2 +- Doc/whatsnew/2.7.rst | 2 +- Doc/whatsnew/3.3.rst | 2 +- Include/unicodeobject.h | 4 ++-- Lib/asyncio/sslproto.py | 2 +- Lib/asyncio/transports.py | 2 +- Lib/ctypes/test/test_random_things.py | 2 +- Lib/http/cookiejar.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/msilib/schema.py | 2 +- Lib/test/regrtest.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_io.py | 2 +- Lib/test/test_socket.py | 2 +- Lib/test/test_userdict.py | 2 +- Lib/tkinter/__init__.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 2 +- Modules/_ssl.c | 2 +- Modules/itertoolsmodule.c | 2 +- Objects/unicodeobject.c | 4 ++-- 34 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -167,7 +167,7 @@ username: password: -The *distutils* section defines a *index-servers* variable that lists the +The *distutils* section defines an *index-servers* variable that lists the name of all sections describing a repository. Each section describing a repository defines three variables: diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -319,7 +319,7 @@ patterns of binding functions into methods. To recap, functions have a :meth:`__get__` method so that they can be converted -to a method when accessed as attributes. The non-data descriptor transforms a +to a method when accessed as attributes. The non-data descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)`` becomes ``f(*args)``. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -148,7 +148,7 @@ On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a +:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a graphical user interface (such as WinZip) or a command-line tool (such as :program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a command prompt window and run:: diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -148,7 +148,7 @@ high-water limit. Neither *high* nor *low* can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting *high* to zero forces *low* to zero as well, and causes :meth:`pause_writing` to be called whenever the diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -142,7 +142,7 @@ is hardwired to stdout. For example, the output of :func:`help` normally is sent to *sys.stdout*. - You can capture that output in a string by redirecting the output to a + You can capture that output in a string by redirecting the output to an :class:`io.StringIO` object:: f = io.StringIO() diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -146,7 +146,7 @@ methods on file-like objects. The text contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). @@ -189,7 +189,7 @@ methods on file-like objects. The bytes contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts, including subparts diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -64,7 +64,7 @@ method. At least one of *fileobj* and *filename* must be given a non-trivial value. - The new class instance is based on *fileobj*, which can be a regular file, a + The new class instance is based on *fileobj*, which can be a regular file, an :class:`io.BytesIO` object, or any other object which simulates a file. It defaults to ``None``, in which case *filename* is opened to provide a file object. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -192,7 +192,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. @@ -288,7 +288,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -786,7 +786,7 @@ .. function:: sethostname(name) - Set the machine's hostname to *name*. This will raise a + Set the machine's hostname to *name*. This will raise an :exc:`OSError` if you don't have enough rights. Availability: Unix. @@ -818,7 +818,7 @@ .. function:: if_indextoname(if_index) - Return a network interface name corresponding to a + Return a network interface name corresponding to an interface index number. :exc:`OSError` if no interface with the given index exists. diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -41,7 +41,7 @@ returned as a :term:`named tuple` with the field names: ``type string start end line``. - The returned :term:`named tuple` has a additional property named + The returned :term:`named tuple` has an additional property named ``exact_type`` that contains the exact operator type for :data:`token.OP` tokens. For all other token types ``exact_type`` equals the named tuple ``type`` field. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -471,7 +471,7 @@ .. versionadded:: 3.1 Unittest supports skipping individual test methods and even whole classes of -tests. In addition, it supports marking a test as a "expected failure," a test +tests. In addition, it supports marking a test as an "expected failure," a test that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1383,7 +1383,7 @@ .. method:: retrieve(url, filename=None, reporthook=None, data=None) Retrieves the contents of *url* and places it in *filename*. The return value - is a tuple consisting of a local filename and either a + is a tuple consisting of a local filename and either an :class:`email.message.Message` object containing the response headers (for remote URLs) or ``None`` (for local URLs). The caller must then open and read the contents of *filename*. If *filename* is not given and the URL refers to a diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -54,7 +54,7 @@ .. function:: parseString(string, parser=None) - Return a :class:`Document` that represents the *string*. This method creates a + Return a :class:`Document` that represents the *string*. This method creates an :class:`io.StringIO` object for the string and passes that on to :func:`parse`. Both functions return a :class:`Document` object representing the content of the diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -30,7 +30,7 @@ .. function:: adler32(data[, value]) - Computes a Adler-32 checksum of *data*. (An Adler-32 checksum is almost as + Computes an Adler-32 checksum of *data*. (An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much more quickly.) If *value* is present, it is used as the starting value of the checksum; otherwise, a fixed default value is used. This allows computing a running checksum over the diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1118,7 +1118,7 @@ (Fixed by Daniel Stutzbach; :issue:`8729`.) * Constructors for the parsing classes in the :mod:`ConfigParser` module now - take a *allow_no_value* parameter, defaulting to false; if true, + take an *allow_no_value* parameter, defaulting to false; if true, options without values will be allowed. For example:: >>> import ConfigParser, StringIO diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -2155,7 +2155,7 @@ * encode an ASCII string to UTF-8 doesn't need to encode characters anymore, the UTF-8 representation is shared with the ASCII representation * the UTF-8 encoder has been optimized - * repeating a single ASCII letter and getting a substring of a ASCII strings + * repeating a single ASCII letter and getting a substring of an ASCII string is 4 times faster * UTF-8 is now 2x to 4x faster. UTF-16 encoding is now up to 10x faster. diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -965,7 +965,7 @@ Py_ssize_t end ); -/* Append a ASCII-encoded byte string. +/* Append an ASCII-encoded byte string. Return 0 on success, raise an exception and return -1 on error. */ PyAPI_FUNC(int) _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, @@ -2041,7 +2041,7 @@ int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ ); -/* Apply a argument tuple or dictionary to a format string and return +/* Apply an argument tuple or dictionary to a format string and return the resulting Unicode string. */ PyAPI_FUNC(PyObject *) PyUnicode_Format( diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -349,7 +349,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -62,7 +62,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -30,7 +30,7 @@ # value is printed correctly. # # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is + # error message - instead an additional frame for the C code is # created, then a full traceback printed. When SystemExit is # raised in a callback function, the interpreter exits. diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1437,7 +1437,7 @@ break # convert RFC 2965 Max-Age to seconds since epoch # XXX Strictly you're supposed to follow RFC 2616 - # age-calculation rules. Remember that zero Max-Age is a + # age-calculation rules. Remember that zero Max-Age # is a request to discard (old and new) cookie, though. k = "expires" v = self._now + v diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -114,7 +114,7 @@ left_node = expr_node.children[0] if isinstance(left_node, Leaf) and \ left_node.value == '__metaclass__': - # We found a assignment to __metaclass__. + # We found an assignment to __metaclass__. fixup_simple_stmt(node, i, simple_node) remove_trailing_newline(simple_node) yield (node, i, simple_node) diff --git a/Lib/msilib/schema.py b/Lib/msilib/schema.py --- a/Lib/msilib/schema.py +++ b/Lib/msilib/schema.py @@ -733,7 +733,7 @@ ('CustomAction','Source','Y',None, None, None, None, 'CustomSource',None, 'The table reference of the source of the code.',), ('CustomAction','Target','Y',None, None, None, None, 'Formatted',None, 'Excecution parameter, depends on the type of custom action',), ('DrLocator','Signature_','N',None, None, None, None, 'Identifier',None, 'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), +('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), ('DrLocator','Depth','Y',0,32767,None, None, None, None, 'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',), ('DrLocator','Parent','Y',None, None, None, None, 'Identifier',None, 'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',), ('DuplicateFile','File_','N',None, None, 'File',1,'Identifier',None, 'Foreign key referencing the source file to be duplicated.',), diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -27,7 +27,7 @@ EPILOG = """\ Additional option details: --r randomizes test execution order. You can use --randseed=int to provide a +-r randomizes test execution order. You can use --randseed=int to provide an int seed value for the randomizer; this is useful for reproducing troublesome test orders. diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -603,7 +603,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(dict): def __missing__(self, key): return 42 diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -15,7 +15,7 @@ ################################################################################ # When writing tests for io, it's important to test both the C and Python # implementations. This is usually done by writing a base test that refers to -# the type it is testing as a attribute. Then it provides custom subclasses to +# the type it is testing as an attribute. Then it provides custom subclasses to # test both implementations. This file has lots of examples. ################################################################################ diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4549,7 +4549,7 @@ except OSError as e: if str(e) == "AF_UNIX path too long": self.skipTest( - "Pathname {0!a} is too long to serve as a AF_UNIX path" + "Pathname {0!a} is too long to serve as an AF_UNIX path" .format(path)) else: raise diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -171,7 +171,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(collections.UserDict): def __missing__(self, key): return 42 diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1123,7 +1123,7 @@ return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -12412,7 +12412,7 @@ - Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly. -- Patch #1212117: os.stat().st_flags is now accessible as a attribute +- Patch #1212117: os.stat().st_flags is now accessible as an attribute if available on the platform. - Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -3072,7 +3072,7 @@ Changes are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an editor window with a filename. When Class Browser is requested otherwise, from a shell, output window, or 'Untitled' editor, Idle no longer displays an error box. It now pops up an Open Module box (Alt+M). If a valid name diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2996,7 +2996,7 @@ cadata_ascii = PyUnicode_AsASCIIString(cadata); if (cadata_ascii == NULL) { PyErr_SetString(PyExc_TypeError, - "cadata should be a ASCII string or a " + "cadata should be an ASCII string or a " "bytes-like object"); goto error; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1725,7 +1725,7 @@ "starmap(function, sequence) --> starmap object\n\ \n\ Return an iterator whose values are returned from the function evaluated\n\ -with a argument tuple taken from the given sequence."); +with an argument tuple taken from the given sequence."); static PyTypeObject starmap_type = { PyVarObject_HEAD_INIT(NULL, 0) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1701,7 +1701,7 @@ return unicode_resize(p_unicode, length); } -/* Copy a ASCII or latin1 char* string into a Python Unicode string. +/* Copy an ASCII or latin1 char* string into a Python Unicode string. WARNING: The function doesn't copy the terminating null character and doesn't check the maximum character (may write a latin1 character in an @@ -7191,7 +7191,7 @@ } /* - * Encode a Unicode string to a Windows code page into a byte string using a + * Encode a Unicode string to a Windows code page into a byte string using an * error handler. * * Returns consumed characters if succeed, or raise an OSError and returns -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 08:07:08 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 02 Nov 2015 13:07:08 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325523=3A_Merge_a-to-an_corrections_from_3=2E5?= =?utf-8?q?=2E?= Message-ID: <20151102130708.21941.85317@psf.io> https://hg.python.org/cpython/rev/72cca30f4707 changeset: 98939:72cca30f4707 parent: 98935:ef4b50e333a5 parent: 98938:a0d0f968b020 user: Serhiy Storchaka date: Mon Nov 02 14:44:29 2015 +0200 summary: Issue #25523: Merge a-to-an corrections from 3.5. files: Doc/distutils/packageindex.rst | 2 +- Doc/howto/descriptor.rst | 2 +- Doc/install/index.rst | 2 +- Doc/library/asyncio-protocol.rst | 2 +- Doc/library/contextlib.rst | 2 +- Doc/library/email.parser.rst | 4 ++-- Doc/library/glob.rst | 2 +- Doc/library/gzip.rst | 2 +- Doc/library/pickle.rst | 4 ++-- Doc/library/socket.rst | 4 ++-- Doc/library/tokenize.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/library/xml.dom.minidom.rst | 2 +- Doc/library/zlib.rst | 2 +- Doc/whatsnew/2.7.rst | 2 +- Doc/whatsnew/3.3.rst | 2 +- Include/unicodeobject.h | 4 ++-- Lib/asyncio/sslproto.py | 2 +- Lib/asyncio/transports.py | 2 +- Lib/ctypes/test/test_random_things.py | 2 +- Lib/http/cookiejar.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/msilib/schema.py | 2 +- Lib/test/libregrtest/cmdline.py | 2 +- Lib/test/test_asdl_parser.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_io.py | 2 +- Lib/test/test_socket.py | 2 +- Lib/test/test_userdict.py | 2 +- Lib/tkinter/__init__.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 4 ++-- Modules/_ssl.c | 4 ++-- Modules/itertoolsmodule.c | 2 +- Objects/unicodeobject.c | 4 ++-- 36 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -167,7 +167,7 @@ username: password: -The *distutils* section defines a *index-servers* variable that lists the +The *distutils* section defines an *index-servers* variable that lists the name of all sections describing a repository. Each section describing a repository defines three variables: diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -319,7 +319,7 @@ patterns of binding functions into methods. To recap, functions have a :meth:`__get__` method so that they can be converted -to a method when accessed as attributes. The non-data descriptor transforms a +to a method when accessed as attributes. The non-data descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)`` becomes ``f(*args)``. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -148,7 +148,7 @@ On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a +:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a graphical user interface (such as WinZip) or a command-line tool (such as :program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a command prompt window and run:: diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -148,7 +148,7 @@ high-water limit. Neither *high* nor *low* can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting *high* to zero forces *low* to zero as well, and causes :meth:`pause_writing` to be called whenever the diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -142,7 +142,7 @@ is hardwired to stdout. For example, the output of :func:`help` normally is sent to *sys.stdout*. - You can capture that output in a string by redirecting the output to a + You can capture that output in a string by redirecting the output to an :class:`io.StringIO` object:: f = io.StringIO() diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -146,7 +146,7 @@ methods on file-like objects. The text contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). @@ -189,7 +189,7 @@ methods on file-like objects. The bytes contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts, including subparts diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -38,7 +38,7 @@ symlinks are included in the results (as in the shell). If *recursive* is true, the pattern "``**``" will match any files and zero or - more directories and subdirectories. If the pattern is followed by a + more directories and subdirectories. If the pattern is followed by an ``os.sep``, only directories and subdirectories match. .. note:: diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -64,7 +64,7 @@ method. At least one of *fileobj* and *filename* must be given a non-trivial value. - The new class instance is based on *fileobj*, which can be a regular file, a + The new class instance is based on *fileobj*, which can be a regular file, an :class:`io.BytesIO` object, or any other object which simulates a file. It defaults to ``None``, in which case *filename* is opened to provide a file object. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -192,7 +192,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. @@ -288,7 +288,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -786,7 +786,7 @@ .. function:: sethostname(name) - Set the machine's hostname to *name*. This will raise a + Set the machine's hostname to *name*. This will raise an :exc:`OSError` if you don't have enough rights. Availability: Unix. @@ -818,7 +818,7 @@ .. function:: if_indextoname(if_index) - Return a network interface name corresponding to a + Return a network interface name corresponding to an interface index number. :exc:`OSError` if no interface with the given index exists. diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -41,7 +41,7 @@ returned as a :term:`named tuple` with the field names: ``type string start end line``. - The returned :term:`named tuple` has a additional property named + The returned :term:`named tuple` has an additional property named ``exact_type`` that contains the exact operator type for :data:`token.OP` tokens. For all other token types ``exact_type`` equals the named tuple ``type`` field. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -471,7 +471,7 @@ .. versionadded:: 3.1 Unittest supports skipping individual test methods and even whole classes of -tests. In addition, it supports marking a test as a "expected failure," a test +tests. In addition, it supports marking a test as an "expected failure," a test that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1383,7 +1383,7 @@ .. method:: retrieve(url, filename=None, reporthook=None, data=None) Retrieves the contents of *url* and places it in *filename*. The return value - is a tuple consisting of a local filename and either a + is a tuple consisting of a local filename and either an :class:`email.message.Message` object containing the response headers (for remote URLs) or ``None`` (for local URLs). The caller must then open and read the contents of *filename*. If *filename* is not given and the URL refers to a diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -54,7 +54,7 @@ .. function:: parseString(string, parser=None) - Return a :class:`Document` that represents the *string*. This method creates a + Return a :class:`Document` that represents the *string*. This method creates an :class:`io.StringIO` object for the string and passes that on to :func:`parse`. Both functions return a :class:`Document` object representing the content of the diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -30,7 +30,7 @@ .. function:: adler32(data[, value]) - Computes a Adler-32 checksum of *data*. (An Adler-32 checksum is almost as + Computes an Adler-32 checksum of *data*. (An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much more quickly.) If *value* is present, it is used as the starting value of the checksum; otherwise, a fixed default value is used. This allows computing a running checksum over the diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1118,7 +1118,7 @@ (Fixed by Daniel Stutzbach; :issue:`8729`.) * Constructors for the parsing classes in the :mod:`ConfigParser` module now - take a *allow_no_value* parameter, defaulting to false; if true, + take an *allow_no_value* parameter, defaulting to false; if true, options without values will be allowed. For example:: >>> import ConfigParser, StringIO diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -2155,7 +2155,7 @@ * encode an ASCII string to UTF-8 doesn't need to encode characters anymore, the UTF-8 representation is shared with the ASCII representation * the UTF-8 encoder has been optimized - * repeating a single ASCII letter and getting a substring of a ASCII strings + * repeating a single ASCII letter and getting a substring of an ASCII string is 4 times faster * UTF-8 is now 2x to 4x faster. UTF-16 encoding is now up to 10x faster. diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -982,7 +982,7 @@ Py_ssize_t end ); -/* Append a ASCII-encoded byte string. +/* Append an ASCII-encoded byte string. Return 0 on success, raise an exception and return -1 on error. */ PyAPI_FUNC(int) _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, @@ -2058,7 +2058,7 @@ int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ ); -/* Apply a argument tuple or dictionary to a format string and return +/* Apply an argument tuple or dictionary to a format string and return the resulting Unicode string. */ PyAPI_FUNC(PyObject *) PyUnicode_Format( diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -349,7 +349,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -62,7 +62,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -30,7 +30,7 @@ # value is printed correctly. # # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is + # error message - instead an additional frame for the C code is # created, then a full traceback printed. When SystemExit is # raised in a callback function, the interpreter exits. diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1437,7 +1437,7 @@ break # convert RFC 2965 Max-Age to seconds since epoch # XXX Strictly you're supposed to follow RFC 2616 - # age-calculation rules. Remember that zero Max-Age is a + # age-calculation rules. Remember that zero Max-Age # is a request to discard (old and new) cookie, though. k = "expires" v = self._now + v diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -114,7 +114,7 @@ left_node = expr_node.children[0] if isinstance(left_node, Leaf) and \ left_node.value == '__metaclass__': - # We found a assignment to __metaclass__. + # We found an assignment to __metaclass__. fixup_simple_stmt(node, i, simple_node) remove_trailing_newline(simple_node) yield (node, i, simple_node) diff --git a/Lib/msilib/schema.py b/Lib/msilib/schema.py --- a/Lib/msilib/schema.py +++ b/Lib/msilib/schema.py @@ -733,7 +733,7 @@ ('CustomAction','Source','Y',None, None, None, None, 'CustomSource',None, 'The table reference of the source of the code.',), ('CustomAction','Target','Y',None, None, None, None, 'Formatted',None, 'Excecution parameter, depends on the type of custom action',), ('DrLocator','Signature_','N',None, None, None, None, 'Identifier',None, 'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), +('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), ('DrLocator','Depth','Y',0,32767,None, None, None, None, 'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',), ('DrLocator','Parent','Y',None, None, None, None, 'Identifier',None, 'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',), ('DuplicateFile','File_','N',None, None, 'File',1,'Identifier',None, 'Foreign key referencing the source file to be duplicated.',), diff --git a/Lib/test/libregrtest/cmdline.py b/Lib/test/libregrtest/cmdline.py --- a/Lib/test/libregrtest/cmdline.py +++ b/Lib/test/libregrtest/cmdline.py @@ -25,7 +25,7 @@ EPILOG = """\ Additional option details: --r randomizes test execution order. You can use --randseed=int to provide a +-r randomizes test execution order. You can use --randseed=int to provide an int seed value for the randomizer; this is useful for reproducing troublesome test orders. diff --git a/Lib/test/test_asdl_parser.py b/Lib/test/test_asdl_parser.py --- a/Lib/test/test_asdl_parser.py +++ b/Lib/test/test_asdl_parser.py @@ -21,7 +21,7 @@ def setUpClass(cls): # Loads the asdl module dynamically, since it's not in a real importable # package. - # Parses Python.asdl into a ast.Module and run the check on it. + # Parses Python.asdl into an ast.Module and run the check on it. # There's no need to do this for each test method, hence setUpClass. sys.path.insert(0, parser_dir) loader = importlib.machinery.SourceFileLoader( diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -603,7 +603,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(dict): def __missing__(self, key): return 42 diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -15,7 +15,7 @@ ################################################################################ # When writing tests for io, it's important to test both the C and Python # implementations. This is usually done by writing a base test that refers to -# the type it is testing as a attribute. Then it provides custom subclasses to +# the type it is testing as an attribute. Then it provides custom subclasses to # test both implementations. This file has lots of examples. ################################################################################ diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4549,7 +4549,7 @@ except OSError as e: if str(e) == "AF_UNIX path too long": self.skipTest( - "Pathname {0!a} is too long to serve as a AF_UNIX path" + "Pathname {0!a} is too long to serve as an AF_UNIX path" .format(path)) else: raise diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -171,7 +171,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(collections.UserDict): def __missing__(self, key): return 42 diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1123,7 +1123,7 @@ return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -12412,7 +12412,7 @@ - Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly. -- Patch #1212117: os.stat().st_flags is now accessible as a attribute +- Patch #1212117: os.stat().st_flags is now accessible as an attribute if available on the platform. - Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2651,7 +2651,7 @@ - Issue #20170: Convert posixmodule to use Argument Clinic. -- Issue #21539: Add a *exists_ok* argument to `Pathlib.mkdir()` to mimic +- Issue #21539: Add an *exists_ok* argument to `Pathlib.mkdir()` to mimic `mkdir -p` and `os.makedirs()` functionality. When true, ignore FileExistsErrors. Patch by Berker Peksag. @@ -3240,7 +3240,7 @@ Changes are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an editor window with a filename. When Class Browser is requested otherwise, from a shell, output window, or 'Untitled' editor, Idle no longer displays an error box. It now pops up an Open Module box (Alt+M). If a valid name diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2996,7 +2996,7 @@ cadata_ascii = PyUnicode_AsASCIIString(cadata); if (cadata_ascii == NULL) { PyErr_SetString(PyExc_TypeError, - "cadata should be a ASCII string or a " + "cadata should be an ASCII string or a " "bytes-like object"); goto error; } @@ -3273,7 +3273,7 @@ ssl = SSL_get_app_data(s); assert(PySSLSocket_Check(ssl)); - /* The servername callback expects a argument that represents the current + /* The servername callback expects an argument that represents the current * SSL connection and that has a .context attribute that can be changed to * identify the requested hostname. Since the official API is the Python * level API we want to pass the callback a Python level object rather than diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1743,7 +1743,7 @@ "starmap(function, sequence) --> starmap object\n\ \n\ Return an iterator whose values are returned from the function evaluated\n\ -with a argument tuple taken from the given sequence."); +with an argument tuple taken from the given sequence."); static PyTypeObject starmap_type = { PyVarObject_HEAD_INIT(NULL, 0) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1865,7 +1865,7 @@ return unicode_resize(p_unicode, length); } -/* Copy a ASCII or latin1 char* string into a Python Unicode string. +/* Copy an ASCII or latin1 char* string into a Python Unicode string. WARNING: The function doesn't copy the terminating null character and doesn't check the maximum character (may write a latin1 character in an @@ -7411,7 +7411,7 @@ } /* - * Encode a Unicode string to a Windows code page into a byte string using a + * Encode a Unicode string to a Windows code page into a byte string using an * error handler. * * Returns consumed characters if succeed, or raise an OSError and returns -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 08:07:11 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 02 Nov 2015 13:07:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTIz?= =?utf-8?q?=3A_Further_a-to-an_corrections_new_in_3=2E5=2E?= Message-ID: <20151102130707.100258.62808@psf.io> https://hg.python.org/cpython/rev/a0d0f968b020 changeset: 98938:a0d0f968b020 branch: 3.5 user: Serhiy Storchaka date: Mon Nov 02 14:40:41 2015 +0200 summary: Issue #25523: Further a-to-an corrections new in 3.5. files: Doc/library/glob.rst | 2 +- Lib/test/test_asdl_parser.py | 2 +- Misc/NEWS | 2 +- Modules/_ssl.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -38,7 +38,7 @@ symlinks are included in the results (as in the shell). If *recursive* is true, the pattern "``**``" will match any files and zero or - more directories and subdirectories. If the pattern is followed by a + more directories and subdirectories. If the pattern is followed by an ``os.sep``, only directories and subdirectories match. .. note:: diff --git a/Lib/test/test_asdl_parser.py b/Lib/test/test_asdl_parser.py --- a/Lib/test/test_asdl_parser.py +++ b/Lib/test/test_asdl_parser.py @@ -21,7 +21,7 @@ def setUpClass(cls): # Loads the asdl module dynamically, since it's not in a real importable # package. - # Parses Python.asdl into a ast.Module and run the check on it. + # Parses Python.asdl into an ast.Module and run the check on it. # There's no need to do this for each test method, hence setUpClass. sys.path.insert(0, parser_dir) loader = importlib.machinery.SourceFileLoader( diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2483,7 +2483,7 @@ - Issue #20170: Convert posixmodule to use Argument Clinic. -- Issue #21539: Add a *exists_ok* argument to `Pathlib.mkdir()` to mimic +- Issue #21539: Add an *exists_ok* argument to `Pathlib.mkdir()` to mimic `mkdir -p` and `os.makedirs()` functionality. When true, ignore FileExistsErrors. Patch by Berker Peksag. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3273,7 +3273,7 @@ ssl = SSL_get_app_data(s); assert(PySSLSocket_Check(ssl)); - /* The servername callback expects a argument that represents the current + /* The servername callback expects an argument that represents the current * SSL connection and that has a .context attribute that can be changed to * identify the requested hostname. Since the official API is the Python * level API we want to pass the callback a Python level object rather than -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 08:07:11 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 02 Nov 2015 13:07:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NTIz?= =?utf-8?q?=3A_Backported_a-to-an_corrections=2E?= Message-ID: <20151102130708.100256.60332@psf.io> https://hg.python.org/cpython/rev/e8f3c011e2b4 changeset: 98940:e8f3c011e2b4 branch: 2.7 parent: 98905:4ed175ee3cca user: Serhiy Storchaka date: Mon Nov 02 15:06:09 2015 +0200 summary: Issue #25523: Backported a-to-an corrections. files: Doc/distutils/packageindex.rst | 2 +- Doc/howto/descriptor.rst | 2 +- Doc/install/index.rst | 2 +- Doc/library/email.parser.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/zlib.rst | 2 +- Doc/whatsnew/2.7.rst | 2 +- Include/unicodeobject.h | 2 +- Lib/cookielib.py | 2 +- Lib/ctypes/test/test_random_things.py | 2 +- Lib/lib-tk/Tkinter.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/test/regrtest.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_io.py | 2 +- Lib/test/test_userdict.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 2 +- Modules/_ssl.c | 2 +- Modules/itertoolsmodule.c | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -169,7 +169,7 @@ username: password: -The *distutils* section defines a *index-servers* variable that lists the +The *distutils* section defines an *index-servers* variable that lists the name of all sections describing a repository. Each section describing a repository defines three variables: diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -325,7 +325,7 @@ patterns of binding functions into methods. To recap, functions have a :meth:`__get__` method so that they can be converted -to a method when accessed as attributes. The non-data descriptor transforms a +to a method when accessed as attributes. The non-data descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)`` becomes ``f(*args)``. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -149,7 +149,7 @@ On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a +:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a graphical user interface (such as WinZip) or a command-line tool (such as :program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a command prompt window and run:: diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -133,7 +133,7 @@ methods on file-like objects. The text contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -568,7 +568,7 @@ .. versionadded:: 2.7 Unittest supports skipping individual test methods and even whole classes of -tests. In addition, it supports marking a test as a "expected failure," a test +tests. In addition, it supports marking a test as an "expected failure," a test that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -31,7 +31,7 @@ .. function:: adler32(data[, value]) - Computes a Adler-32 checksum of *data*. (An Adler-32 checksum is almost as + Computes an Adler-32 checksum of *data*. (An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much more quickly.) If *value* is present, it is used as the starting value of the checksum; otherwise, a fixed default value is used. This allows computing a running checksum over the diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1118,7 +1118,7 @@ (Fixed by Daniel Stutzbach; :issue:`8729`.) * Constructors for the parsing classes in the :mod:`ConfigParser` module now - take a *allow_no_value* parameter, defaulting to false; if true, + take an *allow_no_value* parameter, defaulting to false; if true, options without values will be allowed. For example:: >>> import ConfigParser, StringIO diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1307,7 +1307,7 @@ int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ ); -/* Apply a argument tuple or dictionary to a format string and return +/* Apply an argument tuple or dictionary to a format string and return the resulting Unicode string. */ PyAPI_FUNC(PyObject *) PyUnicode_Format( diff --git a/Lib/cookielib.py b/Lib/cookielib.py --- a/Lib/cookielib.py +++ b/Lib/cookielib.py @@ -1434,7 +1434,7 @@ break # convert RFC 2965 Max-Age to seconds since epoch # XXX Strictly you're supposed to follow RFC 2616 - # age-calculation rules. Remember that zero Max-Age is a + # age-calculation rules. Remember that zero Max-Age # is a request to discard (old and new) cookie, though. k = "expires" v = self._now + v diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -30,7 +30,7 @@ # value is printed correctly. # # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is + # error message - instead an additional frame for the C code is # created, then a full traceback printed. When SystemExit is # raised in a callback function, the interpreter exits. diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py --- a/Lib/lib-tk/Tkinter.py +++ b/Lib/lib-tk/Tkinter.py @@ -1117,7 +1117,7 @@ return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -114,7 +114,7 @@ left_node = expr_node.children[0] if isinstance(left_node, Leaf) and \ left_node.value == u'__metaclass__': - # We found a assignment to __metaclass__. + # We found an assignment to __metaclass__. fixup_simple_stmt(node, i, simple_node) remove_trailing_newline(simple_node) yield (node, i, simple_node) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -62,7 +62,7 @@ Additional Option Details: --r randomizes test execution order. You can use --randseed=int to provide a +-r randomizes test execution order. You can use --randseed=int to provide an int seed value for the randomizer; this is useful for reproducing troublesome test orders. diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -448,7 +448,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(dict): def __missing__(self, key): return 42 diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -15,7 +15,7 @@ ################################################################################ # When writing tests for io, it's important to test both the C and Python # implementations. This is usually done by writing a base test that refers to -# the type it is testing as a attribute. Then it provides custom subclasses to +# the type it is testing as an attribute. Then it provides custom subclasses to # test both implementations. This file has lots of examples. ################################################################################ diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -188,7 +188,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(UserDict.UserDict): def __missing__(self, key): return 42 diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1495,7 +1495,7 @@ - Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly. -- Patch #1212117: os.stat().st_flags is now accessible as a attribute +- Patch #1212117: os.stat().st_flags is now accessible as an attribute if available on the platform. - Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -936,7 +936,7 @@ Changes are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an editor window with a filename. When Class Browser is requested otherwise, from a shell, output window, or 'Untitled' editor, Idle no longer displays an error box. It now pops up an Open Module box (Alt+M). If a valid name diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2788,7 +2788,7 @@ cadata_ascii = PyUnicode_AsASCIIString(cadata); if (cadata_ascii == NULL) { PyErr_SetString(PyExc_TypeError, - "cadata should be a ASCII string or a " + "cadata should be an ASCII string or a " "bytes-like object"); goto error; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1410,7 +1410,7 @@ "starmap(function, sequence) --> starmap object\n\ \n\ Return an iterator whose values are returned from the function evaluated\n\ -with a argument tuple taken from the given sequence."); +with an argument tuple taken from the given sequence."); static PyTypeObject starmap_type = { PyVarObject_HEAD_INIT(NULL, 0) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 08:07:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 02 Nov 2015 13:07:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTIz?= =?utf-8?q?=3A_Further_a-to-an_corrections=2E?= Message-ID: <20151102130707.100258.62607@psf.io> https://hg.python.org/cpython/rev/75df8b0a2cd1 changeset: 98936:75df8b0a2cd1 branch: 3.4 parent: 98928:d8ff13414deb user: Serhiy Storchaka date: Mon Nov 02 14:10:23 2015 +0200 summary: Issue #25523: Further a-to-an corrections. files: Doc/distutils/packageindex.rst | 2 +- Doc/howto/descriptor.rst | 2 +- Doc/install/index.rst | 2 +- Doc/library/asyncio-protocol.rst | 2 +- Doc/library/contextlib.rst | 2 +- Doc/library/email.parser.rst | 4 ++-- Doc/library/gzip.rst | 2 +- Doc/library/pickle.rst | 4 ++-- Doc/library/socket.rst | 4 ++-- Doc/library/tokenize.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/library/xml.dom.minidom.rst | 2 +- Doc/library/zlib.rst | 2 +- Doc/whatsnew/2.7.rst | 2 +- Doc/whatsnew/3.3.rst | 2 +- Include/unicodeobject.h | 4 ++-- Lib/asyncio/sslproto.py | 2 +- Lib/asyncio/transports.py | 2 +- Lib/ctypes/test/test_random_things.py | 2 +- Lib/http/cookiejar.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/msilib/schema.py | 2 +- Lib/test/regrtest.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_io.py | 2 +- Lib/test/test_socket.py | 2 +- Lib/test/test_userdict.py | 2 +- Lib/tkinter/__init__.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 2 +- Modules/_ssl.c | 2 +- Modules/itertoolsmodule.c | 2 +- Objects/unicodeobject.c | 4 ++-- 34 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -167,7 +167,7 @@ username: password: -The *distutils* section defines a *index-servers* variable that lists the +The *distutils* section defines an *index-servers* variable that lists the name of all sections describing a repository. Each section describing a repository defines three variables: diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -319,7 +319,7 @@ patterns of binding functions into methods. To recap, functions have a :meth:`__get__` method so that they can be converted -to a method when accessed as attributes. The non-data descriptor transforms a +to a method when accessed as attributes. The non-data descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)`` becomes ``f(*args)``. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -148,7 +148,7 @@ On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a +:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a graphical user interface (such as WinZip) or a command-line tool (such as :program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a command prompt window and run:: diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -148,7 +148,7 @@ high-water limit. Neither *high* nor *low* can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting *high* to zero forces *low* to zero as well, and causes :meth:`pause_writing` to be called whenever the diff --git a/Doc/library/contextlib.rst b/Doc/library/contextlib.rst --- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -142,7 +142,7 @@ is hardwired to stdout. For example, the output of :func:`help` normally is sent to *sys.stdout*. - You can capture that output in a string by redirecting the output to a + You can capture that output in a string by redirecting the output to an :class:`io.StringIO` object:: f = io.StringIO() diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -146,7 +146,7 @@ methods on file-like objects. The text contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). @@ -189,7 +189,7 @@ methods on file-like objects. The bytes contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts, including subparts diff --git a/Doc/library/gzip.rst b/Doc/library/gzip.rst --- a/Doc/library/gzip.rst +++ b/Doc/library/gzip.rst @@ -64,7 +64,7 @@ method. At least one of *fileobj* and *filename* must be given a non-trivial value. - The new class instance is based on *fileobj*, which can be a regular file, a + The new class instance is based on *fileobj*, which can be a regular file, an :class:`io.BytesIO` object, or any other object which simulates a file. It defaults to ``None``, in which case *filename* is opened to provide a file object. diff --git a/Doc/library/pickle.rst b/Doc/library/pickle.rst --- a/Doc/library/pickle.rst +++ b/Doc/library/pickle.rst @@ -192,7 +192,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. @@ -288,7 +288,7 @@ number is specified, :data:`HIGHEST_PROTOCOL` is selected. The *file* argument must have a write() method that accepts a single bytes - argument. It can thus be an on-disk file opened for binary writing, a + argument. It can thus be an on-disk file opened for binary writing, an :class:`io.BytesIO` instance, or any other custom object that meets this interface. diff --git a/Doc/library/socket.rst b/Doc/library/socket.rst --- a/Doc/library/socket.rst +++ b/Doc/library/socket.rst @@ -762,7 +762,7 @@ .. function:: sethostname(name) - Set the machine's hostname to *name*. This will raise a + Set the machine's hostname to *name*. This will raise an :exc:`OSError` if you don't have enough rights. Availability: Unix. @@ -794,7 +794,7 @@ .. function:: if_indextoname(if_index) - Return a network interface name corresponding to a + Return a network interface name corresponding to an interface index number. :exc:`OSError` if no interface with the given index exists. diff --git a/Doc/library/tokenize.rst b/Doc/library/tokenize.rst --- a/Doc/library/tokenize.rst +++ b/Doc/library/tokenize.rst @@ -41,7 +41,7 @@ returned as a :term:`named tuple` with the field names: ``type string start end line``. - The returned :term:`named tuple` has a additional property named + The returned :term:`named tuple` has an additional property named ``exact_type`` that contains the exact operator type for :data:`token.OP` tokens. For all other token types ``exact_type`` equals the named tuple ``type`` field. diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -464,7 +464,7 @@ .. versionadded:: 3.1 Unittest supports skipping individual test methods and even whole classes of -tests. In addition, it supports marking a test as a "expected failure," a test +tests. In addition, it supports marking a test as an "expected failure," a test that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1322,7 +1322,7 @@ .. method:: retrieve(url, filename=None, reporthook=None, data=None) Retrieves the contents of *url* and places it in *filename*. The return value - is a tuple consisting of a local filename and either a + is a tuple consisting of a local filename and either an :class:`email.message.Message` object containing the response headers (for remote URLs) or ``None`` (for local URLs). The caller must then open and read the contents of *filename*. If *filename* is not given and the URL refers to a diff --git a/Doc/library/xml.dom.minidom.rst b/Doc/library/xml.dom.minidom.rst --- a/Doc/library/xml.dom.minidom.rst +++ b/Doc/library/xml.dom.minidom.rst @@ -54,7 +54,7 @@ .. function:: parseString(string, parser=None) - Return a :class:`Document` that represents the *string*. This method creates a + Return a :class:`Document` that represents the *string*. This method creates an :class:`io.StringIO` object for the string and passes that on to :func:`parse`. Both functions return a :class:`Document` object representing the content of the diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -30,7 +30,7 @@ .. function:: adler32(data[, value]) - Computes a Adler-32 checksum of *data*. (An Adler-32 checksum is almost as + Computes an Adler-32 checksum of *data*. (An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much more quickly.) If *value* is present, it is used as the starting value of the checksum; otherwise, a fixed default value is used. This allows computing a running checksum over the diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1118,7 +1118,7 @@ (Fixed by Daniel Stutzbach; :issue:`8729`.) * Constructors for the parsing classes in the :mod:`ConfigParser` module now - take a *allow_no_value* parameter, defaulting to false; if true, + take an *allow_no_value* parameter, defaulting to false; if true, options without values will be allowed. For example:: >>> import ConfigParser, StringIO diff --git a/Doc/whatsnew/3.3.rst b/Doc/whatsnew/3.3.rst --- a/Doc/whatsnew/3.3.rst +++ b/Doc/whatsnew/3.3.rst @@ -2155,7 +2155,7 @@ * encode an ASCII string to UTF-8 doesn't need to encode characters anymore, the UTF-8 representation is shared with the ASCII representation * the UTF-8 encoder has been optimized - * repeating a single ASCII letter and getting a substring of a ASCII strings + * repeating a single ASCII letter and getting a substring of an ASCII string is 4 times faster * UTF-8 is now 2x to 4x faster. UTF-16 encoding is now up to 10x faster. diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -965,7 +965,7 @@ Py_ssize_t end ); -/* Append a ASCII-encoded byte string. +/* Append an ASCII-encoded byte string. Return 0 on success, raise an exception and return -1 on error. */ PyAPI_FUNC(int) _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer, @@ -2041,7 +2041,7 @@ int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ ); -/* Apply a argument tuple or dictionary to a format string and return +/* Apply an argument tuple or dictionary to a format string and return the resulting Unicode string. */ PyAPI_FUNC(PyObject *) PyUnicode_Format( diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -349,7 +349,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -62,7 +62,7 @@ high-water limit. Neither value can be negative. The defaults are implementation-specific. If only the - high-water limit is given, the low-water limit defaults to a + high-water limit is given, the low-water limit defaults to an implementation-specific value less than or equal to the high-water limit. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -30,7 +30,7 @@ # value is printed correctly. # # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is + # error message - instead an additional frame for the C code is # created, then a full traceback printed. When SystemExit is # raised in a callback function, the interpreter exits. diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -1437,7 +1437,7 @@ break # convert RFC 2965 Max-Age to seconds since epoch # XXX Strictly you're supposed to follow RFC 2616 - # age-calculation rules. Remember that zero Max-Age is a + # age-calculation rules. Remember that zero Max-Age # is a request to discard (old and new) cookie, though. k = "expires" v = self._now + v diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -114,7 +114,7 @@ left_node = expr_node.children[0] if isinstance(left_node, Leaf) and \ left_node.value == '__metaclass__': - # We found a assignment to __metaclass__. + # We found an assignment to __metaclass__. fixup_simple_stmt(node, i, simple_node) remove_trailing_newline(simple_node) yield (node, i, simple_node) diff --git a/Lib/msilib/schema.py b/Lib/msilib/schema.py --- a/Lib/msilib/schema.py +++ b/Lib/msilib/schema.py @@ -733,7 +733,7 @@ ('CustomAction','Source','Y',None, None, None, None, 'CustomSource',None, 'The table reference of the source of the code.',), ('CustomAction','Target','Y',None, None, None, None, 'Formatted',None, 'Excecution parameter, depends on the type of custom action',), ('DrLocator','Signature_','N',None, None, None, None, 'Identifier',None, 'The Signature_ represents a unique file signature and is also the foreign key in the Signature table.',), -('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), +('DrLocator','Path','Y',None, None, None, None, 'AnyPath',None, 'The path on the user system. This is either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded.',), ('DrLocator','Depth','Y',0,32767,None, None, None, None, 'The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0.',), ('DrLocator','Parent','Y',None, None, None, None, 'Identifier',None, 'The parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path.',), ('DuplicateFile','File_','N',None, None, 'File',1,'Identifier',None, 'Foreign key referencing the source file to be duplicated.',), diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -27,7 +27,7 @@ EPILOG = """\ Additional option details: --r randomizes test execution order. You can use --randseed=int to provide a +-r randomizes test execution order. You can use --randseed=int to provide an int seed value for the randomizer; this is useful for reproducing troublesome test orders. diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -603,7 +603,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(dict): def __missing__(self, key): return 42 diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -15,7 +15,7 @@ ################################################################################ # When writing tests for io, it's important to test both the C and Python # implementations. This is usually done by writing a base test that refers to -# the type it is testing as a attribute. Then it provides custom subclasses to +# the type it is testing as an attribute. Then it provides custom subclasses to # test both implementations. This file has lots of examples. ################################################################################ diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -4651,7 +4651,7 @@ except OSError as e: if str(e) == "AF_UNIX path too long": self.skipTest( - "Pathname {0!a} is too long to serve as a AF_UNIX path" + "Pathname {0!a} is too long to serve as an AF_UNIX path" .format(path)) else: raise diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -171,7 +171,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(collections.UserDict): def __missing__(self, key): return 42 diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -1117,7 +1117,7 @@ return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -12379,7 +12379,7 @@ - Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly. -- Patch #1212117: os.stat().st_flags is now accessible as a attribute +- Patch #1212117: os.stat().st_flags is now accessible as an attribute if available on the platform. - Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1008,7 +1008,7 @@ Changes are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an editor window with a filename. When Class Browser is requested otherwise, from a shell, output window, or 'Untitled' editor, Idle no longer displays an error box. It now pops up an Open Module box (Alt+M). If a valid name diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2693,7 +2693,7 @@ cadata_ascii = PyUnicode_AsASCIIString(cadata); if (cadata_ascii == NULL) { PyErr_SetString(PyExc_TypeError, - "cadata should be a ASCII string or a " + "cadata should be an ASCII string or a " "bytes-like object"); goto error; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1725,7 +1725,7 @@ "starmap(function, sequence) --> starmap object\n\ \n\ Return an iterator whose values are returned from the function evaluated\n\ -with a argument tuple taken from the given sequence."); +with an argument tuple taken from the given sequence."); static PyTypeObject starmap_type = { PyVarObject_HEAD_INIT(NULL, 0) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1703,7 +1703,7 @@ return unicode_resize(p_unicode, length); } -/* Copy a ASCII or latin1 char* string into a Python Unicode string. +/* Copy an ASCII or latin1 char* string into a Python Unicode string. WARNING: The function doesn't copy the terminating null character and doesn't check the maximum character (may write a latin1 character in an @@ -7290,7 +7290,7 @@ } /* - * Encode a Unicode string to a Windows code page into a byte string using a + * Encode a Unicode string to a Windows code page into a byte string using an * error handler. * * Returns consumed characters if succeed, or raise an OSError and returns -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Mon Nov 2 11:05:55 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 2 Nov 2015 16:05:55 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-02 Message-ID: <539f22d0-2a77-43ca-bac5-da9ad997bacf@irsmsx106.ger.corp.intel.com> Results for project Python default, build date 2015-11-02 10:18:08 +0000 commit: 83fa2e9b0038db72dc29be5fbcfcb126841c3b05 revision date: 2015-11-02 05:39:56 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.33% -0.11% 7.54% 16.65% :-( pybench 0.11% 0.09% -2.27% 9.23% :-( regex_v8 2.70% 0.26% -4.34% 5.02% :-( nbody 0.15% 0.70% -2.46% 10.29% :-( json_dump_v2 0.33% -1.31% -2.22% 9.21% :-| normal_startup 0.86% -0.38% -0.35% 5.83% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Mon Nov 2 11:16:56 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 2 Nov 2015 16:16:56 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-02 Message-ID: <4ef1f880-c168-4074-9420-ddb7d00876f6@irsmsx106.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-02 11:07:14 +0000 commit: 4ed175ee3ccab4e47792b0821ffdd45350d20ef8 revision date: 2015-10-30 23:41:10 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.15% -0.13% 3.18% 8.60% :-) pybench 0.21% -0.07% 6.63% 7.54% :-| regex_v8 0.55% 0.11% -1.69% 7.11% :-) nbody 0.29% -0.02% 8.70% 4.63% :-) json_dump_v2 0.27% 0.55% 2.69% 14.68% :-| normal_startup 2.17% 0.24% -1.47% 2.72% :-) ssbench 0.27% 2.67% 1.33% -0.28% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Mon Nov 2 12:17:28 2015 From: python-checkins at python.org (guido.van.rossum) Date: Mon, 02 Nov 2015 17:17:28 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Use_sys=2Eplatform_instead_of_os=2Ename_to_detect_Windows_in_a?= =?utf-8?q?syncio_docs=2E_Patch_by?= Message-ID: <20151102171728.494.36554@psf.io> https://hg.python.org/cpython/rev/e2400d5d67e7 changeset: 98942:e2400d5d67e7 branch: 3.5 parent: 98938:a0d0f968b020 parent: 98941:193327cabbbc user: Guido van Rossum date: Mon Nov 02 09:16:37 2015 -0800 summary: Use sys.platform instead of os.name to detect Windows in asyncio docs. Patch by Akira Li. (Merge 3.4->3.5) files: Doc/library/asyncio-eventloops.rst | 5 ++--- Doc/library/asyncio-subprocess.rst | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -57,9 +57,9 @@ Example to use a :class:`ProactorEventLoop` on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) @@ -198,4 +198,3 @@ Set the current event loop policy. If *policy* is ``None``, the default policy is restored. - diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -12,9 +12,9 @@ support subprocesses. :class:`ProactorEventLoop` should be used instead. Example to use it on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 12:17:28 2015 From: python-checkins at python.org (guido.van.rossum) Date: Mon, 02 Nov 2015 17:17:28 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogVXNlIHN5cy5wbGF0?= =?utf-8?q?form_instead_of_os=2Ename_to_detect_Windows_in_asyncio_docs=2E_?= =?utf-8?q?Patch_by?= Message-ID: <20151102171727.12541.90357@psf.io> https://hg.python.org/cpython/rev/193327cabbbc changeset: 98941:193327cabbbc branch: 3.4 parent: 98936:75df8b0a2cd1 user: Guido van Rossum date: Mon Nov 02 09:15:47 2015 -0800 summary: Use sys.platform instead of os.name to detect Windows in asyncio docs. Patch by Akira Li. files: Doc/library/asyncio-eventloops.rst | 5 ++--- Doc/library/asyncio-subprocess.rst | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -57,9 +57,9 @@ Example to use a :class:`ProactorEventLoop` on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) @@ -196,4 +196,3 @@ Set the current event loop policy. If *policy* is ``None``, the default policy is restored. - diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -12,9 +12,9 @@ support subprocesses. :class:`ProactorEventLoop` should be used instead. Example to use it on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 2 12:17:28 2015 From: python-checkins at python.org (guido.van.rossum) Date: Mon, 02 Nov 2015 17:17:28 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Use_sys=2Eplatform_instead_of_os=2Ename_to_detect_Window?= =?utf-8?q?s_in_asyncio_docs=2E_Patch_by?= Message-ID: <20151102171728.500.30855@psf.io> https://hg.python.org/cpython/rev/40ce5f4b8835 changeset: 98943:40ce5f4b8835 parent: 98939:72cca30f4707 parent: 98942:e2400d5d67e7 user: Guido van Rossum date: Mon Nov 02 09:17:08 2015 -0800 summary: Use sys.platform instead of os.name to detect Windows in asyncio docs. Patch by Akira Li. (Merge 3.5->3.6) files: Doc/library/asyncio-eventloops.rst | 5 ++--- Doc/library/asyncio-subprocess.rst | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -57,9 +57,9 @@ Example to use a :class:`ProactorEventLoop` on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) @@ -198,4 +198,3 @@ Set the current event loop policy. If *policy* is ``None``, the default policy is restored. - diff --git a/Doc/library/asyncio-subprocess.rst b/Doc/library/asyncio-subprocess.rst --- a/Doc/library/asyncio-subprocess.rst +++ b/Doc/library/asyncio-subprocess.rst @@ -12,9 +12,9 @@ support subprocesses. :class:`ProactorEventLoop` should be used instead. Example to use it on Windows:: - import asyncio, os + import asyncio, sys - if os.name == 'nt': + if sys.platform == 'win32': loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Tue Nov 3 03:57:40 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 03 Nov 2015 08:57:40 +0000 Subject: [Python-checkins] Daily reference leaks (40ce5f4b8835): sum=7 Message-ID: <20151103085739.18106.84933@psf.io> results for 40ce5f4b8835 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogRKkovS', '--timeout', '7200'] From lp_benchmark_robot at intel.com Tue Nov 3 07:11:52 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 3 Nov 2015 12:11:52 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-03 Message-ID: Results for project Python default, build date 2015-11-03 09:18:51 +0000 commit: 40ce5f4b88354fe872d02e949bef794286221389 revision date: 2015-11-02 17:17:08 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.23% 0.22% 7.74% 16.70% :-( pybench 0.11% -0.02% -2.29% 9.72% :-( regex_v8 2.68% -0.04% -4.39% 5.35% :-| nbody 0.12% 0.79% -1.65% 11.32% :-( json_dump_v2 0.26% -0.09% -2.31% 9.25% :-| normal_startup 0.88% 0.15% 0.10% 5.57% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Tue Nov 3 07:12:38 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 3 Nov 2015 12:12:38 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-03 Message-ID: <2bd3a2a3-6327-4aee-a73c-04e1f8d8e103@irsmsx102.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-03 10:06:54 +0000 commit: e8f3c011e2b4daf8f3cb7dba7f40f587433049ec revision date: 2015-11-02 13:06:09 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.15% 0.10% 3.27% 7.85% :-) pybench 0.21% -0.02% 6.61% 7.14% :-| regex_v8 0.55% 0.14% -1.55% 8.17% :-) nbody 0.18% 0.12% 8.81% 2.72% :-) json_dump_v2 0.25% -0.17% 2.53% 15.30% :-| normal_startup 1.74% -0.18% -1.65% 3.01% :-| ssbench 0.51% -1.40% -0.09% 1.37% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Tue Nov 3 08:35:48 2015 From: python-checkins at python.org (victor.stinner) Date: Tue, 03 Nov 2015 13:35:48 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_locale=2Edelocalize=28=29?= =?utf-8?q?=3A_only_call_localeconv=28=29_once?= Message-ID: <20151103133537.13214.25834@psf.io> https://hg.python.org/cpython/rev/45719f62f3a3 changeset: 98944:45719f62f3a3 user: Victor Stinner date: Tue Nov 03 14:34:51 2015 +0100 summary: locale.delocalize(): only call localeconv() once files: Lib/locale.py | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lib/locale.py b/Lib/locale.py --- a/Lib/locale.py +++ b/Lib/locale.py @@ -303,12 +303,16 @@ def delocalize(string): "Parses a string as a normalized number according to the locale settings." + + conv = localeconv() + #First, get rid of the grouping - ts = localeconv()['thousands_sep'] + ts = conv['thousands_sep'] if ts: string = string.replace(ts, '') + #next, replace the decimal point with a dot - dd = localeconv()['decimal_point'] + dd = conv['decimal_point'] if dd: string = string.replace(dd, '.') return string -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 3 12:45:22 2015 From: python-checkins at python.org (eric.smith) Date: Tue, 03 Nov 2015 17:45:22 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_25483=3A_Add_an_opco?= =?utf-8?q?de_to_make_f-string_formatting_more_robust=2E?= Message-ID: <20151103174522.10568.83496@psf.io> https://hg.python.org/cpython/rev/1ddeb2e175df changeset: 98945:1ddeb2e175df user: Eric V. Smith date: Tue Nov 03 12:45:05 2015 -0500 summary: Issue 25483: Add an opcode to make f-string formatting more robust. files: Include/ceval.h | 8 + Include/opcode.h | 1 + Lib/importlib/_bootstrap_external.py | 3 +- Lib/opcode.py | 2 + Python/ceval.c | 57 ++++ Python/compile.c | 110 ++----- Python/importlib_external.h | 206 +++++++------- Python/opcode_targets.h | 2 +- 8 files changed, 213 insertions(+), 176 deletions(-) diff --git a/Include/ceval.h b/Include/ceval.h --- a/Include/ceval.h +++ b/Include/ceval.h @@ -206,6 +206,14 @@ PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); #endif +/* Masks and values used by FORMAT_VALUE opcode. */ +#define FVC_MASK 0x3 +#define FVC_NONE 0x0 +#define FVC_STR 0x1 +#define FVC_REPR 0x2 +#define FVC_ASCII 0x3 +#define FVS_MASK 0x4 +#define FVS_HAVE_SPEC 0x4 #ifdef __cplusplus } diff --git a/Include/opcode.h b/Include/opcode.h --- a/Include/opcode.h +++ b/Include/opcode.h @@ -122,6 +122,7 @@ #define BUILD_TUPLE_UNPACK 152 #define BUILD_SET_UNPACK 153 #define SETUP_ASYNC_WITH 154 +#define FORMAT_VALUE 155 /* EXCEPT_HANDLER is a special, implicit block type which is created when entering an except handler. It is not an opcode but we define it here diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -223,12 +223,13 @@ # Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations) # Python 3.5b2 3340 (fix dictionary display evaluation order #11205) # Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400) +# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually # due to the addition of new opcodes). -MAGIC_NUMBER = (3350).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3360).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/opcode.py b/Lib/opcode.py --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -214,4 +214,6 @@ def_op('BUILD_TUPLE_UNPACK', 152) def_op('BUILD_SET_UNPACK', 153) +def_op('FORMAT_VALUE', 155) + del def_op, name_op, jrel_op, jabs_op diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3363,6 +3363,63 @@ DISPATCH(); } + TARGET(FORMAT_VALUE) { + /* Handles f-string value formatting. */ + PyObject *result; + PyObject *fmt_spec; + PyObject *value; + PyObject *(*conv_fn)(PyObject *); + int which_conversion = oparg & FVC_MASK; + int have_fmt_spec = (oparg & FVS_MASK) == FVS_HAVE_SPEC; + + fmt_spec = have_fmt_spec ? POP() : NULL; + value = TOP(); + + /* See if any conversion is specified. */ + switch (which_conversion) { + case FVC_STR: conv_fn = PyObject_Str; break; + case FVC_REPR: conv_fn = PyObject_Repr; break; + case FVC_ASCII: conv_fn = PyObject_ASCII; break; + + /* Must be 0 (meaning no conversion), since only four + values are allowed by (oparg & FVC_MASK). */ + default: conv_fn = NULL; break; + } + + /* If there's a conversion function, call it and replace + value with that result. Otherwise, just use value, + without conversion. */ + if (conv_fn) { + result = conv_fn(value); + Py_DECREF(value); + if (!result) { + Py_XDECREF(fmt_spec); + goto error; + } + value = result; + } + + /* If value is a unicode object, and there's no fmt_spec, + then we know the result of format(value) is value + itself. In that case, skip calling format(). I plan to + move this optimization in to PyObject_Format() + itself. */ + if (PyUnicode_CheckExact(value) && fmt_spec == NULL) { + /* Do nothing, just transfer ownership to result. */ + result = value; + } else { + /* Actually call format(). */ + result = PyObject_Format(value, fmt_spec); + Py_DECREF(value); + Py_XDECREF(fmt_spec); + if (!result) + goto error; + } + + SET_TOP(result); + DISPATCH(); + } + TARGET(EXTENDED_ARG) { opcode = NEXTOP(); oparg = oparg<<16 | NEXTARG(); diff --git a/Python/compile.c b/Python/compile.c --- a/Python/compile.c +++ b/Python/compile.c @@ -1067,6 +1067,10 @@ return 1; case GET_YIELD_FROM_ITER: return 0; + case FORMAT_VALUE: + /* If there's a fmt_spec on the stack, we go from 2->1, + else 1->1. */ + return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0; default: return PY_INVALID_STACK_EFFECT; } @@ -3241,83 +3245,47 @@ return 1; } -/* Note that this code uses the builtin functions format(), str(), - repr(), and ascii(). You can break this code, or make it do odd - things, by redefining those functions. */ +/* Used to implement f-strings. Format a single value. */ static int compiler_formatted_value(struct compiler *c, expr_ty e) { - PyObject *conversion_name = NULL; - - static PyObject *format_string; - static PyObject *str_string; - static PyObject *repr_string; - static PyObject *ascii_string; - - if (!format_string) { - format_string = PyUnicode_InternFromString("format"); - if (!format_string) - return 0; + /* Our oparg encodes 2 pieces of information: the conversion + character, and whether or not a format_spec was provided. + + Convert the conversion char to 2 bits: + None: 000 0x0 FVC_NONE + !s : 001 0x1 FVC_STR + !r : 010 0x2 FVC_REPR + !a : 011 0x3 FVC_ASCII + + next bit is whether or not we have a format spec: + yes : 100 0x4 + no : 000 0x0 + */ + + int oparg; + + /* Evaluate the expression to be formatted. */ + VISIT(c, expr, e->v.FormattedValue.value); + + switch (e->v.FormattedValue.conversion) { + case 's': oparg = FVC_STR; break; + case 'r': oparg = FVC_REPR; break; + case 'a': oparg = FVC_ASCII; break; + case -1: oparg = FVC_NONE; break; + default: + PyErr_SetString(PyExc_SystemError, + "Unrecognized conversion character"); + return 0; } - - if (!str_string) { - str_string = PyUnicode_InternFromString("str"); - if (!str_string) - return 0; + if (e->v.FormattedValue.format_spec) { + /* Evaluate the format spec, and update our opcode arg. */ + VISIT(c, expr, e->v.FormattedValue.format_spec); + oparg |= FVS_HAVE_SPEC; } - if (!repr_string) { - repr_string = PyUnicode_InternFromString("repr"); - if (!repr_string) - return 0; - } - if (!ascii_string) { - ascii_string = PyUnicode_InternFromString("ascii"); - if (!ascii_string) - return 0; - } - - ADDOP_NAME(c, LOAD_GLOBAL, format_string, names); - - /* If needed, convert via str, repr, or ascii. */ - if (e->v.FormattedValue.conversion != -1) { - switch (e->v.FormattedValue.conversion) { - case 's': - conversion_name = str_string; - break; - case 'r': - conversion_name = repr_string; - break; - case 'a': - conversion_name = ascii_string; - break; - default: - PyErr_SetString(PyExc_SystemError, - "Unrecognized conversion character"); - return 0; - } - ADDOP_NAME(c, LOAD_GLOBAL, conversion_name, names); - } - - /* Evaluate the value. */ - VISIT(c, expr, e->v.FormattedValue.value); - - /* If needed, convert via str, repr, or ascii. */ - if (conversion_name) { - /* Call the function we previously pushed. */ - ADDOP_I(c, CALL_FUNCTION, 1); - } - - /* If we have a format spec, use format(value, format_spec). Otherwise, - use the single argument form. */ - if (e->v.FormattedValue.format_spec) { - VISIT(c, expr, e->v.FormattedValue.format_spec); - ADDOP_I(c, CALL_FUNCTION, 2); - } else { - /* No format spec specified, call format(value). */ - ADDOP_I(c, CALL_FUNCTION, 1); - } - + /* And push our opcode and oparg */ + ADDOP_I(c, FORMAT_VALUE, oparg); return 1; } diff --git a/Python/importlib_external.h b/Python/importlib_external.h --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -258,7 +258,7 @@ 114,5,0,0,0,218,13,95,119,114,105,116,101,95,97,116, 111,109,105,99,99,0,0,0,115,26,0,0,0,0,5,24, 1,9,1,33,1,3,3,21,1,20,1,20,1,13,1,3, - 1,17,1,13,1,5,1,114,55,0,0,0,105,22,13,0, + 1,17,1,13,1,5,1,114,55,0,0,0,105,32,13,0, 0,233,2,0,0,0,114,13,0,0,0,115,2,0,0,0, 13,10,90,11,95,95,112,121,99,97,99,104,101,95,95,122, 4,111,112,116,45,122,3,46,112,121,122,4,46,112,121,99, @@ -368,7 +368,7 @@ 103,90,15,97,108,109,111,115,116,95,102,105,108,101,110,97, 109,101,114,4,0,0,0,114,4,0,0,0,114,5,0,0, 0,218,17,99,97,99,104,101,95,102,114,111,109,95,115,111, - 117,114,99,101,243,0,0,0,115,46,0,0,0,0,18,12, + 117,114,99,101,244,0,0,0,115,46,0,0,0,0,18,12, 1,9,1,7,1,12,1,6,1,12,1,18,1,18,1,24, 1,12,1,12,1,12,1,36,1,12,1,18,1,9,2,12, 1,12,1,12,1,12,1,21,1,21,1,114,79,0,0,0, @@ -447,7 +447,7 @@ 101,118,101,108,90,13,98,97,115,101,95,102,105,108,101,110, 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,0, 0,0,218,17,115,111,117,114,99,101,95,102,114,111,109,95, - 99,97,99,104,101,31,1,0,0,115,44,0,0,0,0,9, + 99,97,99,104,101,32,1,0,0,115,44,0,0,0,0,9, 18,1,12,1,18,1,18,1,12,1,9,1,15,1,15,1, 12,1,9,1,15,1,12,1,22,1,15,1,9,1,12,1, 22,1,12,1,9,1,12,1,19,1,114,85,0,0,0,99, @@ -484,7 +484,7 @@ 0,0,114,36,0,0,0,90,9,101,120,116,101,110,115,105, 111,110,218,11,115,111,117,114,99,101,95,112,97,116,104,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,15, - 95,103,101,116,95,115,111,117,114,99,101,102,105,108,101,64, + 95,103,101,116,95,115,111,117,114,99,101,102,105,108,101,65, 1,0,0,115,20,0,0,0,0,7,18,1,4,1,24,1, 35,1,4,1,3,1,16,1,19,1,21,1,114,91,0,0, 0,99,1,0,0,0,0,0,0,0,1,0,0,0,11,0, @@ -499,7 +499,7 @@ 0,0,114,79,0,0,0,114,66,0,0,0,114,74,0,0, 0,41,1,218,8,102,105,108,101,110,97,109,101,114,4,0, 0,0,114,4,0,0,0,114,5,0,0,0,218,11,95,103, - 101,116,95,99,97,99,104,101,100,83,1,0,0,115,16,0, + 101,116,95,99,97,99,104,101,100,84,1,0,0,115,16,0, 0,0,0,1,21,1,3,1,14,1,13,1,8,1,21,1, 4,2,114,95,0,0,0,99,1,0,0,0,0,0,0,0, 2,0,0,0,11,0,0,0,67,0,0,0,115,60,0,0, @@ -514,7 +514,7 @@ 114,39,0,0,0,114,41,0,0,0,114,40,0,0,0,41, 2,114,35,0,0,0,114,42,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,10,95,99,97,108, - 99,95,109,111,100,101,95,1,0,0,115,12,0,0,0,0, + 99,95,109,111,100,101,96,1,0,0,115,12,0,0,0,0, 2,3,1,19,1,13,1,11,3,10,1,114,97,0,0,0, 99,1,0,0,0,0,0,0,0,3,0,0,0,11,0,0, 0,3,0,0,0,115,84,0,0,0,100,1,0,135,0,0, @@ -554,7 +554,7 @@ 103,115,90,6,107,119,97,114,103,115,41,1,218,6,109,101, 116,104,111,100,114,4,0,0,0,114,5,0,0,0,218,19, 95,99,104,101,99,107,95,110,97,109,101,95,119,114,97,112, - 112,101,114,115,1,0,0,115,12,0,0,0,0,1,12,1, + 112,101,114,116,1,0,0,115,12,0,0,0,0,1,12,1, 12,1,15,1,6,1,25,1,122,40,95,99,104,101,99,107, 95,110,97,109,101,46,60,108,111,99,97,108,115,62,46,95, 99,104,101,99,107,95,110,97,109,101,95,119,114,97,112,112, @@ -573,7 +573,7 @@ 116,97,116,116,114,218,8,95,95,100,105,99,116,95,95,218, 6,117,112,100,97,116,101,41,3,90,3,110,101,119,90,3, 111,108,100,114,52,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,218,5,95,119,114,97,112,126,1, + 0,0,114,5,0,0,0,218,5,95,119,114,97,112,127,1, 0,0,115,8,0,0,0,0,1,25,1,15,1,29,1,122, 26,95,99,104,101,99,107,95,110,97,109,101,46,60,108,111, 99,97,108,115,62,46,95,119,114,97,112,41,3,218,10,95, @@ -581,7 +581,7 @@ 78,97,109,101,69,114,114,111,114,41,3,114,102,0,0,0, 114,103,0,0,0,114,113,0,0,0,114,4,0,0,0,41, 1,114,102,0,0,0,114,5,0,0,0,218,11,95,99,104, - 101,99,107,95,110,97,109,101,107,1,0,0,115,14,0,0, + 101,99,107,95,110,97,109,101,108,1,0,0,115,14,0,0, 0,0,8,21,7,3,1,13,1,13,2,17,5,13,1,114, 116,0,0,0,99,2,0,0,0,0,0,0,0,5,0,0, 0,4,0,0,0,67,0,0,0,115,84,0,0,0,124,0, @@ -611,7 +611,7 @@ 218,8,112,111,114,116,105,111,110,115,218,3,109,115,103,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,17, 95,102,105,110,100,95,109,111,100,117,108,101,95,115,104,105, - 109,135,1,0,0,115,10,0,0,0,0,10,21,1,24,1, + 109,136,1,0,0,115,10,0,0,0,0,10,21,1,24,1, 6,1,29,1,114,123,0,0,0,99,4,0,0,0,0,0, 0,0,11,0,0,0,19,0,0,0,67,0,0,0,115,252, 1,0,0,105,0,0,125,4,0,124,2,0,100,1,0,107, @@ -698,7 +698,7 @@ 218,11,115,111,117,114,99,101,95,115,105,122,101,114,4,0, 0,0,114,4,0,0,0,114,5,0,0,0,218,25,95,118, 97,108,105,100,97,116,101,95,98,121,116,101,99,111,100,101, - 95,104,101,97,100,101,114,152,1,0,0,115,76,0,0,0, + 95,104,101,97,100,101,114,153,1,0,0,115,76,0,0,0, 0,11,6,1,12,1,13,3,6,1,12,1,10,1,16,1, 16,1,16,1,12,1,18,1,16,1,18,1,18,1,15,1, 16,1,15,1,18,1,15,1,16,1,12,1,12,1,3,1, @@ -729,7 +729,7 @@ 5,114,53,0,0,0,114,98,0,0,0,114,89,0,0,0, 114,90,0,0,0,218,4,99,111,100,101,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,17,95,99,111,109, - 112,105,108,101,95,98,121,116,101,99,111,100,101,207,1,0, + 112,105,108,101,95,98,121,116,101,99,111,100,101,208,1,0, 0,115,16,0,0,0,0,2,15,1,15,1,16,1,12,1, 16,1,4,2,18,1,114,141,0,0,0,114,59,0,0,0, 99,3,0,0,0,0,0,0,0,4,0,0,0,3,0,0, @@ -749,7 +749,7 @@ 100,117,109,112,115,41,4,114,140,0,0,0,114,126,0,0, 0,114,134,0,0,0,114,53,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,17,95,99,111,100, - 101,95,116,111,95,98,121,116,101,99,111,100,101,219,1,0, + 101,95,116,111,95,98,121,116,101,99,111,100,101,220,1,0, 0,115,10,0,0,0,0,3,12,1,19,1,19,1,22,1, 114,144,0,0,0,99,1,0,0,0,0,0,0,0,5,0, 0,0,4,0,0,0,67,0,0,0,115,89,0,0,0,100, @@ -778,7 +778,7 @@ 218,8,101,110,99,111,100,105,110,103,90,15,110,101,119,108, 105,110,101,95,100,101,99,111,100,101,114,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,13,100,101,99,111, - 100,101,95,115,111,117,114,99,101,229,1,0,0,115,10,0, + 100,101,95,115,111,117,114,99,101,230,1,0,0,115,10,0, 0,0,0,5,12,1,18,1,15,1,18,1,114,149,0,0, 0,114,120,0,0,0,218,26,115,117,98,109,111,100,117,108, 101,95,115,101,97,114,99,104,95,108,111,99,97,116,105,111, @@ -843,7 +843,7 @@ 102,105,120,101,115,114,153,0,0,0,90,7,100,105,114,110, 97,109,101,114,4,0,0,0,114,4,0,0,0,114,5,0, 0,0,218,23,115,112,101,99,95,102,114,111,109,95,102,105, - 108,101,95,108,111,99,97,116,105,111,110,246,1,0,0,115, + 108,101,95,108,111,99,97,116,105,111,110,247,1,0,0,115, 60,0,0,0,0,12,12,4,6,1,15,2,3,1,19,1, 13,1,5,8,24,1,9,3,12,1,22,1,21,1,15,1, 9,1,5,2,4,3,12,2,15,1,3,1,19,1,13,1, @@ -883,7 +883,7 @@ 72,75,69,89,95,76,79,67,65,76,95,77,65,67,72,73, 78,69,41,2,218,3,99,108,115,218,3,107,101,121,114,4, 0,0,0,114,4,0,0,0,114,5,0,0,0,218,14,95, - 111,112,101,110,95,114,101,103,105,115,116,114,121,68,2,0, + 111,112,101,110,95,114,101,103,105,115,116,114,121,69,2,0, 0,115,8,0,0,0,0,2,3,1,23,1,13,1,122,36, 87,105,110,100,111,119,115,82,101,103,105,115,116,114,121,70, 105,110,100,101,114,46,95,111,112,101,110,95,114,101,103,105, @@ -910,7 +910,7 @@ 121,95,107,101,121,114,165,0,0,0,90,4,104,107,101,121, 218,8,102,105,108,101,112,97,116,104,114,4,0,0,0,114, 4,0,0,0,114,5,0,0,0,218,16,95,115,101,97,114, - 99,104,95,114,101,103,105,115,116,114,121,75,2,0,0,115, + 99,104,95,114,101,103,105,115,116,114,121,76,2,0,0,115, 22,0,0,0,0,2,9,1,12,2,9,1,15,1,22,1, 3,1,18,1,29,1,13,1,9,1,122,38,87,105,110,100, 111,119,115,82,101,103,105,115,116,114,121,70,105,110,100,101, @@ -935,7 +935,7 @@ 103,101,116,114,171,0,0,0,114,120,0,0,0,114,160,0, 0,0,114,158,0,0,0,114,4,0,0,0,114,4,0,0, 0,114,5,0,0,0,218,9,102,105,110,100,95,115,112,101, - 99,90,2,0,0,115,26,0,0,0,0,2,15,1,12,1, + 99,91,2,0,0,115,26,0,0,0,0,2,15,1,12,1, 4,1,3,1,14,1,13,1,9,1,22,1,21,1,9,1, 15,1,9,1,122,31,87,105,110,100,111,119,115,82,101,103, 105,115,116,114,121,70,105,110,100,101,114,46,102,105,110,100, @@ -954,7 +954,7 @@ 175,0,0,0,114,120,0,0,0,41,4,114,164,0,0,0, 114,119,0,0,0,114,35,0,0,0,114,158,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11, - 102,105,110,100,95,109,111,100,117,108,101,106,2,0,0,115, + 102,105,110,100,95,109,111,100,117,108,101,107,2,0,0,115, 8,0,0,0,0,7,18,1,12,1,7,2,122,33,87,105, 110,100,111,119,115,82,101,103,105,115,116,114,121,70,105,110, 100,101,114,46,102,105,110,100,95,109,111,100,117,108,101,41, @@ -963,7 +963,7 @@ 167,0,0,0,218,11,99,108,97,115,115,109,101,116,104,111, 100,114,166,0,0,0,114,172,0,0,0,114,175,0,0,0, 114,176,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,162,0,0,0,56,2, + 4,0,0,0,114,5,0,0,0,114,162,0,0,0,57,2, 0,0,115,20,0,0,0,12,2,6,3,6,3,6,2,6, 2,18,7,18,15,3,1,21,15,3,1,114,162,0,0,0, 99,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0, @@ -1001,7 +1001,7 @@ 100,0,0,0,114,119,0,0,0,114,94,0,0,0,90,13, 102,105,108,101,110,97,109,101,95,98,97,115,101,90,9,116, 97,105,108,95,110,97,109,101,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,153,0,0,0,125,2,0,0, + 0,0,114,5,0,0,0,114,153,0,0,0,126,2,0,0, 115,8,0,0,0,0,3,25,1,22,1,19,1,122,24,95, 76,111,97,100,101,114,66,97,115,105,99,115,46,105,115,95, 112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0, @@ -1012,7 +1012,7 @@ 111,110,46,78,114,4,0,0,0,41,2,114,100,0,0,0, 114,158,0,0,0,114,4,0,0,0,114,4,0,0,0,114, 5,0,0,0,218,13,99,114,101,97,116,101,95,109,111,100, - 117,108,101,133,2,0,0,115,0,0,0,0,122,27,95,76, + 117,108,101,134,2,0,0,115,0,0,0,0,122,27,95,76, 111,97,100,101,114,66,97,115,105,99,115,46,99,114,101,97, 116,101,95,109,111,100,117,108,101,99,2,0,0,0,0,0, 0,0,3,0,0,0,4,0,0,0,67,0,0,0,115,80, @@ -1033,7 +1033,7 @@ 101,99,114,111,0,0,0,41,3,114,100,0,0,0,218,6, 109,111,100,117,108,101,114,140,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,11,101,120,101,99, - 95,109,111,100,117,108,101,136,2,0,0,115,10,0,0,0, + 95,109,111,100,117,108,101,137,2,0,0,115,10,0,0,0, 0,2,18,1,12,1,9,1,15,1,122,25,95,76,111,97, 100,101,114,66,97,115,105,99,115,46,101,120,101,99,95,109, 111,100,117,108,101,99,2,0,0,0,0,0,0,0,2,0, @@ -1043,13 +1043,13 @@ 95,109,111,100,117,108,101,95,115,104,105,109,41,2,114,100, 0,0,0,114,119,0,0,0,114,4,0,0,0,114,4,0, 0,0,114,5,0,0,0,218,11,108,111,97,100,95,109,111, - 100,117,108,101,144,2,0,0,115,2,0,0,0,0,1,122, + 100,117,108,101,145,2,0,0,115,2,0,0,0,0,1,122, 25,95,76,111,97,100,101,114,66,97,115,105,99,115,46,108, 111,97,100,95,109,111,100,117,108,101,78,41,8,114,105,0, 0,0,114,104,0,0,0,114,106,0,0,0,114,107,0,0, 0,114,153,0,0,0,114,180,0,0,0,114,185,0,0,0, 114,187,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,178,0,0,0,120,2, + 4,0,0,0,114,5,0,0,0,114,178,0,0,0,121,2, 0,0,115,10,0,0,0,12,3,6,2,12,8,12,3,12, 8,114,178,0,0,0,99,0,0,0,0,0,0,0,0,0, 0,0,0,4,0,0,0,64,0,0,0,115,106,0,0,0, @@ -1077,7 +1077,7 @@ 32,32,32,32,78,41,1,218,7,73,79,69,114,114,111,114, 41,2,114,100,0,0,0,114,35,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,5,0,0,0,218,10,112,97,116, - 104,95,109,116,105,109,101,150,2,0,0,115,2,0,0,0, + 104,95,109,116,105,109,101,151,2,0,0,115,2,0,0,0, 0,6,122,23,83,111,117,114,99,101,76,111,97,100,101,114, 46,112,97,116,104,95,109,116,105,109,101,99,2,0,0,0, 0,0,0,0,2,0,0,0,3,0,0,0,67,0,0,0, @@ -1112,7 +1112,7 @@ 10,32,32,32,32,32,32,32,32,114,126,0,0,0,41,1, 114,190,0,0,0,41,2,114,100,0,0,0,114,35,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 218,10,112,97,116,104,95,115,116,97,116,115,158,2,0,0, + 218,10,112,97,116,104,95,115,116,97,116,115,159,2,0,0, 115,2,0,0,0,0,11,122,23,83,111,117,114,99,101,76, 111,97,100,101,114,46,112,97,116,104,95,115,116,97,116,115, 99,4,0,0,0,0,0,0,0,4,0,0,0,3,0,0, @@ -1136,7 +1136,7 @@ 114,100,0,0,0,114,90,0,0,0,90,10,99,97,99,104, 101,95,112,97,116,104,114,53,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,15,95,99,97,99, - 104,101,95,98,121,116,101,99,111,100,101,171,2,0,0,115, + 104,101,95,98,121,116,101,99,111,100,101,172,2,0,0,115, 2,0,0,0,0,8,122,28,83,111,117,114,99,101,76,111, 97,100,101,114,46,95,99,97,99,104,101,95,98,121,116,101, 99,111,100,101,99,3,0,0,0,0,0,0,0,3,0,0, @@ -1153,7 +1153,7 @@ 101,115,46,10,32,32,32,32,32,32,32,32,78,114,4,0, 0,0,41,3,114,100,0,0,0,114,35,0,0,0,114,53, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,192,0,0,0,181,2,0,0,115,0,0,0,0, + 0,0,114,192,0,0,0,182,2,0,0,115,0,0,0,0, 122,21,83,111,117,114,99,101,76,111,97,100,101,114,46,115, 101,116,95,100,97,116,97,99,2,0,0,0,0,0,0,0, 5,0,0,0,16,0,0,0,67,0,0,0,115,105,0,0, @@ -1175,7 +1175,7 @@ 0,41,5,114,100,0,0,0,114,119,0,0,0,114,35,0, 0,0,114,147,0,0,0,218,3,101,120,99,114,4,0,0, 0,114,4,0,0,0,114,5,0,0,0,218,10,103,101,116, - 95,115,111,117,114,99,101,188,2,0,0,115,14,0,0,0, + 95,115,111,117,114,99,101,189,2,0,0,115,14,0,0,0, 0,2,15,1,3,1,19,1,18,1,9,1,31,1,122,23, 83,111,117,114,99,101,76,111,97,100,101,114,46,103,101,116, 95,115,111,117,114,99,101,218,9,95,111,112,116,105,109,105, @@ -1197,7 +1197,7 @@ 99,111,109,112,105,108,101,41,4,114,100,0,0,0,114,53, 0,0,0,114,35,0,0,0,114,197,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,5,0,0,0,218,14,115,111, - 117,114,99,101,95,116,111,95,99,111,100,101,198,2,0,0, + 117,114,99,101,95,116,111,95,99,111,100,101,199,2,0,0, 115,4,0,0,0,0,5,21,1,122,27,83,111,117,114,99, 101,76,111,97,100,101,114,46,115,111,117,114,99,101,95,116, 111,95,99,111,100,101,99,2,0,0,0,0,0,0,0,10, @@ -1259,7 +1259,7 @@ 0,0,218,10,98,121,116,101,115,95,100,97,116,97,114,147, 0,0,0,90,11,99,111,100,101,95,111,98,106,101,99,116, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 181,0,0,0,206,2,0,0,115,78,0,0,0,0,7,15, + 181,0,0,0,207,2,0,0,115,78,0,0,0,0,7,15, 1,6,1,3,1,16,1,13,1,11,2,3,1,19,1,13, 1,5,2,16,1,3,1,19,1,13,1,5,2,3,1,9, 1,12,1,13,1,19,1,5,2,12,1,7,1,15,1,6, @@ -1271,7 +1271,7 @@ 0,0,0,114,193,0,0,0,114,192,0,0,0,114,196,0, 0,0,114,200,0,0,0,114,181,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,188,0,0,0,148,2,0,0,115,14,0,0,0,12,2, + 114,188,0,0,0,149,2,0,0,115,14,0,0,0,12,2, 12,8,12,13,12,10,12,7,12,10,18,8,114,188,0,0, 0,99,0,0,0,0,0,0,0,0,0,0,0,0,4,0, 0,0,0,0,0,0,115,112,0,0,0,101,0,0,90,1, @@ -1300,7 +1300,7 @@ 46,78,41,2,114,98,0,0,0,114,35,0,0,0,41,3, 114,100,0,0,0,114,119,0,0,0,114,35,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,179, - 0,0,0,7,3,0,0,115,4,0,0,0,0,3,9,1, + 0,0,0,8,3,0,0,115,4,0,0,0,0,3,9,1, 122,19,70,105,108,101,76,111,97,100,101,114,46,95,95,105, 110,105,116,95,95,99,2,0,0,0,0,0,0,0,2,0, 0,0,2,0,0,0,67,0,0,0,115,34,0,0,0,124, @@ -1309,7 +1309,7 @@ 83,41,1,78,41,2,218,9,95,95,99,108,97,115,115,95, 95,114,111,0,0,0,41,2,114,100,0,0,0,218,5,111, 116,104,101,114,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,6,95,95,101,113,95,95,13,3,0,0,115, + 0,0,0,218,6,95,95,101,113,95,95,14,3,0,0,115, 4,0,0,0,0,1,18,1,122,17,70,105,108,101,76,111, 97,100,101,114,46,95,95,101,113,95,95,99,1,0,0,0, 0,0,0,0,1,0,0,0,3,0,0,0,67,0,0,0, @@ -1318,7 +1318,7 @@ 1,78,41,3,218,4,104,97,115,104,114,98,0,0,0,114, 35,0,0,0,41,1,114,100,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,5,0,0,0,218,8,95,95,104,97, - 115,104,95,95,17,3,0,0,115,2,0,0,0,0,1,122, + 115,104,95,95,18,3,0,0,115,2,0,0,0,0,1,122, 19,70,105,108,101,76,111,97,100,101,114,46,95,95,104,97, 115,104,95,95,99,2,0,0,0,0,0,0,0,2,0,0, 0,3,0,0,0,3,0,0,0,115,22,0,0,0,116,0, @@ -1333,7 +1333,7 @@ 115,117,112,101,114,114,204,0,0,0,114,187,0,0,0,41, 2,114,100,0,0,0,114,119,0,0,0,41,1,114,205,0, 0,0,114,4,0,0,0,114,5,0,0,0,114,187,0,0, - 0,20,3,0,0,115,2,0,0,0,0,10,122,22,70,105, + 0,21,3,0,0,115,2,0,0,0,0,10,122,22,70,105, 108,101,76,111,97,100,101,114,46,108,111,97,100,95,109,111, 100,117,108,101,99,2,0,0,0,0,0,0,0,2,0,0, 0,1,0,0,0,67,0,0,0,115,7,0,0,0,124,0, @@ -1343,7 +1343,7 @@ 111,117,110,100,32,98,121,32,116,104,101,32,102,105,110,100, 101,114,46,41,1,114,35,0,0,0,41,2,114,100,0,0, 0,114,119,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,151,0,0,0,32,3,0,0,115,2, + 114,5,0,0,0,114,151,0,0,0,33,3,0,0,115,2, 0,0,0,0,3,122,23,70,105,108,101,76,111,97,100,101, 114,46,103,101,116,95,102,105,108,101,110,97,109,101,99,2, 0,0,0,0,0,0,0,3,0,0,0,9,0,0,0,67, @@ -1356,14 +1356,14 @@ 78,41,3,114,49,0,0,0,114,50,0,0,0,90,4,114, 101,97,100,41,3,114,100,0,0,0,114,35,0,0,0,114, 54,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,194,0,0,0,37,3,0,0,115,4,0,0, + 0,0,0,114,194,0,0,0,38,3,0,0,115,4,0,0, 0,0,2,21,1,122,19,70,105,108,101,76,111,97,100,101, 114,46,103,101,116,95,100,97,116,97,41,11,114,105,0,0, 0,114,104,0,0,0,114,106,0,0,0,114,107,0,0,0, 114,179,0,0,0,114,207,0,0,0,114,209,0,0,0,114, 116,0,0,0,114,187,0,0,0,114,151,0,0,0,114,194, 0,0,0,114,4,0,0,0,114,4,0,0,0,41,1,114, - 205,0,0,0,114,5,0,0,0,114,204,0,0,0,2,3, + 205,0,0,0,114,5,0,0,0,114,204,0,0,0,3,3, 0,0,115,14,0,0,0,12,3,6,2,12,6,12,4,12, 3,24,12,18,5,114,204,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, @@ -1387,7 +1387,7 @@ 116,105,109,101,90,7,115,116,95,115,105,122,101,41,3,114, 100,0,0,0,114,35,0,0,0,114,202,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,5,0,0,0,114,191,0, - 0,0,47,3,0,0,115,4,0,0,0,0,2,12,1,122, + 0,0,48,3,0,0,115,4,0,0,0,0,2,12,1,122, 27,83,111,117,114,99,101,70,105,108,101,76,111,97,100,101, 114,46,112,97,116,104,95,115,116,97,116,115,99,4,0,0, 0,0,0,0,0,5,0,0,0,5,0,0,0,67,0,0, @@ -1397,7 +1397,7 @@ 100,101,41,2,114,97,0,0,0,114,192,0,0,0,41,5, 114,100,0,0,0,114,90,0,0,0,114,89,0,0,0,114, 53,0,0,0,114,42,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,193,0,0,0,52,3,0, + 0,0,0,114,5,0,0,0,114,193,0,0,0,53,3,0, 0,115,4,0,0,0,0,2,12,1,122,32,83,111,117,114, 99,101,70,105,108,101,76,111,97,100,101,114,46,95,99,97, 99,104,101,95,98,121,116,101,99,111,100,101,114,214,0,0, @@ -1436,7 +1436,7 @@ 0,114,53,0,0,0,114,214,0,0,0,218,6,112,97,114, 101,110,116,114,94,0,0,0,114,27,0,0,0,114,23,0, 0,0,114,195,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,192,0,0,0,57,3,0,0,115, + 0,114,5,0,0,0,114,192,0,0,0,58,3,0,0,115, 42,0,0,0,0,2,18,1,6,2,22,1,18,1,17,2, 19,1,15,1,3,1,17,1,13,2,7,1,18,3,9,1, 10,1,27,1,3,1,16,1,20,1,18,2,12,1,122,25, @@ -1445,7 +1445,7 @@ 0,114,104,0,0,0,114,106,0,0,0,114,107,0,0,0, 114,191,0,0,0,114,193,0,0,0,114,192,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,212,0,0,0,43,3,0,0,115,8,0,0, + 0,0,0,114,212,0,0,0,44,3,0,0,115,8,0,0, 0,12,2,6,2,12,5,12,5,114,212,0,0,0,99,0, 0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,64, 0,0,0,115,46,0,0,0,101,0,0,90,1,0,100,0, @@ -1467,7 +1467,7 @@ 0,114,135,0,0,0,114,141,0,0,0,41,5,114,100,0, 0,0,114,119,0,0,0,114,35,0,0,0,114,53,0,0, 0,114,203,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,181,0,0,0,92,3,0,0,115,8, + 114,5,0,0,0,114,181,0,0,0,93,3,0,0,115,8, 0,0,0,0,1,15,1,15,1,24,1,122,29,83,111,117, 114,99,101,108,101,115,115,70,105,108,101,76,111,97,100,101, 114,46,103,101,116,95,99,111,100,101,99,2,0,0,0,0, @@ -1477,13 +1477,13 @@ 32,105,115,32,110,111,32,115,111,117,114,99,101,32,99,111, 100,101,46,78,114,4,0,0,0,41,2,114,100,0,0,0, 114,119,0,0,0,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,114,196,0,0,0,98,3,0,0,115,2,0, + 5,0,0,0,114,196,0,0,0,99,3,0,0,115,2,0, 0,0,0,2,122,31,83,111,117,114,99,101,108,101,115,115, 70,105,108,101,76,111,97,100,101,114,46,103,101,116,95,115, 111,117,114,99,101,78,41,6,114,105,0,0,0,114,104,0, 0,0,114,106,0,0,0,114,107,0,0,0,114,181,0,0, 0,114,196,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,217,0,0,0,88, + 114,4,0,0,0,114,5,0,0,0,114,217,0,0,0,89, 3,0,0,115,6,0,0,0,12,2,6,2,12,6,114,217, 0,0,0,99,0,0,0,0,0,0,0,0,0,0,0,0, 3,0,0,0,64,0,0,0,115,136,0,0,0,101,0,0, @@ -1508,7 +1508,7 @@ 0,124,0,0,95,1,0,100,0,0,83,41,1,78,41,2, 114,98,0,0,0,114,35,0,0,0,41,3,114,100,0,0, 0,114,98,0,0,0,114,35,0,0,0,114,4,0,0,0, - 114,4,0,0,0,114,5,0,0,0,114,179,0,0,0,115, + 114,4,0,0,0,114,5,0,0,0,114,179,0,0,0,116, 3,0,0,115,4,0,0,0,0,1,9,1,122,28,69,120, 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, 114,46,95,95,105,110,105,116,95,95,99,2,0,0,0,0, @@ -1518,7 +1518,7 @@ 1,0,107,2,0,83,41,1,78,41,2,114,205,0,0,0, 114,111,0,0,0,41,2,114,100,0,0,0,114,206,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,207,0,0,0,119,3,0,0,115,4,0,0,0,0,1, + 114,207,0,0,0,120,3,0,0,115,4,0,0,0,0,1, 18,1,122,26,69,120,116,101,110,115,105,111,110,70,105,108, 101,76,111,97,100,101,114,46,95,95,101,113,95,95,99,1, 0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,67, @@ -1527,7 +1527,7 @@ 65,83,41,1,78,41,3,114,208,0,0,0,114,98,0,0, 0,114,35,0,0,0,41,1,114,100,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,5,0,0,0,114,209,0,0, - 0,123,3,0,0,115,2,0,0,0,0,1,122,28,69,120, + 0,124,3,0,0,115,2,0,0,0,0,1,122,28,69,120, 116,101,110,115,105,111,110,70,105,108,101,76,111,97,100,101, 114,46,95,95,104,97,115,104,95,95,99,2,0,0,0,0, 0,0,0,3,0,0,0,4,0,0,0,67,0,0,0,115, @@ -1544,7 +1544,7 @@ 101,95,100,121,110,97,109,105,99,114,129,0,0,0,114,98, 0,0,0,114,35,0,0,0,41,3,114,100,0,0,0,114, 158,0,0,0,114,184,0,0,0,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,180,0,0,0,126,3,0, + 0,0,0,114,5,0,0,0,114,180,0,0,0,127,3,0, 0,115,10,0,0,0,0,2,6,1,15,1,9,1,16,1, 122,33,69,120,116,101,110,115,105,111,110,70,105,108,101,76, 111,97,100,101,114,46,99,114,101,97,116,101,95,109,111,100, @@ -1562,7 +1562,7 @@ 99,95,100,121,110,97,109,105,99,114,129,0,0,0,114,98, 0,0,0,114,35,0,0,0,41,2,114,100,0,0,0,114, 184,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,114,185,0,0,0,134,3,0,0,115,6,0,0, + 0,0,0,114,185,0,0,0,135,3,0,0,115,6,0,0, 0,0,2,19,1,9,1,122,31,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,46,101,120,101, 99,95,109,111,100,117,108,101,99,2,0,0,0,0,0,0, @@ -1581,7 +1581,7 @@ 0,0,41,2,114,22,0,0,0,218,6,115,117,102,102,105, 120,41,1,218,9,102,105,108,101,95,110,97,109,101,114,4, 0,0,0,114,5,0,0,0,250,9,60,103,101,110,101,120, - 112,114,62,143,3,0,0,115,2,0,0,0,6,1,122,49, + 112,114,62,144,3,0,0,115,2,0,0,0,6,1,122,49, 69,120,116,101,110,115,105,111,110,70,105,108,101,76,111,97, 100,101,114,46,105,115,95,112,97,99,107,97,103,101,46,60, 108,111,99,97,108,115,62,46,60,103,101,110,101,120,112,114, @@ -1589,7 +1589,7 @@ 110,121,218,18,69,88,84,69,78,83,73,79,78,95,83,85, 70,70,73,88,69,83,41,2,114,100,0,0,0,114,119,0, 0,0,114,4,0,0,0,41,1,114,220,0,0,0,114,5, - 0,0,0,114,153,0,0,0,140,3,0,0,115,6,0,0, + 0,0,0,114,153,0,0,0,141,3,0,0,115,6,0,0, 0,0,2,19,1,18,1,122,30,69,120,116,101,110,115,105, 111,110,70,105,108,101,76,111,97,100,101,114,46,105,115,95, 112,97,99,107,97,103,101,99,2,0,0,0,0,0,0,0, @@ -1600,7 +1600,7 @@ 111,116,32,99,114,101,97,116,101,32,97,32,99,111,100,101, 32,111,98,106,101,99,116,46,78,114,4,0,0,0,41,2, 114,100,0,0,0,114,119,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,181,0,0,0,146,3, + 4,0,0,0,114,5,0,0,0,114,181,0,0,0,147,3, 0,0,115,2,0,0,0,0,2,122,28,69,120,116,101,110, 115,105,111,110,70,105,108,101,76,111,97,100,101,114,46,103, 101,116,95,99,111,100,101,99,2,0,0,0,0,0,0,0, @@ -1611,7 +1611,7 @@ 111,32,115,111,117,114,99,101,32,99,111,100,101,46,78,114, 4,0,0,0,41,2,114,100,0,0,0,114,119,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 196,0,0,0,150,3,0,0,115,2,0,0,0,0,2,122, + 196,0,0,0,151,3,0,0,115,2,0,0,0,0,2,122, 30,69,120,116,101,110,115,105,111,110,70,105,108,101,76,111, 97,100,101,114,46,103,101,116,95,115,111,117,114,99,101,99, 2,0,0,0,0,0,0,0,2,0,0,0,1,0,0,0, @@ -1622,7 +1622,7 @@ 98,121,32,116,104,101,32,102,105,110,100,101,114,46,41,1, 114,35,0,0,0,41,2,114,100,0,0,0,114,119,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,151,0,0,0,154,3,0,0,115,2,0,0,0,0,3, + 114,151,0,0,0,155,3,0,0,115,2,0,0,0,0,3, 122,32,69,120,116,101,110,115,105,111,110,70,105,108,101,76, 111,97,100,101,114,46,103,101,116,95,102,105,108,101,110,97, 109,101,78,41,14,114,105,0,0,0,114,104,0,0,0,114, @@ -1631,7 +1631,7 @@ 0,0,114,153,0,0,0,114,181,0,0,0,114,196,0,0, 0,114,116,0,0,0,114,151,0,0,0,114,4,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 218,0,0,0,107,3,0,0,115,20,0,0,0,12,6,6, + 218,0,0,0,108,3,0,0,115,20,0,0,0,12,6,6, 2,12,4,12,4,12,3,12,8,12,6,12,6,12,4,12, 4,114,218,0,0,0,99,0,0,0,0,0,0,0,0,0, 0,0,0,2,0,0,0,64,0,0,0,115,130,0,0,0, @@ -1675,7 +1675,7 @@ 104,95,102,105,110,100,101,114,41,4,114,100,0,0,0,114, 98,0,0,0,114,35,0,0,0,218,11,112,97,116,104,95, 102,105,110,100,101,114,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,179,0,0,0,167,3,0,0,115,8, + 114,5,0,0,0,114,179,0,0,0,168,3,0,0,115,8, 0,0,0,0,1,9,1,9,1,21,1,122,23,95,78,97, 109,101,115,112,97,99,101,80,97,116,104,46,95,95,105,110, 105,116,95,95,99,1,0,0,0,0,0,0,0,4,0,0, @@ -1694,7 +1694,7 @@ 0,0,0,114,216,0,0,0,218,3,100,111,116,90,2,109, 101,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, 218,23,95,102,105,110,100,95,112,97,114,101,110,116,95,112, - 97,116,104,95,110,97,109,101,115,173,3,0,0,115,8,0, + 97,116,104,95,110,97,109,101,115,174,3,0,0,115,8,0, 0,0,0,2,27,1,12,2,4,3,122,38,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,95,102,105,110,100, 95,112,97,114,101,110,116,95,112,97,116,104,95,110,97,109, @@ -1707,7 +1707,7 @@ 3,114,100,0,0,0,90,18,112,97,114,101,110,116,95,109, 111,100,117,108,101,95,110,97,109,101,90,14,112,97,116,104, 95,97,116,116,114,95,110,97,109,101,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,227,0,0,0,183,3, + 4,0,0,0,114,5,0,0,0,114,227,0,0,0,184,3, 0,0,115,4,0,0,0,0,1,18,1,122,31,95,78,97, 109,101,115,112,97,99,101,80,97,116,104,46,95,103,101,116, 95,112,97,114,101,110,116,95,112,97,116,104,99,1,0,0, @@ -1725,7 +1725,7 @@ 150,0,0,0,114,226,0,0,0,41,3,114,100,0,0,0, 90,11,112,97,114,101,110,116,95,112,97,116,104,114,158,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,218,12,95,114,101,99,97,108,99,117,108,97,116,101,187, + 0,218,12,95,114,101,99,97,108,99,117,108,97,116,101,188, 3,0,0,115,16,0,0,0,0,2,18,1,15,1,21,3, 27,1,9,1,12,1,9,1,122,27,95,78,97,109,101,115, 112,97,99,101,80,97,116,104,46,95,114,101,99,97,108,99, @@ -1734,7 +1734,7 @@ 0,0,124,0,0,106,1,0,131,0,0,131,1,0,83,41, 1,78,41,2,218,4,105,116,101,114,114,234,0,0,0,41, 1,114,100,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,218,8,95,95,105,116,101,114,95,95,200, + 114,5,0,0,0,218,8,95,95,105,116,101,114,95,95,201, 3,0,0,115,2,0,0,0,0,1,122,23,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,95,95,105,116,101, 114,95,95,99,1,0,0,0,0,0,0,0,1,0,0,0, @@ -1742,7 +1742,7 @@ 124,0,0,106,1,0,131,0,0,131,1,0,83,41,1,78, 41,2,114,31,0,0,0,114,234,0,0,0,41,1,114,100, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,218,7,95,95,108,101,110,95,95,203,3,0,0,115, + 0,0,218,7,95,95,108,101,110,95,95,204,3,0,0,115, 2,0,0,0,0,1,122,22,95,78,97,109,101,115,112,97, 99,101,80,97,116,104,46,95,95,108,101,110,95,95,99,1, 0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,67, @@ -1751,7 +1751,7 @@ 109,101,115,112,97,99,101,80,97,116,104,40,123,33,114,125, 41,41,2,114,47,0,0,0,114,226,0,0,0,41,1,114, 100,0,0,0,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,8,95,95,114,101,112,114,95,95,206,3,0, + 0,0,0,218,8,95,95,114,101,112,114,95,95,207,3,0, 0,115,2,0,0,0,0,1,122,23,95,78,97,109,101,115, 112,97,99,101,80,97,116,104,46,95,95,114,101,112,114,95, 95,99,2,0,0,0,0,0,0,0,2,0,0,0,2,0, @@ -1759,7 +1759,7 @@ 0,106,0,0,131,0,0,107,6,0,83,41,1,78,41,1, 114,234,0,0,0,41,2,114,100,0,0,0,218,4,105,116, 101,109,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,209, + 0,218,12,95,95,99,111,110,116,97,105,110,115,95,95,210, 3,0,0,115,2,0,0,0,0,1,122,27,95,78,97,109, 101,115,112,97,99,101,80,97,116,104,46,95,95,99,111,110, 116,97,105,110,115,95,95,99,2,0,0,0,0,0,0,0, @@ -1768,7 +1768,7 @@ 1,100,0,0,83,41,1,78,41,2,114,226,0,0,0,114, 157,0,0,0,41,2,114,100,0,0,0,114,239,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 157,0,0,0,212,3,0,0,115,2,0,0,0,0,1,122, + 157,0,0,0,213,3,0,0,115,2,0,0,0,0,1,122, 21,95,78,97,109,101,115,112,97,99,101,80,97,116,104,46, 97,112,112,101,110,100,78,41,13,114,105,0,0,0,114,104, 0,0,0,114,106,0,0,0,114,107,0,0,0,114,179,0, @@ -1776,7 +1776,7 @@ 0,114,236,0,0,0,114,237,0,0,0,114,238,0,0,0, 114,240,0,0,0,114,157,0,0,0,114,4,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,114,224, - 0,0,0,160,3,0,0,115,20,0,0,0,12,5,6,2, + 0,0,0,161,3,0,0,115,20,0,0,0,12,5,6,2, 12,6,12,10,12,4,12,13,12,3,12,3,12,3,12,3, 114,224,0,0,0,99,0,0,0,0,0,0,0,0,0,0, 0,0,3,0,0,0,64,0,0,0,115,118,0,0,0,101, @@ -1795,7 +1795,7 @@ 2,114,224,0,0,0,114,226,0,0,0,41,4,114,100,0, 0,0,114,98,0,0,0,114,35,0,0,0,114,230,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,179,0,0,0,218,3,0,0,115,2,0,0,0,0,1, + 114,179,0,0,0,219,3,0,0,115,2,0,0,0,0,1, 122,25,95,78,97,109,101,115,112,97,99,101,76,111,97,100, 101,114,46,95,95,105,110,105,116,95,95,99,2,0,0,0, 0,0,0,0,2,0,0,0,2,0,0,0,67,0,0,0, @@ -1812,21 +1812,21 @@ 115,112,97,99,101,41,62,41,2,114,47,0,0,0,114,105, 0,0,0,41,2,114,164,0,0,0,114,184,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,11, - 109,111,100,117,108,101,95,114,101,112,114,221,3,0,0,115, + 109,111,100,117,108,101,95,114,101,112,114,222,3,0,0,115, 2,0,0,0,0,7,122,28,95,78,97,109,101,115,112,97, 99,101,76,111,97,100,101,114,46,109,111,100,117,108,101,95, 114,101,112,114,99,2,0,0,0,0,0,0,0,2,0,0, 0,1,0,0,0,67,0,0,0,115,4,0,0,0,100,1, 0,83,41,2,78,84,114,4,0,0,0,41,2,114,100,0, 0,0,114,119,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,153,0,0,0,230,3,0,0,115, + 0,114,5,0,0,0,114,153,0,0,0,231,3,0,0,115, 2,0,0,0,0,1,122,27,95,78,97,109,101,115,112,97, 99,101,76,111,97,100,101,114,46,105,115,95,112,97,99,107, 97,103,101,99,2,0,0,0,0,0,0,0,2,0,0,0, 1,0,0,0,67,0,0,0,115,4,0,0,0,100,1,0, 83,41,2,78,114,30,0,0,0,114,4,0,0,0,41,2, 114,100,0,0,0,114,119,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,196,0,0,0,233,3, + 4,0,0,0,114,5,0,0,0,114,196,0,0,0,234,3, 0,0,115,2,0,0,0,0,1,122,27,95,78,97,109,101, 115,112,97,99,101,76,111,97,100,101,114,46,103,101,116,95, 115,111,117,114,99,101,99,2,0,0,0,0,0,0,0,2, @@ -1836,7 +1836,7 @@ 60,115,116,114,105,110,103,62,114,183,0,0,0,114,198,0, 0,0,84,41,1,114,199,0,0,0,41,2,114,100,0,0, 0,114,119,0,0,0,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,181,0,0,0,236,3,0,0,115,2, + 114,5,0,0,0,114,181,0,0,0,237,3,0,0,115,2, 0,0,0,0,1,122,25,95,78,97,109,101,115,112,97,99, 101,76,111,97,100,101,114,46,103,101,116,95,99,111,100,101, 99,2,0,0,0,0,0,0,0,2,0,0,0,1,0,0, @@ -1846,14 +1846,14 @@ 108,101,32,99,114,101,97,116,105,111,110,46,78,114,4,0, 0,0,41,2,114,100,0,0,0,114,158,0,0,0,114,4, 0,0,0,114,4,0,0,0,114,5,0,0,0,114,180,0, - 0,0,239,3,0,0,115,0,0,0,0,122,30,95,78,97, + 0,0,240,3,0,0,115,0,0,0,0,122,30,95,78,97, 109,101,115,112,97,99,101,76,111,97,100,101,114,46,99,114, 101,97,116,101,95,109,111,100,117,108,101,99,2,0,0,0, 0,0,0,0,2,0,0,0,1,0,0,0,67,0,0,0, 115,4,0,0,0,100,0,0,83,41,1,78,114,4,0,0, 0,41,2,114,100,0,0,0,114,184,0,0,0,114,4,0, 0,0,114,4,0,0,0,114,5,0,0,0,114,185,0,0, - 0,242,3,0,0,115,2,0,0,0,0,1,122,28,95,78, + 0,243,3,0,0,115,2,0,0,0,0,1,122,28,95,78, 97,109,101,115,112,97,99,101,76,111,97,100,101,114,46,101, 120,101,99,95,109,111,100,117,108,101,99,2,0,0,0,0, 0,0,0,2,0,0,0,3,0,0,0,67,0,0,0,115, @@ -1871,7 +1871,7 @@ 32,123,33,114,125,41,4,114,114,0,0,0,114,129,0,0, 0,114,226,0,0,0,114,186,0,0,0,41,2,114,100,0, 0,0,114,119,0,0,0,114,4,0,0,0,114,4,0,0, - 0,114,5,0,0,0,114,187,0,0,0,245,3,0,0,115, + 0,114,5,0,0,0,114,187,0,0,0,246,3,0,0,115, 6,0,0,0,0,7,9,1,10,1,122,28,95,78,97,109, 101,115,112,97,99,101,76,111,97,100,101,114,46,108,111,97, 100,95,109,111,100,117,108,101,78,41,12,114,105,0,0,0, @@ -1880,7 +1880,7 @@ 0,0,0,114,181,0,0,0,114,180,0,0,0,114,185,0, 0,0,114,187,0,0,0,114,4,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,5,0,0,0,114,241,0,0,0, - 217,3,0,0,115,16,0,0,0,12,1,12,3,18,9,12, + 218,3,0,0,115,16,0,0,0,12,1,12,3,18,9,12, 3,12,3,12,3,12,3,12,3,114,241,0,0,0,99,0, 0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,64, 0,0,0,115,160,0,0,0,101,0,0,90,1,0,100,0, @@ -1917,7 +1917,7 @@ 101,114,95,99,97,99,104,101,218,6,118,97,108,117,101,115, 114,108,0,0,0,114,244,0,0,0,41,2,114,164,0,0, 0,218,6,102,105,110,100,101,114,114,4,0,0,0,114,4, - 0,0,0,114,5,0,0,0,114,244,0,0,0,7,4,0, + 0,0,0,114,5,0,0,0,114,244,0,0,0,8,4,0, 0,115,6,0,0,0,0,4,22,1,15,1,122,28,80,97, 116,104,70,105,110,100,101,114,46,105,110,118,97,108,105,100, 97,116,101,95,99,97,99,104,101,115,99,2,0,0,0,0, @@ -1943,7 +1943,7 @@ 114,99,0,0,0,41,3,114,164,0,0,0,114,35,0,0, 0,90,4,104,111,111,107,114,4,0,0,0,114,4,0,0, 0,114,5,0,0,0,218,11,95,112,97,116,104,95,104,111, - 111,107,115,15,4,0,0,115,16,0,0,0,0,7,25,1, + 111,107,115,16,4,0,0,115,16,0,0,0,0,7,25,1, 16,1,16,1,3,1,14,1,13,1,12,2,122,22,80,97, 116,104,70,105,110,100,101,114,46,95,112,97,116,104,95,104, 111,111,107,115,99,2,0,0,0,0,0,0,0,3,0,0, @@ -1975,7 +1975,7 @@ 0,0,0,114,249,0,0,0,41,3,114,164,0,0,0,114, 35,0,0,0,114,247,0,0,0,114,4,0,0,0,114,4, 0,0,0,114,5,0,0,0,218,20,95,112,97,116,104,95, - 105,109,112,111,114,116,101,114,95,99,97,99,104,101,32,4, + 105,109,112,111,114,116,101,114,95,99,97,99,104,101,33,4, 0,0,115,22,0,0,0,0,8,12,1,3,1,16,1,13, 3,9,1,3,1,17,1,13,1,15,1,18,1,122,31,80, 97,116,104,70,105,110,100,101,114,46,95,112,97,116,104,95, @@ -1995,7 +1995,7 @@ 0,0,0,114,119,0,0,0,114,247,0,0,0,114,120,0, 0,0,114,121,0,0,0,114,158,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,5,0,0,0,218,16,95,108,101, - 103,97,99,121,95,103,101,116,95,115,112,101,99,54,4,0, + 103,97,99,121,95,103,101,116,95,115,112,101,99,55,4,0, 0,115,18,0,0,0,0,4,15,1,24,2,15,1,6,1, 12,1,16,1,18,1,9,1,122,27,80,97,116,104,70,105, 110,100,101,114,46,95,108,101,103,97,99,121,95,103,101,116, @@ -2031,7 +2031,7 @@ 109,101,115,112,97,99,101,95,112,97,116,104,90,5,101,110, 116,114,121,114,247,0,0,0,114,158,0,0,0,114,121,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,218,9,95,103,101,116,95,115,112,101,99,69,4,0,0, + 0,218,9,95,103,101,116,95,115,112,101,99,70,4,0,0, 115,40,0,0,0,0,5,6,1,13,1,21,1,3,1,15, 1,12,1,15,1,21,2,18,1,12,1,3,1,15,1,4, 1,9,1,12,1,12,5,17,2,18,1,9,1,122,20,80, @@ -2059,7 +2059,7 @@ 41,6,114,164,0,0,0,114,119,0,0,0,114,35,0,0, 0,114,174,0,0,0,114,158,0,0,0,114,254,0,0,0, 114,4,0,0,0,114,4,0,0,0,114,5,0,0,0,114, - 175,0,0,0,101,4,0,0,115,26,0,0,0,0,4,12, + 175,0,0,0,102,4,0,0,115,26,0,0,0,0,4,12, 1,9,1,21,1,12,1,4,1,15,1,9,1,6,3,9, 1,24,1,4,2,7,2,122,20,80,97,116,104,70,105,110, 100,101,114,46,102,105,110,100,95,115,112,101,99,99,3,0, @@ -2081,7 +2081,7 @@ 2,114,175,0,0,0,114,120,0,0,0,41,4,114,164,0, 0,0,114,119,0,0,0,114,35,0,0,0,114,158,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,176,0,0,0,123,4,0,0,115,8,0,0,0,0,8, + 114,176,0,0,0,124,4,0,0,115,8,0,0,0,0,8, 18,1,12,1,4,1,122,22,80,97,116,104,70,105,110,100, 101,114,46,102,105,110,100,95,109,111,100,117,108,101,41,12, 114,105,0,0,0,114,104,0,0,0,114,106,0,0,0,114, @@ -2089,7 +2089,7 @@ 0,0,0,114,251,0,0,0,114,252,0,0,0,114,255,0, 0,0,114,175,0,0,0,114,176,0,0,0,114,4,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,243,0,0,0,3,4,0,0,115,22,0,0,0,12,2, + 114,243,0,0,0,4,4,0,0,115,22,0,0,0,12,2, 6,2,18,8,18,17,18,22,18,15,3,1,18,31,3,1, 21,21,3,1,114,243,0,0,0,99,0,0,0,0,0,0, 0,0,0,0,0,0,3,0,0,0,64,0,0,0,115,133, @@ -2138,7 +2138,7 @@ 2,0,86,1,113,3,0,100,0,0,83,41,1,78,114,4, 0,0,0,41,2,114,22,0,0,0,114,219,0,0,0,41, 1,114,120,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,221,0,0,0,152,4,0,0,115,2,0,0,0,6,0, + 114,221,0,0,0,153,4,0,0,115,2,0,0,0,6,0, 122,38,70,105,108,101,70,105,110,100,101,114,46,95,95,105, 110,105,116,95,95,46,60,108,111,99,97,108,115,62,46,60, 103,101,110,101,120,112,114,62,114,58,0,0,0,114,29,0, @@ -2151,7 +2151,7 @@ 108,111,97,100,101,114,95,100,101,116,97,105,108,115,90,7, 108,111,97,100,101,114,115,114,160,0,0,0,114,4,0,0, 0,41,1,114,120,0,0,0,114,5,0,0,0,114,179,0, - 0,0,146,4,0,0,115,16,0,0,0,0,4,6,1,19, + 0,0,147,4,0,0,115,16,0,0,0,0,4,6,1,19, 1,36,1,9,2,15,1,9,1,12,1,122,19,70,105,108, 101,70,105,110,100,101,114,46,95,95,105,110,105,116,95,95, 99,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0, @@ -2161,7 +2161,7 @@ 111,114,121,32,109,116,105,109,101,46,114,29,0,0,0,78, 114,87,0,0,0,41,1,114,2,1,0,0,41,1,114,100, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,5,0, - 0,0,114,244,0,0,0,160,4,0,0,115,2,0,0,0, + 0,0,114,244,0,0,0,161,4,0,0,115,2,0,0,0, 0,2,122,28,70,105,108,101,70,105,110,100,101,114,46,105, 110,118,97,108,105,100,97,116,101,95,99,97,99,104,101,115, 99,2,0,0,0,0,0,0,0,3,0,0,0,2,0,0, @@ -2185,7 +2185,7 @@ 3,114,175,0,0,0,114,120,0,0,0,114,150,0,0,0, 41,3,114,100,0,0,0,114,119,0,0,0,114,158,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,117,0,0,0,166,4,0,0,115,8,0,0,0,0,7, + 114,117,0,0,0,167,4,0,0,115,8,0,0,0,0,7, 15,1,12,1,10,1,122,22,70,105,108,101,70,105,110,100, 101,114,46,102,105,110,100,95,108,111,97,100,101,114,99,6, 0,0,0,0,0,0,0,7,0,0,0,7,0,0,0,67, @@ -2196,7 +2196,7 @@ 161,0,0,0,41,7,114,100,0,0,0,114,159,0,0,0, 114,119,0,0,0,114,35,0,0,0,90,4,115,109,115,108, 114,174,0,0,0,114,120,0,0,0,114,4,0,0,0,114, - 4,0,0,0,114,5,0,0,0,114,255,0,0,0,178,4, + 4,0,0,0,114,5,0,0,0,114,255,0,0,0,179,4, 0,0,115,6,0,0,0,0,1,15,1,18,1,122,20,70, 105,108,101,70,105,110,100,101,114,46,95,103,101,116,95,115, 112,101,99,78,99,3,0,0,0,0,0,0,0,14,0,0, @@ -2260,7 +2260,7 @@ 0,0,90,13,105,110,105,116,95,102,105,108,101,110,97,109, 101,90,9,102,117,108,108,95,112,97,116,104,114,158,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,175,0,0,0,183,4,0,0,115,70,0,0,0,0,3, + 114,175,0,0,0,184,4,0,0,115,70,0,0,0,0,3, 6,1,19,1,3,1,34,1,13,1,11,1,15,1,10,1, 9,2,9,1,9,1,15,2,9,1,6,2,12,1,18,1, 22,1,10,1,15,1,12,1,32,4,12,2,22,1,22,1, @@ -2296,7 +2296,7 @@ 0,106,0,0,131,0,0,146,2,0,113,6,0,83,114,4, 0,0,0,41,1,114,88,0,0,0,41,2,114,22,0,0, 0,90,2,102,110,114,4,0,0,0,114,4,0,0,0,114, - 5,0,0,0,250,9,60,115,101,116,99,111,109,112,62,2, + 5,0,0,0,250,9,60,115,101,116,99,111,109,112,62,3, 5,0,0,115,2,0,0,0,9,0,122,41,70,105,108,101, 70,105,110,100,101,114,46,95,102,105,108,108,95,99,97,99, 104,101,46,60,108,111,99,97,108,115,62,46,60,115,101,116, @@ -2314,7 +2314,7 @@ 0,0,0,114,98,0,0,0,114,231,0,0,0,114,219,0, 0,0,90,8,110,101,119,95,110,97,109,101,114,4,0,0, 0,114,4,0,0,0,114,5,0,0,0,114,7,1,0,0, - 229,4,0,0,115,34,0,0,0,0,2,9,1,3,1,31, + 230,4,0,0,115,34,0,0,0,0,2,9,1,3,1,31, 1,22,3,11,3,18,1,18,7,9,1,13,1,24,1,6, 1,27,2,6,1,17,1,9,1,18,1,122,22,70,105,108, 101,70,105,110,100,101,114,46,95,102,105,108,108,95,99,97, @@ -2352,7 +2352,7 @@ 0,0,0,114,99,0,0,0,41,1,114,35,0,0,0,41, 2,114,164,0,0,0,114,6,1,0,0,114,4,0,0,0, 114,5,0,0,0,218,24,112,97,116,104,95,104,111,111,107, - 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,14, + 95,102,111,114,95,70,105,108,101,70,105,110,100,101,114,15, 5,0,0,115,6,0,0,0,0,2,12,1,18,1,122,54, 70,105,108,101,70,105,110,100,101,114,46,112,97,116,104,95, 104,111,111,107,46,60,108,111,99,97,108,115,62,46,112,97, @@ -2360,7 +2360,7 @@ 70,105,110,100,101,114,114,4,0,0,0,41,3,114,164,0, 0,0,114,6,1,0,0,114,12,1,0,0,114,4,0,0, 0,41,2,114,164,0,0,0,114,6,1,0,0,114,5,0, - 0,0,218,9,112,97,116,104,95,104,111,111,107,4,5,0, + 0,0,218,9,112,97,116,104,95,104,111,111,107,5,5,0, 0,115,4,0,0,0,0,10,21,6,122,20,70,105,108,101, 70,105,110,100,101,114,46,112,97,116,104,95,104,111,111,107, 99,1,0,0,0,0,0,0,0,1,0,0,0,2,0,0, @@ -2369,7 +2369,7 @@ 105,108,101,70,105,110,100,101,114,40,123,33,114,125,41,41, 2,114,47,0,0,0,114,35,0,0,0,41,1,114,100,0, 0,0,114,4,0,0,0,114,4,0,0,0,114,5,0,0, - 0,114,238,0,0,0,22,5,0,0,115,2,0,0,0,0, + 0,114,238,0,0,0,23,5,0,0,115,2,0,0,0,0, 1,122,19,70,105,108,101,70,105,110,100,101,114,46,95,95, 114,101,112,114,95,95,41,15,114,105,0,0,0,114,104,0, 0,0,114,106,0,0,0,114,107,0,0,0,114,179,0,0, @@ -2377,7 +2377,7 @@ 114,117,0,0,0,114,255,0,0,0,114,175,0,0,0,114, 7,1,0,0,114,177,0,0,0,114,13,1,0,0,114,238, 0,0,0,114,4,0,0,0,114,4,0,0,0,114,4,0, - 0,0,114,5,0,0,0,114,0,1,0,0,137,4,0,0, + 0,0,114,5,0,0,0,114,0,1,0,0,138,4,0,0, 115,20,0,0,0,12,7,6,2,12,14,12,4,6,2,12, 12,12,5,15,46,12,31,18,18,114,0,1,0,0,99,4, 0,0,0,0,0,0,0,6,0,0,0,11,0,0,0,67, @@ -2403,7 +2403,7 @@ 90,8,112,97,116,104,110,97,109,101,90,9,99,112,97,116, 104,110,97,109,101,114,120,0,0,0,114,158,0,0,0,114, 4,0,0,0,114,4,0,0,0,114,5,0,0,0,218,14, - 95,102,105,120,95,117,112,95,109,111,100,117,108,101,28,5, + 95,102,105,120,95,117,112,95,109,111,100,117,108,101,29,5, 0,0,115,34,0,0,0,0,2,15,1,15,1,6,1,6, 1,12,1,12,1,18,2,15,1,6,1,21,1,3,1,10, 1,10,1,10,1,14,1,13,2,114,18,1,0,0,99,0, @@ -2424,7 +2424,7 @@ 0,114,74,0,0,0,41,3,90,10,101,120,116,101,110,115, 105,111,110,115,90,6,115,111,117,114,99,101,90,8,98,121, 116,101,99,111,100,101,114,4,0,0,0,114,4,0,0,0, - 114,5,0,0,0,114,155,0,0,0,51,5,0,0,115,8, + 114,5,0,0,0,114,155,0,0,0,52,5,0,0,115,8, 0,0,0,0,5,18,1,12,1,12,1,114,155,0,0,0, 99,1,0,0,0,0,0,0,0,12,0,0,0,12,0,0, 0,67,0,0,0,115,70,2,0,0,124,0,0,97,0,0, @@ -2486,7 +2486,7 @@ 3,0,100,1,0,83,41,2,114,29,0,0,0,78,41,1, 114,31,0,0,0,41,2,114,22,0,0,0,114,77,0,0, 0,114,4,0,0,0,114,4,0,0,0,114,5,0,0,0, - 114,221,0,0,0,87,5,0,0,115,2,0,0,0,6,0, + 114,221,0,0,0,88,5,0,0,115,2,0,0,0,6,0, 122,25,95,115,101,116,117,112,46,60,108,111,99,97,108,115, 62,46,60,103,101,110,101,120,112,114,62,114,59,0,0,0, 122,30,105,109,112,111,114,116,108,105,98,32,114,101,113,117, @@ -2516,7 +2516,7 @@ 111,100,117,108,101,90,14,119,101,97,107,114,101,102,95,109, 111,100,117,108,101,90,13,119,105,110,114,101,103,95,109,111, 100,117,108,101,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,6,95,115,101,116,117,112,62,5,0,0,115, + 0,0,0,218,6,95,115,101,116,117,112,63,5,0,0,115, 82,0,0,0,0,8,6,1,9,1,9,3,13,1,13,1, 15,1,18,2,13,1,20,3,33,1,19,2,31,1,10,1, 15,1,13,1,4,2,3,1,15,1,5,1,13,1,12,2, @@ -2542,7 +2542,7 @@ 114,243,0,0,0,114,212,0,0,0,41,2,114,26,1,0, 0,90,17,115,117,112,112,111,114,116,101,100,95,108,111,97, 100,101,114,115,114,4,0,0,0,114,4,0,0,0,114,5, - 0,0,0,218,8,95,105,110,115,116,97,108,108,130,5,0, + 0,0,0,218,8,95,105,110,115,116,97,108,108,131,5,0, 0,115,16,0,0,0,0,2,10,1,9,1,28,1,15,1, 16,1,16,4,9,1,114,29,1,0,0,41,3,122,3,119, 105,110,114,1,0,0,0,114,2,0,0,0,41,56,114,107, @@ -2571,7 +2571,7 @@ 0,0,0,114,4,0,0,0,114,5,0,0,0,218,8,60, 109,111,100,117,108,101,62,8,0,0,0,115,98,0,0,0, 6,17,6,3,12,12,12,5,12,5,12,6,12,12,12,10, - 12,9,12,5,12,7,15,22,15,110,22,1,18,2,6,1, + 12,9,12,5,12,7,15,22,15,111,22,1,18,2,6,1, 6,2,9,2,9,2,10,2,21,44,12,33,12,19,12,12, 12,12,12,28,12,17,21,55,21,12,18,10,12,14,9,3, 12,1,15,65,19,64,19,28,22,110,19,41,25,45,25,16, diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -154,7 +154,7 @@ &&TARGET_BUILD_TUPLE_UNPACK, &&TARGET_BUILD_SET_UNPACK, &&TARGET_SETUP_ASYNC_WITH, - &&_unknown_opcode, + &&TARGET_FORMAT_VALUE, &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 3 13:09:17 2015 From: python-checkins at python.org (eric.smith) Date: Tue, 03 Nov 2015 18:09:17 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_25483=3A_Update_dis?= =?utf-8?q?=2Erst_with_FORMAT=5FVALUE_opcode_description=2E?= Message-ID: <20151103180917.10560.5788@psf.io> https://hg.python.org/cpython/rev/4734713a31ed changeset: 98946:4734713a31ed user: Eric V. Smith date: Tue Nov 03 13:09:01 2015 -0500 summary: Issue 25483: Update dis.rst with FORMAT_VALUE opcode description. files: Doc/library/dis.rst | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -989,6 +989,25 @@ arguments. +.. opcode:: FORMAT_VALUE (flags) + + Used for implementing formatted literal strings (f-strings). Pops + an optional *fmt_spec* from the stack, then a required *value*. + *flags* is interpreted as follows: + + * ``(flags & 0x03) == 0x00``: *value* is formattedd as-is. + * ``(flags & 0x03) == 0x01``: call :func:`str` on *value* before + formatting it. + * ``(flags & 0x03) == 0x02``: call :func:`repr` on *value* before + formatting it. + * ``(flags & 0x03) == 0x03``: call :func:`ascii` on *value* before + formatting it. + * ``(flags & 0x04) == 0x04``: pop *fmt_spec* from the stack and use + it, else use an empty *fmt_spec*. + + Formatting is performed using the :c:func:`PyObject_Format` function. + + .. opcode:: HAVE_ARGUMENT This is not really an opcode. It identifies the dividing line between -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 3 16:30:52 2015 From: python-checkins at python.org (eric.smith) Date: Tue, 03 Nov 2015 21:30:52 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_25483=3A_Fix_doc_typ?= =?utf-8?q?o_and_added_versionadded=2E_Thanks=2C_Berker_Peksag=2E?= Message-ID: <20151103213049.18108.5523@psf.io> https://hg.python.org/cpython/rev/93fd7adbc7dd changeset: 98947:93fd7adbc7dd user: Eric V. Smith date: Tue Nov 03 16:30:49 2015 -0500 summary: Issue 25483: Fix doc typo and added versionadded. Thanks, Berker Peksag. files: Doc/library/dis.rst | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -995,7 +995,7 @@ an optional *fmt_spec* from the stack, then a required *value*. *flags* is interpreted as follows: - * ``(flags & 0x03) == 0x00``: *value* is formattedd as-is. + * ``(flags & 0x03) == 0x00``: *value* is formatted as-is. * ``(flags & 0x03) == 0x01``: call :func:`str` on *value* before formatting it. * ``(flags & 0x03) == 0x02``: call :func:`repr` on *value* before @@ -1007,6 +1007,8 @@ Formatting is performed using the :c:func:`PyObject_Format` function. + .. versionadded:: 3.6 + .. opcode:: HAVE_ARGUMENT -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 3 22:00:30 2015 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 04 Nov 2015 03:00:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Neaten-up_the_inner-loop_l?= =?utf-8?q?ogic=2E?= Message-ID: <20151104030029.108157.951@psf.io> https://hg.python.org/cpython/rev/aba28afc5732 changeset: 98948:aba28afc5732 user: Raymond Hettinger date: Tue Nov 03 22:00:26 2015 -0500 summary: Neaten-up the inner-loop logic. files: Modules/_collectionsmodule.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1053,13 +1053,13 @@ } } - n = stop - i; - while (n--) { + n = stop - i + 1; + while (--n) { CHECK_NOT_END(b); item = b->data[index]; cmp = PyObject_RichCompareBool(item, v, Py_EQ); if (cmp > 0) - return PyLong_FromSsize_t(stop - (n + 1)); + return PyLong_FromSsize_t(stop - n); if (cmp < 0) return NULL; if (start_state != deque->state) { -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:07 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:07 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_link_to_modern?= =?utf-8?q?_PUG_url?= Message-ID: <20151104064407.8986.73131@psf.io> https://hg.python.org/cpython/rev/759fa4e89339 changeset: 98951:759fa4e89339 branch: 3.4 parent: 98941:193327cabbbc user: Benjamin Peterson date: Tue Nov 03 22:42:02 2015 -0800 summary: link to modern PUG url files: Doc/distutils/index.rst | 7 +++---- Doc/install/index.rst | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -15,10 +15,9 @@ .. note:: This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third - party tools offer easier to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,17 +27,17 @@ .. note:: - - This guide only covers the basic tools for installing extensions that are - provided as part of this version of Python. Third party tools offer easier - to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. .. _inst-intro: + Introduction ============ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:07 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:07 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E4?= Message-ID: <20151104064407.3582.27628@psf.io> https://hg.python.org/cpython/rev/34864daee5f1 changeset: 98952:34864daee5f1 branch: 3.5 parent: 98942:e2400d5d67e7 parent: 98951:759fa4e89339 user: Benjamin Peterson date: Tue Nov 03 22:42:35 2015 -0800 summary: merge 3.4 files: Doc/distutils/index.rst | 7 +++---- Doc/install/index.rst | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -15,10 +15,9 @@ .. note:: This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third - party tools offer easier to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,17 +27,17 @@ .. note:: - - This guide only covers the basic tools for installing extensions that are - provided as part of this version of Python. Third party tools offer easier - to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. .. _inst-intro: + Introduction ============ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:08 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:08 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_link_to_modern?= =?utf-8?q?_PUG_url?= Message-ID: <20151104064406.112383.26636@psf.io> https://hg.python.org/cpython/rev/18121aa6a937 changeset: 98949:18121aa6a937 branch: 2.7 parent: 98905:4ed175ee3cca user: Benjamin Peterson date: Tue Nov 03 22:42:02 2015 -0800 summary: link to modern PUG url files: Doc/distutils/index.rst | 7 +++---- Doc/install/index.rst | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -15,10 +15,9 @@ .. note:: This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third - party tools offer easier to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,17 +27,17 @@ .. note:: - - This guide only covers the basic tools for installing extensions that are - provided as part of this version of Python. Third party tools offer easier - to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. .. _inst-intro: + Introduction ============ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:08 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:08 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf-8?q?_merge_heads?= Message-ID: <20151104064406.36339.76329@psf.io> https://hg.python.org/cpython/rev/02ce8fb89494 changeset: 98950:02ce8fb89494 branch: 2.7 parent: 98949:18121aa6a937 parent: 98940:e8f3c011e2b4 user: Benjamin Peterson date: Tue Nov 03 22:42:08 2015 -0800 summary: merge heads files: Doc/distutils/packageindex.rst | 2 +- Doc/howto/descriptor.rst | 2 +- Doc/install/index.rst | 2 +- Doc/library/email.parser.rst | 2 +- Doc/library/unittest.rst | 2 +- Doc/library/zlib.rst | 2 +- Doc/whatsnew/2.7.rst | 2 +- Include/unicodeobject.h | 2 +- Lib/cookielib.py | 2 +- Lib/ctypes/test/test_random_things.py | 2 +- Lib/lib-tk/Tkinter.py | 2 +- Lib/lib2to3/fixes/fix_metaclass.py | 2 +- Lib/test/regrtest.py | 2 +- Lib/test/test_dict.py | 2 +- Lib/test/test_io.py | 2 +- Lib/test/test_userdict.py | 2 +- Misc/HISTORY | 2 +- Misc/NEWS | 2 +- Modules/_ssl.c | 2 +- Modules/itertoolsmodule.c | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Doc/distutils/packageindex.rst b/Doc/distutils/packageindex.rst --- a/Doc/distutils/packageindex.rst +++ b/Doc/distutils/packageindex.rst @@ -169,7 +169,7 @@ username: password: -The *distutils* section defines a *index-servers* variable that lists the +The *distutils* section defines an *index-servers* variable that lists the name of all sections describing a repository. Each section describing a repository defines three variables: diff --git a/Doc/howto/descriptor.rst b/Doc/howto/descriptor.rst --- a/Doc/howto/descriptor.rst +++ b/Doc/howto/descriptor.rst @@ -325,7 +325,7 @@ patterns of binding functions into methods. To recap, functions have a :meth:`__get__` method so that they can be converted -to a method when accessed as attributes. The non-data descriptor transforms a +to a method when accessed as attributes. The non-data descriptor transforms an ``obj.f(*args)`` call into ``f(obj, *args)``. Calling ``klass.f(*args)`` becomes ``f(*args)``. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -149,7 +149,7 @@ On Windows, you'd probably download :file:`foo-1.0.zip`. If you downloaded the archive file to :file:`C:\\Temp`, then it would unpack into -:file:`C:\\Temp\\foo-1.0`; you can use either a archive manipulator with a +:file:`C:\\Temp\\foo-1.0`; you can use either an archive manipulator with a graphical user interface (such as WinZip) or a command-line tool (such as :program:`unzip` or :program:`pkunzip`) to unpack the archive. Then, open a command prompt window and run:: diff --git a/Doc/library/email.parser.rst b/Doc/library/email.parser.rst --- a/Doc/library/email.parser.rst +++ b/Doc/library/email.parser.rst @@ -133,7 +133,7 @@ methods on file-like objects. The text contained in *fp* must be formatted as a block of :rfc:`2822` - style headers and header continuation lines, optionally preceded by a + style headers and header continuation lines, optionally preceded by an envelope header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). diff --git a/Doc/library/unittest.rst b/Doc/library/unittest.rst --- a/Doc/library/unittest.rst +++ b/Doc/library/unittest.rst @@ -568,7 +568,7 @@ .. versionadded:: 2.7 Unittest supports skipping individual test methods and even whole classes of -tests. In addition, it supports marking a test as a "expected failure," a test +tests. In addition, it supports marking a test as an "expected failure," a test that is broken and will fail, but shouldn't be counted as a failure on a :class:`TestResult`. diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -31,7 +31,7 @@ .. function:: adler32(data[, value]) - Computes a Adler-32 checksum of *data*. (An Adler-32 checksum is almost as + Computes an Adler-32 checksum of *data*. (An Adler-32 checksum is almost as reliable as a CRC32 but can be computed much more quickly.) If *value* is present, it is used as the starting value of the checksum; otherwise, a fixed default value is used. This allows computing a running checksum over the diff --git a/Doc/whatsnew/2.7.rst b/Doc/whatsnew/2.7.rst --- a/Doc/whatsnew/2.7.rst +++ b/Doc/whatsnew/2.7.rst @@ -1118,7 +1118,7 @@ (Fixed by Daniel Stutzbach; :issue:`8729`.) * Constructors for the parsing classes in the :mod:`ConfigParser` module now - take a *allow_no_value* parameter, defaulting to false; if true, + take an *allow_no_value* parameter, defaulting to false; if true, options without values will be allowed. For example:: >>> import ConfigParser, StringIO diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1307,7 +1307,7 @@ int op /* Operation: Py_EQ, Py_NE, Py_GT, etc. */ ); -/* Apply a argument tuple or dictionary to a format string and return +/* Apply an argument tuple or dictionary to a format string and return the resulting Unicode string. */ PyAPI_FUNC(PyObject *) PyUnicode_Format( diff --git a/Lib/cookielib.py b/Lib/cookielib.py --- a/Lib/cookielib.py +++ b/Lib/cookielib.py @@ -1434,7 +1434,7 @@ break # convert RFC 2965 Max-Age to seconds since epoch # XXX Strictly you're supposed to follow RFC 2616 - # age-calculation rules. Remember that zero Max-Age is a + # age-calculation rules. Remember that zero Max-Age # is a request to discard (old and new) cookie, though. k = "expires" v = self._now + v diff --git a/Lib/ctypes/test/test_random_things.py b/Lib/ctypes/test/test_random_things.py --- a/Lib/ctypes/test/test_random_things.py +++ b/Lib/ctypes/test/test_random_things.py @@ -30,7 +30,7 @@ # value is printed correctly. # # Changed in 0.9.3: No longer is '(in callback)' prepended to the - # error message - instead a additional frame for the C code is + # error message - instead an additional frame for the C code is # created, then a full traceback printed. When SystemExit is # raised in a callback function, the interpreter exits. diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py --- a/Lib/lib-tk/Tkinter.py +++ b/Lib/lib-tk/Tkinter.py @@ -1117,7 +1117,7 @@ return self._bind(('bind', className), sequence, func, add, 0) def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + """Unbind for all widgets with bindtag CLASSNAME for event SEQUENCE all functions.""" self.tk.call('bind', className , sequence, '') def mainloop(self, n=0): diff --git a/Lib/lib2to3/fixes/fix_metaclass.py b/Lib/lib2to3/fixes/fix_metaclass.py --- a/Lib/lib2to3/fixes/fix_metaclass.py +++ b/Lib/lib2to3/fixes/fix_metaclass.py @@ -114,7 +114,7 @@ left_node = expr_node.children[0] if isinstance(left_node, Leaf) and \ left_node.value == u'__metaclass__': - # We found a assignment to __metaclass__. + # We found an assignment to __metaclass__. fixup_simple_stmt(node, i, simple_node) remove_trailing_newline(simple_node) yield (node, i, simple_node) diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -62,7 +62,7 @@ Additional Option Details: --r randomizes test execution order. You can use --randseed=int to provide a +-r randomizes test execution order. You can use --randseed=int to provide an int seed value for the randomizer; this is useful for reproducing troublesome test orders. diff --git a/Lib/test/test_dict.py b/Lib/test/test_dict.py --- a/Lib/test/test_dict.py +++ b/Lib/test/test_dict.py @@ -448,7 +448,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(dict): def __missing__(self, key): return 42 diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -15,7 +15,7 @@ ################################################################################ # When writing tests for io, it's important to test both the C and Python # implementations. This is usually done by writing a base test that refers to -# the type it is testing as a attribute. Then it provides custom subclasses to +# the type it is testing as an attribute. Then it provides custom subclasses to # test both implementations. This file has lots of examples. ################################################################################ diff --git a/Lib/test/test_userdict.py b/Lib/test/test_userdict.py --- a/Lib/test/test_userdict.py +++ b/Lib/test/test_userdict.py @@ -188,7 +188,7 @@ # (D) subclass defines __missing__ method returning a value # (E) subclass defines __missing__ method raising RuntimeError # (F) subclass sets __missing__ instance variable (no effect) - # (G) subclass doesn't define __missing__ at a all + # (G) subclass doesn't define __missing__ at all class D(UserDict.UserDict): def __missing__(self, key): return 42 diff --git a/Misc/HISTORY b/Misc/HISTORY --- a/Misc/HISTORY +++ b/Misc/HISTORY @@ -1495,7 +1495,7 @@ - Bug #1194181: bz2.BZ2File didn't handle mode 'U' correctly. -- Patch #1212117: os.stat().st_flags is now accessible as a attribute +- Patch #1212117: os.stat().st_flags is now accessible as an attribute if available on the platform. - Patch #1103951: Expose O_SHLOCK and O_EXLOCK in the posix module if diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -936,7 +936,7 @@ Changes are written to HOME/.idlerc/config-extensions.cfg. Original patch by Tal Einat. -- Issue #16233: A module browser (File : Class Browser, Alt+C) requires a +- Issue #16233: A module browser (File : Class Browser, Alt+C) requires an editor window with a filename. When Class Browser is requested otherwise, from a shell, output window, or 'Untitled' editor, Idle no longer displays an error box. It now pops up an Open Module box (Alt+M). If a valid name diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2788,7 +2788,7 @@ cadata_ascii = PyUnicode_AsASCIIString(cadata); if (cadata_ascii == NULL) { PyErr_SetString(PyExc_TypeError, - "cadata should be a ASCII string or a " + "cadata should be an ASCII string or a " "bytes-like object"); goto error; } diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -1410,7 +1410,7 @@ "starmap(function, sequence) --> starmap object\n\ \n\ Return an iterator whose values are returned from the function evaluated\n\ -with a argument tuple taken from the given sequence."); +with an argument tuple taken from the given sequence."); static PyTypeObject starmap_type = { PyVarObject_HEAD_INIT(NULL, 0) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:10 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41?= Message-ID: <20151104064407.57627.13240@psf.io> https://hg.python.org/cpython/rev/eafd2bc7edde changeset: 98953:eafd2bc7edde parent: 98948:aba28afc5732 parent: 98952:34864daee5f1 user: Benjamin Peterson date: Tue Nov 03 22:42:42 2015 -0800 summary: merge 3.5 files: Doc/distutils/index.rst | 7 +++---- Doc/install/index.rst | 12 ++++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Doc/distutils/index.rst b/Doc/distutils/index.rst --- a/Doc/distutils/index.rst +++ b/Doc/distutils/index.rst @@ -15,10 +15,9 @@ .. note:: This guide only covers the basic tools for building and distributing - extensions that are provided as part of this version of Python. Third - party tools offer easier to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,17 +27,17 @@ .. note:: - - This guide only covers the basic tools for installing extensions that are - provided as part of this version of Python. Third party tools offer easier - to use and more secure alternatives. Refer to the - `quick recommendations section - `__ + + This guide only covers the basic tools for building and distributing + extensions that are provided as part of this version of Python. Third party + tools offer easier to use and more secure alternatives. Refer to the `quick + recommendations section `__ in the Python Packaging User Guide for more information. .. _inst-intro: + Introduction ============ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:12 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_remove_trailin?= =?utf-8?q?g_ws?= Message-ID: <20151104064412.17092.6837@psf.io> https://hg.python.org/cpython/rev/d4b68ac6c4ea changeset: 98954:d4b68ac6c4ea branch: 2.7 parent: 98950:02ce8fb89494 user: Benjamin Peterson date: Tue Nov 03 22:43:31 2015 -0800 summary: remove trailing ws files: Doc/install/index.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,7 +27,7 @@ .. note:: - + This guide only covers the basic tools for building and distributing extensions that are provided as part of this version of Python. Third party tools offer easier to use and more secure alternatives. Refer to the `quick -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:12 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_remove_trailin?= =?utf-8?q?g_ws?= Message-ID: <20151104064412.36339.76993@psf.io> https://hg.python.org/cpython/rev/030abe093847 changeset: 98955:030abe093847 branch: 3.4 parent: 98951:759fa4e89339 user: Benjamin Peterson date: Tue Nov 03 22:43:31 2015 -0800 summary: remove trailing ws files: Doc/install/index.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,7 +27,7 @@ .. note:: - + This guide only covers the basic tools for building and distributing extensions that are provided as part of this version of Python. Third party tools offer easier to use and more secure alternatives. Refer to the `quick -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:12 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E4?= Message-ID: <20151104064412.9432.23172@psf.io> https://hg.python.org/cpython/rev/ebc546e8bc98 changeset: 98956:ebc546e8bc98 branch: 3.5 parent: 98952:34864daee5f1 parent: 98955:030abe093847 user: Benjamin Peterson date: Tue Nov 03 22:43:41 2015 -0800 summary: merge 3.4 files: Doc/install/index.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,7 +27,7 @@ .. note:: - + This guide only covers the basic tools for building and distributing extensions that are provided as part of this version of Python. Third party tools offer easier to use and more secure alternatives. Refer to the `quick -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 01:44:13 2015 From: python-checkins at python.org (benjamin.peterson) Date: Wed, 04 Nov 2015 06:44:13 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41?= Message-ID: <20151104064412.36331.60266@psf.io> https://hg.python.org/cpython/rev/3f7d559d5f8a changeset: 98957:3f7d559d5f8a parent: 98953:eafd2bc7edde parent: 98956:ebc546e8bc98 user: Benjamin Peterson date: Tue Nov 03 22:43:52 2015 -0800 summary: merge 3.5 files: Doc/install/index.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/install/index.rst b/Doc/install/index.rst --- a/Doc/install/index.rst +++ b/Doc/install/index.rst @@ -27,7 +27,7 @@ .. note:: - + This guide only covers the basic tools for building and distributing extensions that are provided as part of this version of Python. Third party tools offer easier to use and more secure alternatives. Refer to the `quick -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 03:04:19 2015 From: python-checkins at python.org (victor.stinner) Date: Wed, 04 Nov 2015 08:04:19 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_regrtest=3A_display_progre?= =?utf-8?q?ss_every_30_seconds_=28instead_of_60_seconds=29_when?= Message-ID: <20151104080418.108153.96778@psf.io> https://hg.python.org/cpython/rev/53f2a1d311cd changeset: 98958:53f2a1d311cd user: Victor Stinner date: Wed Nov 04 09:03:53 2015 +0100 summary: regrtest: display progress every 30 seconds (instead of 60 seconds) when running tests in multiprocessing mode (-jN). files: Lib/test/libregrtest/runtest_mp.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -21,7 +21,7 @@ PROGRESS_MIN_TIME = 30.0 # seconds # Display the running tests if nothing happened last N seconds -PROGRESS_UPDATE = 60.0 # seconds +PROGRESS_UPDATE = 30.0 # seconds def run_test_in_subprocess(testname, ns): -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Wed Nov 4 03:45:03 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 04 Nov 2015 08:45:03 +0000 Subject: [Python-checkins] Daily reference leaks (aba28afc5732): sum=7 Message-ID: <20151104084502.57605.45963@psf.io> results for aba28afc5732 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogMvuXlN', '--timeout', '7200'] From python-checkins at python.org Wed Nov 4 07:11:20 2015 From: python-checkins at python.org (eric.smith) Date: Wed, 04 Nov 2015 12:11:20 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_For_FORMAT=5FVALUE_opcode?= =?utf-8?q?=2C_make_it_clear_that_the_result_of_PyObject=5FFormat_is?= Message-ID: <20151104121120.108161.17067@psf.io> https://hg.python.org/cpython/rev/7674e41d5c7e changeset: 98959:7674e41d5c7e user: Eric V. Smith date: Wed Nov 04 07:11:13 2015 -0500 summary: For FORMAT_VALUE opcode, make it clear that the result of PyObject_Format is pushed on the stack. files: Doc/library/dis.rst | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1005,7 +1005,8 @@ * ``(flags & 0x04) == 0x04``: pop *fmt_spec* from the stack and use it, else use an empty *fmt_spec*. - Formatting is performed using the :c:func:`PyObject_Format` function. + Formatting is performed using :c:func:`PyObject_Format`. The + result is pushed on the stack. .. versionadded:: 3.6 -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Wed Nov 4 08:49:55 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 4 Nov 2015 13:49:55 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-04 Message-ID: <675b657e-efe6-4557-b965-3832513b902d@irsmsx152.ger.corp.intel.com> Results for project Python default, build date 2015-11-04 08:46:18 +0000 commit: 53f2a1d311cd10adf35f2b13194df6e344a556e3 revision date: 2015-11-04 08:03:53 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.18% -1.65% 6.63% 17.21% :-( pybench 0.15% -0.53% -2.84% 9.41% :-( regex_v8 2.74% -1.04% -5.48% 7.35% :-| nbody 0.18% 1.55% -0.07% 8.39% :-| json_dump_v2 0.29% 1.54% -0.74% 9.48% :-| normal_startup 0.64% -0.07% 0.27% 5.07% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Wed Nov 4 08:50:46 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 4 Nov 2015 13:50:46 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-04 Message-ID: Results for project Python 2.7, build date 2015-11-04 09:36:31 +0000 commit: d4b68ac6c4eaf51dd06a339a16f188737199c78e revision date: 2015-11-04 06:43:31 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.14% -0.70% 2.59% 10.39% :-) pybench 0.18% -0.16% 6.46% 6.92% :-| regex_v8 0.58% -0.23% -1.79% 6.98% :-) nbody 0.19% -0.19% 8.64% 3.89% :-) json_dump_v2 0.24% -0.19% 2.35% 13.39% :-| normal_startup 1.76% -0.05% -1.70% 3.00% :-| ssbench 1.40% 1.44% 1.34% -0.21% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Wed Nov 4 15:34:03 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:34:03 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDQ5?= =?utf-8?q?=3A_Iterating_OrderedDict_with_keys_with_unstable_hash_now_rais?= =?utf-8?q?es?= Message-ID: <20151104203403.9014.27632@psf.io> https://hg.python.org/cpython/rev/499398d91b97 changeset: 98960:499398d91b97 branch: 3.5 parent: 98956:ebc546e8bc98 user: Serhiy Storchaka date: Wed Nov 04 22:05:38 2015 +0200 summary: Issue #25449: Iterating OrderedDict with keys with unstable hash now raises KeyError in C implementations as well as in Python implementation. Added tests for OrderedDict subclasses. files: Lib/test/test_collections.py | 144 +++++++++++++--------- Misc/NEWS | 5 + Objects/odictobject.c | 2 + 3 files changed, 90 insertions(+), 61 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1641,7 +1641,7 @@ class OrderedDictTests: def test_init(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1665,7 +1665,7 @@ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) def test_update(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict().update([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1711,7 +1711,7 @@ self.assertRaises(TypeError, OrderedDict.update) def test_fromkeys(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) od = OrderedDict.fromkeys('abc', value=None) @@ -1720,12 +1720,12 @@ self.assertEqual(list(od.items()), [(c, 0) for c in 'abc']) def test_abc(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict self.assertIsInstance(OrderedDict(), MutableMapping) self.assertTrue(issubclass(OrderedDict, MutableMapping)) def test_clear(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1734,7 +1734,7 @@ self.assertEqual(len(od), 0) def test_delitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) del od['a'] @@ -1744,7 +1744,7 @@ self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) def test_setitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) od['c'] = 10 # existing element od['f'] = 20 # new element @@ -1752,7 +1752,7 @@ [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) def test_iterators(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1769,7 +1769,7 @@ self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) def test_detect_deletion_during_iteration(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') it = iter(od) key = next(it) @@ -1780,7 +1780,7 @@ next(it) def test_sorted_iterators(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict([('a', 1), ('b', 2)], None) pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1793,7 +1793,7 @@ sorted([t[0] for t in reversed(pairs)])) def test_iterators_empty(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() empty = [] self.assertEqual(list(od), empty) @@ -1806,7 +1806,7 @@ self.assertEqual(list(reversed(od.items())), empty) def test_popitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1817,7 +1817,7 @@ self.assertEqual(len(od), 0) def test_popitem_last(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [(i, i) for i in range(30)] obj = OrderedDict(pairs) @@ -1828,7 +1828,7 @@ self.assertEqual(len(obj), 20) def test_pop(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1854,7 +1854,7 @@ m.pop('a') def test_equality(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od1 = OrderedDict(pairs) @@ -1870,7 +1870,7 @@ self.assertNotEqual(od1, OrderedDict(pairs[:-1])) def test_copying(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Check that ordered dicts are copyable, deepcopyable, picklable, # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1897,7 +1897,7 @@ check(OrderedDict(od)) def test_yaml_linkage(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. # In yaml, lists are native but tuples are not. pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1907,7 +1907,7 @@ self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) def test_reduce_not_too_fat(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # do not save instance dictionary if not needed pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) @@ -1916,7 +1916,7 @@ self.assertIsNotNone(od.__reduce__()[2]) def test_pickle_recursive(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() od[1] = od @@ -1929,7 +1929,7 @@ self.assertIs(dup[1], dup) def test_repr(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) self.assertEqual(repr(od), "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") @@ -1937,7 +1937,7 @@ self.assertEqual(repr(OrderedDict()), "OrderedDict()") def test_repr_recursive(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # See issue #9826 od = OrderedDict.fromkeys('abc') od['x'] = od @@ -1945,7 +1945,7 @@ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") def test_setdefault(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1965,7 +1965,7 @@ self.assertEqual(Missing().setdefault(5, 9), 9) def test_reinsert(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Given insert a, insert b, delete a, re-insert a, # verify that a is now later than b. od = OrderedDict() @@ -1977,7 +1977,7 @@ self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) def test_move_to_end(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abcde') self.assertEqual(list(od), list('abcde')) od.move_to_end('c') @@ -1996,7 +1996,7 @@ od.move_to_end('x', 0) def test_move_to_end_issue25406(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') od.move_to_end('c', last=False) self.assertEqual(list(od), list('cab')) @@ -2010,14 +2010,14 @@ self.assertEqual(list(od), list('bac')) def test_sizeof(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Wimpy test: Just verify the reported size is larger than a regular dict d = dict(a=1) od = OrderedDict(**d) self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) def test_override_update(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Verify that subclasses can override update() without breaking __init__() class MyOD(OrderedDict): def update(self, *args, **kwds): @@ -2027,7 +2027,7 @@ def test_highly_nested(self): # Issue 25395: crashes during garbage collection - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict obj = None for _ in range(1000): obj = OrderedDict([(None, obj)]) @@ -2036,7 +2036,7 @@ def test_highly_nested_subclass(self): # Issue 25395: crashes during garbage collection - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict deleted = [] class MyOD(OrderedDict): def __del__(self): @@ -2049,19 +2049,8 @@ support.gc_collect() self.assertEqual(deleted, list(reversed(range(100)))) - -class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = py_coll - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = c_coll - def test_delitem_hash_collision(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __init__(self, hash): @@ -2099,25 +2088,8 @@ del od[colliding] self.assertEqual(list(od.items()), [(key, ...), ('after', ...)]) - def test_key_change_during_iteration(self): - OrderedDict = self.module.OrderedDict - - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - with self.assertRaises(RuntimeError): - for i, k in enumerate(od): - od.move_to_end(k) - self.assertLess(i, 5) - with self.assertRaises(RuntimeError): - for k in od: - od['f'] = None - with self.assertRaises(RuntimeError): - for k in od: - del od['c'] - self.assertEqual(list(od), list('bdeaf')) - def test_issue24347(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __hash__(self): @@ -2130,12 +2102,16 @@ # These should not crash. with self.assertRaises(KeyError): + list(od.values()) + with self.assertRaises(KeyError): + list(od.items()) + with self.assertRaises(KeyError): repr(od) with self.assertRaises(KeyError): od.copy() def test_issue24348(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __hash__(self): @@ -2158,7 +2134,7 @@ that we will keep the size of the odict the same at each popitem call. This verifies that we handled the dict resize properly. """ - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() for c0 in '0123456789ABCDEF': @@ -2170,6 +2146,50 @@ od[key] = key +class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = py_coll + OrderedDict = py_coll.OrderedDict + + + at unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = c_coll + OrderedDict = c_coll.OrderedDict + + def test_key_change_during_iteration(self): + OrderedDict = self.OrderedDict + + od = OrderedDict.fromkeys('abcde') + self.assertEqual(list(od), list('abcde')) + with self.assertRaises(RuntimeError): + for i, k in enumerate(od): + od.move_to_end(k) + self.assertLess(i, 5) + with self.assertRaises(RuntimeError): + for k in od: + od['f'] = None + with self.assertRaises(RuntimeError): + for k in od: + del od['c'] + self.assertEqual(list(od), list('bdeaf')) + + +class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests): + + module = py_coll + class OrderedDict(py_coll.OrderedDict): + pass + + +class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests): + + module = c_coll + class OrderedDict(c_coll.OrderedDict): + pass + + class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): @classmethod @@ -2231,6 +2251,8 @@ test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs, TestCounter, TestChainMap, PurePythonOrderedDictTests, CPythonOrderedDictTests, + PurePythonOrderedDictSubclassTests, + CPythonOrderedDictSubclassTests, PurePythonGeneralMappingTests, CPythonGeneralMappingTests, PurePythonSubclassMappingTests, CPythonSubclassMappingTests, TestUserObjects, diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises + KeyError in C implementations as well as in Python implementation. + - Issue #25395: Fixed crash when highly nested OrderedDict structures were garbage collected. @@ -333,6 +336,8 @@ Tests ----- +- Issue #25449: Added tests for OrderedDict subclasses. + - Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1789,6 +1789,8 @@ /* Get the key. */ node = _odict_find_node(di->di_odict, di->di_current); if (node == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, di->di_current); /* Must have been deleted. */ Py_CLEAR(di->di_current); return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 15:34:03 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:34:03 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDQ5?= =?utf-8?q?=3A_Fixed_a_crash_and_leaking_NULL_in_repr=28=29_of_OrderedDict?= =?utf-8?q?_that?= Message-ID: <20151104203403.9450.16378@psf.io> https://hg.python.org/cpython/rev/59c7615ea921 changeset: 98962:59c7615ea921 branch: 3.5 parent: 98960:499398d91b97 user: Serhiy Storchaka date: Wed Nov 04 22:33:07 2015 +0200 summary: Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. files: Lib/test/test_collections.py | 54 ++++++++++++++++++++++++ Misc/NEWS | 3 + Objects/odictobject.c | 15 +++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -2145,6 +2145,60 @@ key = c0 + c1 od[key] = key + # Direct use of dict methods + + def test_dict_setitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + dict.__setitem__(od, 'spam', 1) + self.assertNotIn('NULL', repr(od)) + + def test_dict_delitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.__delitem__(od, 'spam') + with self.assertRaises(KeyError): + repr(od) + + def test_dict_clear(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.clear(od) + self.assertNotIn('NULL', repr(od)) + + def test_dict_pop(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.pop(od, 'spam') + with self.assertRaises(KeyError): + repr(od) + + def test_dict_popitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.popitem(od) + with self.assertRaises(KeyError): + repr(od) + + def test_dict_setdefault(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + dict.setdefault(od, 'spam', 1) + self.assertNotIn('NULL', repr(od)) + + def test_dict_update(self): + od = OrderedDict() + dict.update(od, [('spam', 1)]) + self.assertNotIn('NULL', repr(od)) + class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that + was mutated by direct calls of dict methods. + - Issue #25449: Iterating OrderedDict with keys with unstable hash now raises KeyError in C implementations as well as in Python implementation. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1462,7 +1462,6 @@ { int i; _Py_IDENTIFIER(items); - Py_ssize_t count = -1; PyObject *pieces = NULL, *result = NULL; const char *classname; @@ -1481,6 +1480,7 @@ } if (PyODict_CheckExact(self)) { + Py_ssize_t count = 0; _ODictNode *node; pieces = PyList_New(PyODict_SIZE(self)); if (pieces == NULL) @@ -1499,8 +1499,19 @@ if (pair == NULL) goto Done; - PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */ + if (count < PyList_GET_SIZE(pieces)) + PyList_SET_ITEM(pieces, count, pair); /* steals reference */ + else { + if (PyList_Append(pieces, pair) < 0) { + Py_DECREF(pair); + goto Done; + } + Py_DECREF(pair); + } + count++; } + if (count < PyList_GET_SIZE(pieces)) + PyList_GET_SIZE(pieces) = count; } else { PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 15:34:03 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:34:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325449=3A_Fixed_a_crash_and_leaking_NULL_in_repr?= =?utf-8?q?=28=29_of_OrderedDict_that?= Message-ID: <20151104203403.17075.71742@psf.io> https://hg.python.org/cpython/rev/76e848554b5d changeset: 98963:76e848554b5d parent: 98961:9db4191723eb parent: 98962:59c7615ea921 user: Serhiy Storchaka date: Wed Nov 04 22:33:33 2015 +0200 summary: Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. files: Lib/test/test_collections.py | 54 ++++++++++++++++++++++++ Misc/NEWS | 3 + Objects/odictobject.c | 15 +++++- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -2153,6 +2153,60 @@ key = c0 + c1 od[key] = key + # Direct use of dict methods + + def test_dict_setitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + dict.__setitem__(od, 'spam', 1) + self.assertNotIn('NULL', repr(od)) + + def test_dict_delitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.__delitem__(od, 'spam') + with self.assertRaises(KeyError): + repr(od) + + def test_dict_clear(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.clear(od) + self.assertNotIn('NULL', repr(od)) + + def test_dict_pop(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.pop(od, 'spam') + with self.assertRaises(KeyError): + repr(od) + + def test_dict_popitem(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + od['spam'] = 1 + od['ham'] = 2 + dict.popitem(od) + with self.assertRaises(KeyError): + repr(od) + + def test_dict_setdefault(self): + OrderedDict = self.OrderedDict + od = OrderedDict() + dict.setdefault(od, 'spam', 1) + self.assertNotIn('NULL', repr(od)) + + def test_dict_update(self): + od = OrderedDict() + dict.update(od, [('spam', 1)]) + self.assertNotIn('NULL', repr(od)) + class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that + was mutated by direct calls of dict methods. + - Issue #25449: Iterating OrderedDict with keys with unstable hash now raises KeyError in C implementations as well as in Python implementation. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1462,7 +1462,6 @@ { int i; _Py_IDENTIFIER(items); - Py_ssize_t count = -1; PyObject *pieces = NULL, *result = NULL; const char *classname; @@ -1481,6 +1480,7 @@ } if (PyODict_CheckExact(self)) { + Py_ssize_t count = 0; _ODictNode *node; pieces = PyList_New(PyODict_SIZE(self)); if (pieces == NULL) @@ -1499,8 +1499,19 @@ if (pair == NULL) goto Done; - PyList_SET_ITEM(pieces, ++count, pair); /* steals reference */ + if (count < PyList_GET_SIZE(pieces)) + PyList_SET_ITEM(pieces, count, pair); /* steals reference */ + else { + if (PyList_Append(pieces, pair) < 0) { + Py_DECREF(pair); + goto Done; + } + Py_DECREF(pair); + } + count++; } + if (count < PyList_GET_SIZE(pieces)) + PyList_GET_SIZE(pieces) = count; } else { PyObject *items = _PyObject_CallMethodIdObjArgs((PyObject *)self, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 15:34:09 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:34:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325449=3A_Iterating_OrderedDict_with_keys_with_u?= =?utf-8?q?nstable_hash_now_raises?= Message-ID: <20151104203403.112367.18833@psf.io> https://hg.python.org/cpython/rev/9db4191723eb changeset: 98961:9db4191723eb parent: 98959:7674e41d5c7e parent: 98960:499398d91b97 user: Serhiy Storchaka date: Wed Nov 04 22:08:52 2015 +0200 summary: Issue #25449: Iterating OrderedDict with keys with unstable hash now raises KeyError in C implementations as well as in Python implementation. Added tests for OrderedDict subclasses. files: Lib/test/test_collections.py | 146 +++++++++++++--------- Misc/NEWS | 5 + Objects/odictobject.c | 2 + 3 files changed, 91 insertions(+), 62 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1641,7 +1641,7 @@ class OrderedDictTests: def test_init(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1665,7 +1665,7 @@ [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) def test_update(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict().update([('a', 1), ('b', 2)], None) # too many args pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1711,7 +1711,7 @@ self.assertRaises(TypeError, OrderedDict.update) def test_fromkeys(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) od = OrderedDict.fromkeys('abc', value=None) @@ -1720,12 +1720,12 @@ self.assertEqual(list(od.items()), [(c, 0) for c in 'abc']) def test_abc(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict self.assertIsInstance(OrderedDict(), MutableMapping) self.assertTrue(issubclass(OrderedDict, MutableMapping)) def test_clear(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1734,7 +1734,7 @@ self.assertEqual(len(od), 0) def test_delitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) del od['a'] @@ -1744,7 +1744,7 @@ self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) def test_setitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) od['c'] = 10 # existing element od['f'] = 20 # new element @@ -1752,7 +1752,7 @@ [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) def test_iterators(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1769,7 +1769,7 @@ self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) def test_detect_deletion_during_iteration(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') it = iter(od) key = next(it) @@ -1780,7 +1780,7 @@ next(it) def test_sorted_iterators(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict with self.assertRaises(TypeError): OrderedDict([('a', 1), ('b', 2)], None) pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] @@ -1793,7 +1793,7 @@ sorted([t[0] for t in reversed(pairs)])) def test_iterators_empty(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() empty = [] self.assertEqual(list(od), empty) @@ -1806,7 +1806,7 @@ self.assertEqual(list(reversed(od.items())), empty) def test_popitem(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1817,7 +1817,7 @@ self.assertEqual(len(od), 0) def test_popitem_last(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [(i, i) for i in range(30)] obj = OrderedDict(pairs) @@ -1828,7 +1828,7 @@ self.assertEqual(len(obj), 20) def test_pop(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1854,7 +1854,7 @@ m.pop('a') def test_equality(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od1 = OrderedDict(pairs) @@ -1870,7 +1870,7 @@ self.assertNotEqual(od1, OrderedDict(pairs[:-1])) def test_copying(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Check that ordered dicts are copyable, deepcopyable, picklable, # and have a repr/eval round-trip pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1897,7 +1897,7 @@ check(OrderedDict(od)) def test_yaml_linkage(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. # In yaml, lists are native but tuples are not. pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] @@ -1907,7 +1907,7 @@ self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) def test_reduce_not_too_fat(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # do not save instance dictionary if not needed pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] od = OrderedDict(pairs) @@ -1916,7 +1916,7 @@ self.assertIsNotNone(od.__reduce__()[2]) def test_pickle_recursive(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() od[1] = od @@ -1929,7 +1929,7 @@ self.assertIs(dup[1], dup) def test_repr(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) self.assertEqual(repr(od), "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") @@ -1937,7 +1937,7 @@ self.assertEqual(repr(OrderedDict()), "OrderedDict()") def test_repr_recursive(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # See issue #9826 od = OrderedDict.fromkeys('abc') od['x'] = od @@ -1945,7 +1945,7 @@ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") def test_setdefault(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] shuffle(pairs) od = OrderedDict(pairs) @@ -1965,7 +1965,7 @@ self.assertEqual(Missing().setdefault(5, 9), 9) def test_reinsert(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Given insert a, insert b, delete a, re-insert a, # verify that a is now later than b. od = OrderedDict() @@ -1977,7 +1977,7 @@ self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) def test_move_to_end(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abcde') self.assertEqual(list(od), list('abcde')) od.move_to_end('c') @@ -1996,7 +1996,7 @@ od.move_to_end('x', 0) def test_move_to_end_issue25406(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict.fromkeys('abc') od.move_to_end('c', last=False) self.assertEqual(list(od), list('cab')) @@ -2010,14 +2010,14 @@ self.assertEqual(list(od), list('bac')) def test_sizeof(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Wimpy test: Just verify the reported size is larger than a regular dict d = dict(a=1) od = OrderedDict(**d) self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) def test_views(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # See http://bugs.python.org/issue24286 s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split() od = OrderedDict.fromkeys(s) @@ -2025,7 +2025,7 @@ self.assertEqual(od.items(), dict(od).items()) def test_override_update(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict # Verify that subclasses can override update() without breaking __init__() class MyOD(OrderedDict): def update(self, *args, **kwds): @@ -2035,7 +2035,7 @@ def test_highly_nested(self): # Issue 25395: crashes during garbage collection - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict obj = None for _ in range(1000): obj = OrderedDict([(None, obj)]) @@ -2044,7 +2044,7 @@ def test_highly_nested_subclass(self): # Issue 25395: crashes during garbage collection - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict deleted = [] class MyOD(OrderedDict): def __del__(self): @@ -2057,19 +2057,8 @@ support.gc_collect() self.assertEqual(deleted, list(reversed(range(100)))) - -class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = py_coll - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = c_coll - def test_delitem_hash_collision(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __init__(self, hash): @@ -2107,25 +2096,8 @@ del od[colliding] self.assertEqual(list(od.items()), [(key, ...), ('after', ...)]) - def test_key_change_during_iteration(self): - OrderedDict = self.module.OrderedDict - - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - with self.assertRaises(RuntimeError): - for i, k in enumerate(od): - od.move_to_end(k) - self.assertLess(i, 5) - with self.assertRaises(RuntimeError): - for k in od: - od['f'] = None - with self.assertRaises(RuntimeError): - for k in od: - del od['c'] - self.assertEqual(list(od), list('bdeaf')) - def test_issue24347(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __hash__(self): @@ -2138,12 +2110,16 @@ # These should not crash. with self.assertRaises(KeyError): + list(od.values()) + with self.assertRaises(KeyError): + list(od.items()) + with self.assertRaises(KeyError): repr(od) with self.assertRaises(KeyError): od.copy() def test_issue24348(self): - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict class Key: def __hash__(self): @@ -2166,7 +2142,7 @@ that we will keep the size of the odict the same at each popitem call. This verifies that we handled the dict resize properly. """ - OrderedDict = self.module.OrderedDict + OrderedDict = self.OrderedDict od = OrderedDict() for c0 in '0123456789ABCDEF': @@ -2178,6 +2154,50 @@ od[key] = key +class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = py_coll + OrderedDict = py_coll.OrderedDict + + + at unittest.skipUnless(c_coll, 'requires the C version of the collections module') +class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): + + module = c_coll + OrderedDict = c_coll.OrderedDict + + def test_key_change_during_iteration(self): + OrderedDict = self.OrderedDict + + od = OrderedDict.fromkeys('abcde') + self.assertEqual(list(od), list('abcde')) + with self.assertRaises(RuntimeError): + for i, k in enumerate(od): + od.move_to_end(k) + self.assertLess(i, 5) + with self.assertRaises(RuntimeError): + for k in od: + od['f'] = None + with self.assertRaises(RuntimeError): + for k in od: + del od['c'] + self.assertEqual(list(od), list('bdeaf')) + + +class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests): + + module = py_coll + class OrderedDict(py_coll.OrderedDict): + pass + + +class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests): + + module = c_coll + class OrderedDict(c_coll.OrderedDict): + pass + + class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): @classmethod @@ -2239,6 +2259,8 @@ test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs, TestCounter, TestChainMap, PurePythonOrderedDictTests, CPythonOrderedDictTests, + PurePythonOrderedDictSubclassTests, + CPythonOrderedDictSubclassTests, PurePythonGeneralMappingTests, CPythonGeneralMappingTests, PurePythonSubclassMappingTests, CPythonSubclassMappingTests, TestUserObjects, diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25449: Iterating OrderedDict with keys with unstable hash now raises + KeyError in C implementations as well as in Python implementation. + - Issue #25395: Fixed crash when highly nested OrderedDict structures were garbage collected. @@ -298,6 +301,8 @@ Tests ----- +- Issue #25449: Added tests for OrderedDict subclasses. + - Issue #25188: Add -P/--pgo to test.regrtest to suppress error output when running the test suite for the purposes of a PGO build. Initial patch by Alecsandru Patrascu. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1789,6 +1789,8 @@ /* Get the key. */ node = _odict_find_node(di->di_odict, di->di_current); if (node == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, di->di_current); /* Must have been deleted. */ Py_CLEAR(di->di_current); return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 15:39:03 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:39:03 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI0NzI2?= =?utf-8?q?=3A_Fixed_issue_number_for_previous_changeset_59c7615ea921=2E?= Message-ID: <20151104203903.101543.6291@psf.io> https://hg.python.org/cpython/rev/88d97cd99d16 changeset: 98964:88d97cd99d16 branch: 3.5 parent: 98962:59c7615ea921 user: Serhiy Storchaka date: Wed Nov 04 22:37:46 2015 +0200 summary: Issue #24726: Fixed issue number for previous changeset 59c7615ea921. files: Misc/NEWS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,7 +11,7 @@ Core and Builtins ----------------- -- Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that +- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. - Issue #25449: Iterating OrderedDict with keys with unstable hash now raises -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 15:39:03 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 04 Nov 2015 20:39:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324726=3A_Fixed_issue_number_for_previous_change?= =?utf-8?q?set_76e848554b5d=2E?= Message-ID: <20151104203903.2003.79572@psf.io> https://hg.python.org/cpython/rev/965109e81ffa changeset: 98965:965109e81ffa parent: 98963:76e848554b5d parent: 98964:88d97cd99d16 user: Serhiy Storchaka date: Wed Nov 04 22:38:40 2015 +0200 summary: Issue #24726: Fixed issue number for previous changeset 76e848554b5d. files: Misc/NEWS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,7 +10,7 @@ Core and Builtins ----------------- -- Issue #25449: Fixed a crash and leaking NULL in repr() of OrderedDict that +- Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. - Issue #25449: Iterating OrderedDict with keys with unstable hash now raises -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 4 23:10:38 2015 From: python-checkins at python.org (larry.hastings) Date: Thu, 05 Nov 2015 04:10:38 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_Add_schedule_for_3=2E5=2E1_re?= =?utf-8?q?leases=2E?= Message-ID: <20151105041038.9438.71233@psf.io> https://hg.python.org/peps/rev/4c7172052ed3 changeset: 6126:4c7172052ed3 user: Larry Hastings date: Wed Nov 04 20:10:34 2015 -0800 summary: Add schedule for 3.5.1 releases. files: pep-0478.txt | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/pep-0478.txt b/pep-0478.txt --- a/pep-0478.txt +++ b/pep-0478.txt @@ -48,10 +48,12 @@ - 3.5.0 release candidate 1: August 10, 2015 - 3.5.0 release candidate 2: August 25, 2015 - 3.5.0 release candidate 3: September 7, 2015 +- 3.5.0 final: September 13, 2015 Planned future release dates: -- 3.5.0 final: September 13, 2015 +- 3.5.1 release candidate 1: November 22, 2015 +- 3.5.1 final: December 6, 2015 Features for 3.5 -- Repository URL: https://hg.python.org/peps From solipsis at pitrou.net Thu Nov 5 03:45:48 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 05 Nov 2015 08:45:48 +0000 Subject: [Python-checkins] Daily reference leaks (965109e81ffa): sum=7 Message-ID: <20151105084548.9434.18979@psf.io> results for 965109e81ffa on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogPXR1yM', '--timeout', '7200'] From python-checkins at python.org Thu Nov 5 05:22:33 2015 From: python-checkins at python.org (victor.stinner) Date: Thu, 05 Nov 2015 10:22:33 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_sysmodule=2Ec=3A_reuse_Py?= =?utf-8?q?=5FSTRINGIFY=28=29_macro?= Message-ID: <20151105102233.108147.42276@psf.io> https://hg.python.org/cpython/rev/8ade9d907f31 changeset: 98966:8ade9d907f31 user: Victor Stinner date: Thu Nov 05 11:21:38 2015 +0100 summary: sysmodule.c: reuse Py_STRINGIFY() macro files: Python/sysmodule.c | 8 ++------ 1 files changed, 2 insertions(+), 6 deletions(-) diff --git a/Python/sysmodule.c b/Python/sysmodule.c --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1643,15 +1643,11 @@ /* sys.implementation values */ #define NAME "cpython" const char *_PySys_ImplName = NAME; -#define QUOTE(arg) #arg -#define STRIFY(name) QUOTE(name) -#define MAJOR STRIFY(PY_MAJOR_VERSION) -#define MINOR STRIFY(PY_MINOR_VERSION) +#define MAJOR Py_STRINGIFY(PY_MAJOR_VERSION) +#define MINOR Py_STRINGIFY(PY_MINOR_VERSION) #define TAG NAME "-" MAJOR MINOR const char *_PySys_ImplCacheTag = TAG; #undef NAME -#undef QUOTE -#undef STRIFY #undef MAJOR #undef MINOR #undef TAG -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 08:02:23 2015 From: python-checkins at python.org (victor.stinner) Date: Thu, 05 Nov 2015 13:02:23 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151105130217.112385.1850@psf.io> https://hg.python.org/cpython/rev/3261fb7fa17b changeset: 98968:3261fb7fa17b parent: 98966:8ade9d907f31 parent: 98967:1e87bcf20707 user: Victor Stinner date: Thu Nov 05 13:55:43 2015 +0100 summary: Merge 3.5 files: Python/ceval.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2363,6 +2363,10 @@ /* Slow-path if globals or builtins is not a dict */ v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { + if (!PyErr_ExceptionMatches(PyExc_KeyError)) + goto error; + PyErr_Clear(); + v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyError)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 08:02:17 2015 From: python-checkins at python.org (victor.stinner) Date: Thu, 05 Nov 2015 13:02:17 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325556=3A_Add_asse?= =?utf-8?q?rtions_to_PyObject=5FGetItem=28=29_to_ensure_that_an_exception?= Message-ID: <20151105130217.17067.7239@psf.io> https://hg.python.org/cpython/rev/c1414f80ebc9 changeset: 98969:c1414f80ebc9 user: Victor Stinner date: Thu Nov 05 13:56:58 2015 +0100 summary: Issue #25556: Add assertions to PyObject_GetItem() to ensure that an exception is raised when it returns NULL. Simplify also ceval.c: rely on the fact that PyObject_GetItem() raised an exception when it returns NULL. files: Objects/abstract.c | 11 ++++++++--- Python/ceval.c | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -141,8 +141,11 @@ return null_error(); m = o->ob_type->tp_as_mapping; - if (m && m->mp_subscript) - return m->mp_subscript(o, key); + if (m && m->mp_subscript) { + PyObject *item = m->mp_subscript(o, key); + assert((item != NULL) ^ (PyErr_Occurred() != NULL)); + return item; + } if (o->ob_type->tp_as_sequence) { if (PyIndex_Check(key)) { @@ -1526,8 +1529,10 @@ if (i < 0) { if (m->sq_length) { Py_ssize_t l = (*m->sq_length)(s); - if (l < 0) + if (l < 0) { + assert(PyErr_Occurred()); return NULL; + } i += l; } } diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2307,7 +2307,7 @@ } else { v = PyObject_GetItem(locals, name); - if (v == NULL && _PyErr_OCCURRED()) { + if (v == NULL) { if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error; PyErr_Clear(); @@ -2426,7 +2426,7 @@ } else { value = PyObject_GetItem(locals, name); - if (value == NULL && PyErr_Occurred()) { + if (value == NULL) { if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error; PyErr_Clear(); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 08:02:22 2015 From: python-checkins at python.org (victor.stinner) Date: Thu, 05 Nov 2015 13:02:22 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTU2?= =?utf-8?q?=3A_Fix_LOAD=5FGLOBAL_bytecode_when_globals_type_is_not_dict_an?= =?utf-8?q?d_the?= Message-ID: <20151105130217.101543.49026@psf.io> https://hg.python.org/cpython/rev/1e87bcf20707 changeset: 98967:1e87bcf20707 branch: 3.5 parent: 98964:88d97cd99d16 user: Victor Stinner date: Thu Nov 05 13:55:20 2015 +0100 summary: Issue #25556: Fix LOAD_GLOBAL bytecode when globals type is not dict and the requested name doesn't exist in globals: clear the KeyError exception before calling PyObject_GetItem(). Fail also if the raised exception is not a KeyError. files: Python/ceval.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2363,6 +2363,10 @@ /* Slow-path if globals or builtins is not a dict */ v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { + if (!PyErr_ExceptionMatches(PyExc_KeyError)) + goto error; + PyErr_Clear(); + v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyError)) -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Thu Nov 5 09:33:42 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 5 Nov 2015 14:33:42 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-05 Message-ID: Results for project Python default, build date 2015-11-05 04:02:59 +0000 commit: 965109e81ffa568d9687976bcf90cd28ef77d6bb revision date: 2015-11-04 20:38:40 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.27% 0.14% 6.76% 17.75% :-( pybench 0.10% 0.41% -2.42% 9.60% :-( regex_v8 2.68% 0.00% -5.47% 4.16% :-| nbody 0.15% -0.24% -0.31% 9.80% :-| json_dump_v2 0.24% -0.34% -1.08% 10.96% :-| normal_startup 0.88% 0.14% 0.40% 4.71% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Thu Nov 5 09:34:28 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 5 Nov 2015 14:34:28 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-05 Message-ID: <4a1fc0ce-cafd-4db3-9683-92475f1bdb3d@irsmsx104.ger.corp.intel.com> No new revisions. Here are the previous results: Results for project Python 2.7, build date 2015-11-05 04:53:04 +0000 commit: d4b68ac6c4eaf51dd06a339a16f188737199c78e revision date: 2015-11-04 06:43:31 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.14% -0.70% 2.59% 10.39% :-) pybench 0.18% -0.16% 6.46% 6.92% :-| regex_v8 0.58% -0.23% -1.79% 6.98% :-) nbody 0.19% -0.19% 8.64% 3.89% :-) json_dump_v2 0.24% -0.19% 2.35% 13.39% :-| normal_startup 1.76% -0.05% -1.70% 3.00% :-| ssbench 1.40% 1.44% 1.34% -0.21% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Thu Nov 5 10:51:39 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 05 Nov 2015 15:51:39 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Reuse_Py=5FSTRINGIFY=28=29?= =?utf-8?q?_macro_in_sre=5Flib=2Eh_and_dynload=5Fwin=2Ec=2E?= Message-ID: <20151105155139.9016.59136@psf.io> https://hg.python.org/cpython/rev/9135ff7255a1 changeset: 98970:9135ff7255a1 user: Serhiy Storchaka date: Thu Nov 05 17:43:42 2015 +0200 summary: Reuse Py_STRINGIFY() macro in sre_lib.h and dynload_win.c. files: Modules/sre_lib.h | 6 ++---- Python/dynload_win.c | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h --- a/Modules/sre_lib.h +++ b/Modules/sre_lib.h @@ -367,14 +367,12 @@ #define RETURN_ON_FAILURE(i) \ do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0) -#define SFY(x) #x - #define DATA_STACK_ALLOC(state, type, ptr) \ do { \ alloc_pos = state->data_stack_base; \ TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \ "(%" PY_FORMAT_SIZE_T "d)\n", \ - SFY(type), alloc_pos, sizeof(type))); \ + Py_STRINGIFY(type), alloc_pos, sizeof(type))); \ if (sizeof(type) > state->data_stack_size - alloc_pos) { \ int j = data_stack_grow(state, sizeof(type)); \ if (j < 0) return j; \ @@ -387,7 +385,7 @@ #define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \ do { \ - TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", SFY(type), pos)); \ + TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \ ptr = (type*)(state->data_stack+pos); \ } while (0) diff --git a/Python/dynload_win.c b/Python/dynload_win.c --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -24,12 +24,10 @@ #define PYD_DEBUG_SUFFIX "" #endif -#define STRINGIZE2(x) #x -#define STRINGIZE(x) STRINGIZE2(x) #ifdef PYD_PLATFORM_TAG -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" #else -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) ".pyd" +#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd" #endif #define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 10:51:40 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 05 Nov 2015 15:51:40 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTU0?= =?utf-8?q?=3A_Got_rid_of_circular_references_in_regular_expression_parsin?= =?utf-8?q?g=2E?= Message-ID: <20151105155139.8994.37454@psf.io> https://hg.python.org/cpython/rev/7f4fca8f13a2 changeset: 98971:7f4fca8f13a2 branch: 3.5 parent: 98967:1e87bcf20707 user: Serhiy Storchaka date: Thu Nov 05 17:49:26 2015 +0200 summary: Issue #25554: Got rid of circular references in regular expression parsing. files: Lib/sre_parse.py | 12 ++++++------ Misc/NEWS | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -70,14 +70,14 @@ def __init__(self): self.flags = 0 self.groupdict = {} - self.subpatterns = [None] # group 0 + self.groupwidths = [None] # group 0 self.lookbehindgroups = None @property def groups(self): - return len(self.subpatterns) + return len(self.groupwidths) def opengroup(self, name=None): gid = self.groups - self.subpatterns.append(None) + self.groupwidths.append(None) if self.groups > MAXGROUPS: raise error("too many groups") if name is not None: @@ -88,9 +88,9 @@ self.groupdict[name] = gid return gid def closegroup(self, gid, p): - self.subpatterns[gid] = p + self.groupwidths[gid] = p.getwidth() def checkgroup(self, gid): - return gid < self.groups and self.subpatterns[gid] is not None + return gid < self.groups and self.groupwidths[gid] is not None def checklookbehindgroup(self, gid, source): if self.lookbehindgroups is not None: @@ -195,7 +195,7 @@ lo = lo + 1 hi = hi + 1 elif op is GROUPREF: - i, j = self.pattern.subpatterns[av].getwidth() + i, j = self.pattern.groupwidths[av] lo = lo + i hi = hi + j elif op is GROUPREF_EXISTS: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -54,6 +54,8 @@ Library ------- +- Issue #25554: Got rid of circular references in regular expression parsing. + - Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 10:52:27 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 05 Nov 2015 15:52:27 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325554=3A_Got_rid_of_circular_references_in_regu?= =?utf-8?q?lar_expression_parsing=2E?= Message-ID: <20151105155140.57625.86960@psf.io> https://hg.python.org/cpython/rev/8621727dd9f7 changeset: 98972:8621727dd9f7 parent: 98970:9135ff7255a1 parent: 98971:7f4fca8f13a2 user: Serhiy Storchaka date: Thu Nov 05 17:51:15 2015 +0200 summary: Issue #25554: Got rid of circular references in regular expression parsing. files: Lib/sre_parse.py | 12 ++++++------ Misc/NEWS | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -70,14 +70,14 @@ def __init__(self): self.flags = 0 self.groupdict = {} - self.subpatterns = [None] # group 0 + self.groupwidths = [None] # group 0 self.lookbehindgroups = None @property def groups(self): - return len(self.subpatterns) + return len(self.groupwidths) def opengroup(self, name=None): gid = self.groups - self.subpatterns.append(None) + self.groupwidths.append(None) if self.groups > MAXGROUPS: raise error("too many groups") if name is not None: @@ -88,9 +88,9 @@ self.groupdict[name] = gid return gid def closegroup(self, gid, p): - self.subpatterns[gid] = p + self.groupwidths[gid] = p.getwidth() def checkgroup(self, gid): - return gid < self.groups and self.subpatterns[gid] is not None + return gid < self.groups and self.groupwidths[gid] is not None def checklookbehindgroup(self, gid, source): if self.lookbehindgroups is not None: @@ -195,7 +195,7 @@ lo = lo + 1 hi = hi + 1 elif op is GROUPREF: - i, j = self.pattern.subpatterns[av].getwidth() + i, j = self.pattern.groupwidths[av] lo = lo + i hi = hi + j elif op is GROUPREF_EXISTS: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -72,6 +72,8 @@ Library ------- +- Issue #25554: Got rid of circular references in regular expression parsing. + - Issue #18973: Command-line interface of the calendar module now uses argparse instead of optparse. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 11:28:35 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 05 Nov 2015 16:28:35 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fix_use_of_def?= =?utf-8?q?ault_reST_role?= Message-ID: <20151105162831.101529.99266@psf.io> https://hg.python.org/cpython/rev/692322517a3e changeset: 98973:692322517a3e branch: 2.7 parent: 98954:d4b68ac6c4ea user: Zachary Ware date: Thu Nov 05 10:28:18 2015 -0600 summary: Fix use of default reST role files: Doc/howto/logging-cookbook.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/howto/logging-cookbook.rst b/Doc/howto/logging-cookbook.rst --- a/Doc/howto/logging-cookbook.rst +++ b/Doc/howto/logging-cookbook.rst @@ -1320,7 +1320,7 @@ class UTCFormatter(logging.Formatter): converter = time.gmtime -and you can then use the `UTCFormatter` in your code instead of +and you can then use the ``UTCFormatter`` in your code instead of :class:`~logging.Formatter`. If you want to do that via configuration, you can use the :func:`~logging.config.dictConfig` API with an approach illustrated by the following complete example:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 14:31:01 2015 From: python-checkins at python.org (yury.selivanov) Date: Thu, 05 Nov 2015 19:31:01 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151105193100.9014.25207@psf.io> https://hg.python.org/cpython/rev/ce93a386dcb8 changeset: 98975:ce93a386dcb8 branch: 3.5 parent: 98971:7f4fca8f13a2 parent: 98974:295459bd437f user: Yury Selivanov date: Thu Nov 05 14:29:19 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/tasks.py | 4 ++ Lib/test/test_asyncio/test_tasks.py | 24 +++++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -488,6 +488,10 @@ @coroutine def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" + if delay == 0: + yield + return result + future = futures.Future(loop=loop) h = future._loop.call_later(delay, future._set_result_unless_cancelled, result) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2188,5 +2188,29 @@ self.assertEqual(context['exception'], exc_context.exception) +class SleepTests(test_utils.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def test_sleep_zero(self): + result = 0 + + def inc_result(num): + nonlocal result + result += num + + @asyncio.coroutine + def coro(): + self.loop.call_soon(inc_result, 1) + self.assertEqual(result, 0) + num = yield from asyncio.sleep(0, loop=self.loop, result=10) + self.assertEqual(result, 1) # inc'ed by call_soon + inc_result(num) # num should be 11 + + self.loop.run_until_complete(coro()) + self.assertEqual(result, 11) + + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 14:31:03 2015 From: python-checkins at python.org (yury.selivanov) Date: Thu, 05 Nov 2015 19:31:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151105193100.36333.49314@psf.io> https://hg.python.org/cpython/rev/21a28f6de358 changeset: 98976:21a28f6de358 parent: 98972:8621727dd9f7 parent: 98975:ce93a386dcb8 user: Yury Selivanov date: Thu Nov 05 14:30:41 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/tasks.py | 4 ++ Lib/test/test_asyncio/test_tasks.py | 24 +++++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -488,6 +488,10 @@ @coroutine def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" + if delay == 0: + yield + return result + future = futures.Future(loop=loop) h = future._loop.call_later(delay, future._set_result_unless_cancelled, result) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2188,5 +2188,29 @@ self.assertEqual(context['exception'], exc_context.exception) +class SleepTests(test_utils.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def test_sleep_zero(self): + result = 0 + + def inc_result(num): + nonlocal result + result += num + + @asyncio.coroutine + def coro(): + self.loop.call_soon(inc_result, 1) + self.assertEqual(result, 0) + num = yield from asyncio.sleep(0, loop=self.loop, result=10) + self.assertEqual(result, 1) # inc'ed by call_soon + inc_result(num) # num should be 11 + + self.loop.run_until_complete(coro()) + self.assertEqual(result, 11) + + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 14:31:03 2015 From: python-checkins at python.org (yury.selivanov) Date: Thu, 05 Nov 2015 19:31:03 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogT3B0?= =?utf-8?q?imize_asyncio=2Esleep=280=29?= Message-ID: <20151105193100.36323.61294@psf.io> https://hg.python.org/cpython/rev/295459bd437f changeset: 98974:295459bd437f branch: 3.4 parent: 98955:030abe093847 user: Yury Selivanov date: Thu Nov 05 14:29:04 2015 -0500 summary: asyncio: Optimize asyncio.sleep(0) files: Lib/asyncio/tasks.py | 4 ++ Lib/test/test_asyncio/test_tasks.py | 24 +++++++++++++++++ 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -488,6 +488,10 @@ @coroutine def sleep(delay, result=None, *, loop=None): """Coroutine that completes after a given time (in seconds).""" + if delay == 0: + yield + return result + future = futures.Future(loop=loop) h = future._loop.call_later(delay, future._set_result_unless_cancelled, result) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2188,5 +2188,29 @@ self.assertEqual(context['exception'], exc_context.exception) +class SleepTests(test_utils.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def test_sleep_zero(self): + result = 0 + + def inc_result(num): + nonlocal result + result += num + + @asyncio.coroutine + def coro(): + self.loop.call_soon(inc_result, 1) + self.assertEqual(result, 0) + num = yield from asyncio.sleep(0, loop=self.loop, result=10) + self.assertEqual(result, 1) # inc'ed by call_soon + inc_result(num) # num should be 11 + + self.loop.run_until_complete(coro()) + self.assertEqual(result, 11) + + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 14:42:16 2015 From: python-checkins at python.org (matthias.klose) Date: Thu, 05 Nov 2015 19:42:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEyNjEy?= =?utf-8?q?=3A_Add_some_Valgrind_suppressions_for_64-bit_machines=2E?= Message-ID: <20151105194215.108155.67496@psf.io> https://hg.python.org/cpython/rev/92dda5f00b0f changeset: 98977:92dda5f00b0f branch: 2.7 parent: 98973:692322517a3e user: doko at ubuntu.com date: Thu Nov 05 20:41:57 2015 +0100 summary: Issue #12612: Add some Valgrind suppressions for 64-bit machines. files: Misc/valgrind-python.supp | 24 ++++++++++++++++++++++++ 1 files changed, 24 insertions(+), 0 deletions(-) diff --git a/Misc/valgrind-python.supp b/Misc/valgrind-python.supp --- a/Misc/valgrind-python.supp +++ b/Misc/valgrind-python.supp @@ -137,6 +137,18 @@ ###} ### ###{ +### ADDRESS_IN_RANGE/Use of uninitialised value of size 8 +### Memcheck:Addr8 +### fun:PyObject_Free +###} +### +###{ +### ADDRESS_IN_RANGE/Use of uninitialised value of size 8 +### Memcheck:Value8 +### fun:PyObject_Free +###} +### +###{ ### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value ### Memcheck:Cond ### fun:PyObject_Free @@ -155,6 +167,18 @@ ###} ### ###{ +### ADDRESS_IN_RANGE/Use of uninitialised value of size 8 +### Memcheck:Addr8 +### fun:PyObject_Realloc +###} +### +###{ +### ADDRESS_IN_RANGE/Use of uninitialised value of size 8 +### Memcheck:Value8 +### fun:PyObject_Realloc +###} +### +###{ ### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value ### Memcheck:Cond ### fun:PyObject_Realloc -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 20:09:56 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 06 Nov 2015 01:09:56 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2318010=3A_Merge_pydoc_web_search_fix_from_3=2E5?= Message-ID: <20151106010956.9000.98902@psf.io> https://hg.python.org/cpython/rev/d86ff708f545 changeset: 98980:d86ff708f545 parent: 98976:21a28f6de358 parent: 98979:8702efa1feb4 user: Martin Panter date: Fri Nov 06 01:08:34 2015 +0000 summary: Issue #18010: Merge pydoc web search fix from 3.5 files: Lib/pydoc.py | 4 ++- Lib/test/test_pydoc.py | 38 +++++++++++++++++++++++++---- Misc/NEWS | 3 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -2370,7 +2370,9 @@ with warnings.catch_warnings(): warnings.filterwarnings('ignore') # ignore problems during import - ModuleScanner().run(callback, key) + def onerror(modname): + pass + ModuleScanner().run(callback, key, onerror=onerror) # format page def bltinlink(name): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -396,6 +396,13 @@ finally: pkgutil.walk_packages = walk_packages + def call_url_handler(self, url, expected_title): + text = pydoc._url_handler(url, "text/html") + result = get_html_title(text) + # Check the title to ensure an unexpected error page was not returned + self.assertEqual(result, expected_title, text) + return text + class PydocDocTest(unittest.TestCase): @@ -704,6 +711,29 @@ finally: os.chmod(pkgdir, current_mode) + def test_url_search_package_error(self): + # URL handler search should cope with packages that raise exceptions + pkgdir = os.path.join(TESTFN, "test_error_package") + os.mkdir(pkgdir) + init = os.path.join(pkgdir, "__init__.py") + with open(init, "wt", encoding="ascii") as f: + f.write("""raise ValueError("ouch")\n""") + with self.restrict_walk_packages(path=[TESTFN]): + # Package has to be importable for the error to have any effect + saved_paths = tuple(sys.path) + sys.path.insert(0, TESTFN) + try: + with self.assertRaisesRegex(ValueError, "ouch"): + import test_error_package # Sanity check + + text = self.call_url_handler("search?key=test_error_package", + "Pydoc: Search Results") + found = ('' + 'test_error_package') + self.assertIn(found, text) + finally: + sys.path[:] = saved_paths + @unittest.skip('causes undesireable side-effects (#20128)') def test_modules(self): # See Helper.listmodules(). @@ -896,16 +926,12 @@ with self.restrict_walk_packages(): for url, title in requests: - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title, text) + self.call_url_handler(url, title) path = string.__file__ title = "Pydoc: getfile " + path url = "getfile?key=" + path - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title) + self.call_url_handler(url, title) class TestHelper(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -72,6 +72,9 @@ Library ------- +- Issue #18010: Fix the pydoc web server's module search function to handle + exceptions from importing packages. + - Issue #25554: Got rid of circular references in regular expression parsing. - Issue #18973: Command-line interface of the calendar module now uses argparse -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 20:09:57 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 06 Nov 2015 01:09:57 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzE4MDEw?= =?utf-8?q?=3A_Fix_pydoc_web_server_search_to_handle_package_exceptions?= Message-ID: <20151106010955.108165.48416@psf.io> https://hg.python.org/cpython/rev/9098731de840 changeset: 98978:9098731de840 branch: 3.4 parent: 98974:295459bd437f user: Martin Panter date: Fri Nov 06 00:27:14 2015 +0000 summary: Issue #18010: Fix pydoc web server search to handle package exceptions Implementation by Antoine Pitrou. files: Lib/pydoc.py | 4 ++- Lib/test/test_pydoc.py | 38 +++++++++++++++++++++++++---- Misc/NEWS | 3 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -2355,7 +2355,9 @@ with warnings.catch_warnings(): warnings.filterwarnings('ignore') # ignore problems during import - ModuleScanner().run(callback, key) + def onerror(modname): + pass + ModuleScanner().run(callback, key, onerror=onerror) # format page def bltinlink(name): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -403,6 +403,13 @@ finally: pkgutil.walk_packages = walk_packages + def call_url_handler(self, url, expected_title): + text = pydoc._url_handler(url, "text/html") + result = get_html_title(text) + # Check the title to ensure an unexpected error page was not returned + self.assertEqual(result, expected_title, text) + return text + class PydocDocTest(unittest.TestCase): @@ -715,6 +722,29 @@ finally: os.chmod(pkgdir, current_mode) + def test_url_search_package_error(self): + # URL handler search should cope with packages that raise exceptions + pkgdir = os.path.join(TESTFN, "test_error_package") + os.mkdir(pkgdir) + init = os.path.join(pkgdir, "__init__.py") + with open(init, "wt", encoding="ascii") as f: + f.write("""raise ValueError("ouch")\n""") + with self.restrict_walk_packages(path=[TESTFN]): + # Package has to be importable for the error to have any effect + saved_paths = tuple(sys.path) + sys.path.insert(0, TESTFN) + try: + with self.assertRaisesRegex(ValueError, "ouch"): + import test_error_package # Sanity check + + text = self.call_url_handler("search?key=test_error_package", + "Pydoc: Search Results") + found = ('' + 'test_error_package') + self.assertIn(found, text) + finally: + sys.path[:] = saved_paths + @unittest.skip('causes undesireable side-effects (#20128)') def test_modules(self): # See Helper.listmodules(). @@ -891,16 +921,12 @@ with self.restrict_walk_packages(): for url, title in requests: - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title, text) + self.call_url_handler(url, title) path = string.__file__ title = "Pydoc: getfile " + path url = "getfile?key=" + path - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title) + self.call_url_handler(url, title) class TestHelper(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -96,6 +96,9 @@ Library ------- +- Issue #18010: Fix the pydoc web server's module search function to handle + exceptions from importing packages. + - Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 5 20:09:57 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 06 Nov 2015 01:09:57 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2318010=3A_Merge_pydoc_web_search_fix_from_3=2E4_into_3?= =?utf-8?q?=2E5?= Message-ID: <20151106010955.36329.55293@psf.io> https://hg.python.org/cpython/rev/8702efa1feb4 changeset: 98979:8702efa1feb4 branch: 3.5 parent: 98975:ce93a386dcb8 parent: 98978:9098731de840 user: Martin Panter date: Fri Nov 06 00:51:38 2015 +0000 summary: Issue #18010: Merge pydoc web search fix from 3.4 into 3.5 files: Lib/pydoc.py | 4 ++- Lib/test/test_pydoc.py | 38 +++++++++++++++++++++++++---- Misc/NEWS | 3 ++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -2359,7 +2359,9 @@ with warnings.catch_warnings(): warnings.filterwarnings('ignore') # ignore problems during import - ModuleScanner().run(callback, key) + def onerror(modname): + pass + ModuleScanner().run(callback, key, onerror=onerror) # format page def bltinlink(name): diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py --- a/Lib/test/test_pydoc.py +++ b/Lib/test/test_pydoc.py @@ -396,6 +396,13 @@ finally: pkgutil.walk_packages = walk_packages + def call_url_handler(self, url, expected_title): + text = pydoc._url_handler(url, "text/html") + result = get_html_title(text) + # Check the title to ensure an unexpected error page was not returned + self.assertEqual(result, expected_title, text) + return text + class PydocDocTest(unittest.TestCase): @@ -704,6 +711,29 @@ finally: os.chmod(pkgdir, current_mode) + def test_url_search_package_error(self): + # URL handler search should cope with packages that raise exceptions + pkgdir = os.path.join(TESTFN, "test_error_package") + os.mkdir(pkgdir) + init = os.path.join(pkgdir, "__init__.py") + with open(init, "wt", encoding="ascii") as f: + f.write("""raise ValueError("ouch")\n""") + with self.restrict_walk_packages(path=[TESTFN]): + # Package has to be importable for the error to have any effect + saved_paths = tuple(sys.path) + sys.path.insert(0, TESTFN) + try: + with self.assertRaisesRegex(ValueError, "ouch"): + import test_error_package # Sanity check + + text = self.call_url_handler("search?key=test_error_package", + "Pydoc: Search Results") + found = ('' + 'test_error_package') + self.assertIn(found, text) + finally: + sys.path[:] = saved_paths + @unittest.skip('causes undesireable side-effects (#20128)') def test_modules(self): # See Helper.listmodules(). @@ -880,16 +910,12 @@ with self.restrict_walk_packages(): for url, title in requests: - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title, text) + self.call_url_handler(url, title) path = string.__file__ title = "Pydoc: getfile " + path url = "getfile?key=" + path - text = pydoc._url_handler(url, "text/html") - result = get_html_title(text) - self.assertEqual(result, title) + self.call_url_handler(url, title) class TestHelper(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -54,6 +54,9 @@ Library ------- +- Issue #18010: Fix the pydoc web server's module search function to handle + exceptions from importing packages. + - Issue #25554: Got rid of circular references in regular expression parsing. - Issue #25510: fileinput.FileInput.readline() now returns b'' instead of '' -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Fri Nov 6 03:45:46 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 06 Nov 2015 08:45:46 +0000 Subject: [Python-checkins] Daily reference leaks (d86ff708f545): sum=7 Message-ID: <20151106084546.10016.45329@psf.io> results for d86ff708f545 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogtaPoeL', '--timeout', '7200'] From python-checkins at python.org Fri Nov 6 04:21:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTU4?= =?utf-8?q?=3A_Refactoring_OrderedDict_iteration=2E?= Message-ID: <20151106092153.24940.96971@psf.io> https://hg.python.org/cpython/rev/ad44d551c13c changeset: 98981:ad44d551c13c branch: 3.5 parent: 98979:8702efa1feb4 user: Serhiy Storchaka date: Fri Nov 06 10:39:51 2015 +0200 summary: Issue #25558: Refactoring OrderedDict iteration. files: Objects/odictobject.c | 73 +++++++++++++----------------- 1 files changed, 32 insertions(+), 41 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1829,7 +1829,7 @@ static PyObject * odictiter_iternext(odictiterobject *di) { - PyObject *value; + PyObject *result, *value; PyObject *key = odictiter_nextkey(di); /* new reference */ if (key == NULL) @@ -1840,52 +1840,43 @@ return key; } + value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */ + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + goto done; + } + Py_INCREF(value); + + /* Handle the values case. */ + if (!(di->kind & _odict_ITER_KEYS)) { + Py_DECREF(key); + return value; + } + /* Handle the items case. */ - if (di->kind & _odict_ITER_KEYS) { - PyObject *result = di->di_result; + result = di->di_result; - value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */ - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); + if (Py_REFCNT(result) == 1) { + /* not in use so we can reuse it + * (the common case during iteration) */ + Py_INCREF(result); + Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */ + Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */ + } + else { + result = PyTuple_New(2); + if (result == NULL) { Py_DECREF(key); + Py_DECREF(value); goto done; } - Py_INCREF(value); + } - if (result->ob_refcnt == 1) { - /* not in use so we can reuse it - * (the common case during iteration) */ - Py_INCREF(result); - Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */ - Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */ - } - else { - result = PyTuple_New(2); - if (result == NULL) { - Py_DECREF(key); - Py_DECREF(value); - goto done; - } - } - - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ - - return result; - } - /* Handle the values case. */ - else { - value = PyODict_GetItem((PyObject *)di->di_odict, key); - Py_DECREF(key); - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); - goto done; - } - Py_INCREF(value); - return value; - } + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + return result; done: Py_CLEAR(di->di_current); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 04:21:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325558=3A_Refactoring_OrderedDict_iteration=2E?= Message-ID: <20151106092153.10973.23390@psf.io> https://hg.python.org/cpython/rev/51f3547da99c changeset: 98982:51f3547da99c parent: 98980:d86ff708f545 parent: 98981:ad44d551c13c user: Serhiy Storchaka date: Fri Nov 06 10:40:05 2015 +0200 summary: Issue #25558: Refactoring OrderedDict iteration. files: Objects/odictobject.c | 73 +++++++++++++----------------- 1 files changed, 32 insertions(+), 41 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1829,7 +1829,7 @@ static PyObject * odictiter_iternext(odictiterobject *di) { - PyObject *value; + PyObject *result, *value; PyObject *key = odictiter_nextkey(di); /* new reference */ if (key == NULL) @@ -1840,52 +1840,43 @@ return key; } + value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */ + if (value == NULL) { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError, key); + Py_DECREF(key); + goto done; + } + Py_INCREF(value); + + /* Handle the values case. */ + if (!(di->kind & _odict_ITER_KEYS)) { + Py_DECREF(key); + return value; + } + /* Handle the items case. */ - if (di->kind & _odict_ITER_KEYS) { - PyObject *result = di->di_result; + result = di->di_result; - value = PyODict_GetItem((PyObject *)di->di_odict, key); /* borrowed */ - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); + if (Py_REFCNT(result) == 1) { + /* not in use so we can reuse it + * (the common case during iteration) */ + Py_INCREF(result); + Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */ + Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */ + } + else { + result = PyTuple_New(2); + if (result == NULL) { Py_DECREF(key); + Py_DECREF(value); goto done; } - Py_INCREF(value); + } - if (result->ob_refcnt == 1) { - /* not in use so we can reuse it - * (the common case during iteration) */ - Py_INCREF(result); - Py_DECREF(PyTuple_GET_ITEM(result, 0)); /* borrowed */ - Py_DECREF(PyTuple_GET_ITEM(result, 1)); /* borrowed */ - } - else { - result = PyTuple_New(2); - if (result == NULL) { - Py_DECREF(key); - Py_DECREF(value); - goto done; - } - } - - PyTuple_SET_ITEM(result, 0, key); /* steals reference */ - PyTuple_SET_ITEM(result, 1, value); /* steals reference */ - - return result; - } - /* Handle the values case. */ - else { - value = PyODict_GetItem((PyObject *)di->di_odict, key); - Py_DECREF(key); - if (value == NULL) { - if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_KeyError, key); - goto done; - } - Py_INCREF(value); - return value; - } + PyTuple_SET_ITEM(result, 0, key); /* steals reference */ + PyTuple_SET_ITEM(result, 1, value); /* steals reference */ + return result; done: Py_CLEAR(di->di_current); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 04:21:58 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:58 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324726=3A_Revert_setting_the_value_on_the_dict_i?= =?utf-8?q?f?= Message-ID: <20151106092158.16147.14705@psf.io> https://hg.python.org/cpython/rev/b391e97ccfe5 changeset: 98984:b391e97ccfe5 parent: 98982:51f3547da99c parent: 98983:1594c23d8c2f user: Serhiy Storchaka date: Fri Nov 06 11:07:31 2015 +0200 summary: Issue #24726: Revert setting the value on the dict if _odict_add_new_node() fails. files: Objects/odictobject.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1721,7 +1721,13 @@ int res = PyDict_SetItem(od, key, value); if (res == 0) { res = _odict_add_new_node((PyODictObject *)od, key); - /* XXX Revert setting the value on the dict? */ + if (res < 0) { + /* Revert setting the value on the dict */ + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + (void) PyDict_DelItem(od, key); + _PyErr_ChainExceptions(exc, val, tb); + } } return res; }; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 04:21:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI0NzI2?= =?utf-8?q?=3A_Revert_setting_the_value_on_the_dict_if?= Message-ID: <20151106092158.100493.94080@psf.io> https://hg.python.org/cpython/rev/1594c23d8c2f changeset: 98983:1594c23d8c2f branch: 3.5 parent: 98981:ad44d551c13c user: Serhiy Storchaka date: Fri Nov 06 11:07:11 2015 +0200 summary: Issue #24726: Revert setting the value on the dict if _odict_add_new_node() fails. files: Objects/odictobject.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -1721,7 +1721,13 @@ int res = PyDict_SetItem(od, key, value); if (res == 0) { res = _odict_add_new_node((PyODictObject *)od, key); - /* XXX Revert setting the value on the dict? */ + if (res < 0) { + /* Revert setting the value on the dict */ + PyObject *exc, *val, *tb; + PyErr_Fetch(&exc, &val, &tb); + (void) PyDict_DelItem(od, key); + _PyErr_ChainExceptions(exc, val, tb); + } } return res; }; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 04:21:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fixed_merging_?= =?utf-8?q?error_in_3ebeeed1eb28=2E?= Message-ID: <20151106092158.100497.49168@psf.io> https://hg.python.org/cpython/rev/4c200145698f changeset: 98985:4c200145698f branch: 3.5 parent: 98983:1594c23d8c2f user: Serhiy Storchaka date: Fri Nov 06 11:19:42 2015 +0200 summary: Fixed merging error in 3ebeeed1eb28. Thanks ???? ?????????. files: Doc/library/ssl.rst | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -315,8 +315,6 @@ For almost all applications :func:`os.urandom` is preferable. - For almost all applications :func:`os.urandom` is preferable. - .. versionadded:: 3.3 .. function:: RAND_status() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 04:21:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 09:21:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fixed_merging_error_in_3ebeeed1eb28=2E?= Message-ID: <20151106092159.10024.55539@psf.io> https://hg.python.org/cpython/rev/d29c576dc7a0 changeset: 98986:d29c576dc7a0 parent: 98984:b391e97ccfe5 parent: 98985:4c200145698f user: Serhiy Storchaka date: Fri Nov 06 11:21:02 2015 +0200 summary: Fixed merging error in 3ebeeed1eb28. Thanks ???? ?????????. files: Doc/library/ssl.rst | 2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/Doc/library/ssl.rst b/Doc/library/ssl.rst --- a/Doc/library/ssl.rst +++ b/Doc/library/ssl.rst @@ -315,8 +315,6 @@ For almost all applications :func:`os.urandom` is preferable. - For almost all applications :func:`os.urandom` is preferable. - .. versionadded:: 3.3 .. function:: RAND_status() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 05:01:04 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 10:01:04 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDEw?= =?utf-8?q?=3A_Made_testing_that_od=5Ffast=5Fnodes_and_dk=5Fentries_are_in?= =?utf-8?q?_sync_more?= Message-ID: <20151106100103.123077.76857@psf.io> https://hg.python.org/cpython/rev/45ce4c6b4f36 changeset: 98987:45ce4c6b4f36 branch: 3.5 parent: 98985:4c200145698f user: Serhiy Storchaka date: Fri Nov 06 12:00:03 2015 +0200 summary: Issue #25410: Made testing that od_fast_nodes and dk_entries are in sync more reliable. files: Objects/odictobject.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -481,10 +481,12 @@ PyDictObject od_dict; /* the underlying dict */ _ODictNode *od_first; /* first node in the linked list, if any */ _ODictNode *od_last; /* last node in the linked list, if any */ - /* od_fast_nodes and od_resize_sentinel are managed by _odict_resize() + /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed + * by _odict_resize(). * Note that we rely on implementation details of dict for both. */ _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */ - Py_uintptr_t od_resize_sentinel; /* changes if odict should be resized */ + Py_ssize_t od_fast_nodes_size; + void *od_resize_sentinel; /* changes if odict should be resized */ size_t od_state; /* incremented whenever the LL changes */ PyObject *od_inst_dict; /* OrderedDict().__dict__ */ @@ -573,7 +575,8 @@ /* Replace the old fast nodes table. */ _odict_free_fast_nodes(od); od->od_fast_nodes = fast_nodes; - od->od_resize_sentinel = (Py_uintptr_t)(((PyDictObject *)od)->ma_keys); + od->od_fast_nodes_size = size; + od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys; return 0; } @@ -591,7 +594,8 @@ keys = ((PyDictObject *)od)->ma_keys; /* Ensure od_fast_nodes and dk_entries are in sync. */ - if (od->od_resize_sentinel != (Py_uintptr_t)keys) { + if (od->od_resize_sentinel != keys || + od->od_fast_nodes_size != keys->dk_size) { int resize_res = _odict_resize(od); if (resize_res < 0) return -1; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 05:01:04 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 06 Nov 2015 10:01:04 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325410=3A_Made_testing_that_od=5Ffast=5Fnodes_an?= =?utf-8?q?d_dk=5Fentries_are_in_sync_more?= Message-ID: <20151106100103.2112.71746@psf.io> https://hg.python.org/cpython/rev/c16af48153a4 changeset: 98988:c16af48153a4 parent: 98986:d29c576dc7a0 parent: 98987:45ce4c6b4f36 user: Serhiy Storchaka date: Fri Nov 06 12:00:43 2015 +0200 summary: Issue #25410: Made testing that od_fast_nodes and dk_entries are in sync more reliable. files: Objects/odictobject.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -481,10 +481,12 @@ PyDictObject od_dict; /* the underlying dict */ _ODictNode *od_first; /* first node in the linked list, if any */ _ODictNode *od_last; /* last node in the linked list, if any */ - /* od_fast_nodes and od_resize_sentinel are managed by _odict_resize() + /* od_fast_nodes, od_fast_nodes_size and od_resize_sentinel are managed + * by _odict_resize(). * Note that we rely on implementation details of dict for both. */ _ODictNode **od_fast_nodes; /* hash table that mirrors the dict table */ - Py_uintptr_t od_resize_sentinel; /* changes if odict should be resized */ + Py_ssize_t od_fast_nodes_size; + void *od_resize_sentinel; /* changes if odict should be resized */ size_t od_state; /* incremented whenever the LL changes */ PyObject *od_inst_dict; /* OrderedDict().__dict__ */ @@ -573,7 +575,8 @@ /* Replace the old fast nodes table. */ _odict_free_fast_nodes(od); od->od_fast_nodes = fast_nodes; - od->od_resize_sentinel = (Py_uintptr_t)(((PyDictObject *)od)->ma_keys); + od->od_fast_nodes_size = size; + od->od_resize_sentinel = ((PyDictObject *)od)->ma_keys; return 0; } @@ -591,7 +594,8 @@ keys = ((PyDictObject *)od)->ma_keys; /* Ensure od_fast_nodes and dk_entries are in sync. */ - if (od->od_resize_sentinel != (Py_uintptr_t)keys) { + if (od->od_resize_sentinel != keys || + od->od_fast_nodes_size != keys->dk_size) { int resize_res = _odict_resize(od); if (resize_res < 0) return -1; -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Fri Nov 6 07:44:29 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 6 Nov 2015 12:44:29 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-06 Message-ID: Results for project Python default, build date 2015-11-06 04:02:19 +0000 commit: d86ff708f545fa96cb4ee963f8033b2c73771c4d revision date: 2015-11-06 01:08:34 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.37% 1.57% 8.22% 15.56% :-( pybench 0.10% 0.30% -2.11% 8.64% :-( regex_v8 2.68% 0.23% -5.23% 6.20% :-| nbody 0.07% 0.79% 0.49% 2.72% :-| json_dump_v2 0.22% -0.15% -1.23% 11.04% :-| normal_startup 0.91% -0.07% 0.21% 5.02% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Fri Nov 6 07:50:55 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 6 Nov 2015 12:50:55 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-06 Message-ID: <033bdd14-4eb9-4990-b540-30098b92bc3e@irsmsx101.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-06 04:51:46 +0000 commit: 92dda5f00b0f154862d8b671b9366868d767cf6b revision date: 2015-11-05 19:41:57 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.19% 0.43% 3.01% 9.33% :-) pybench 0.21% 0.24% 6.68% 6.90% :-| regex_v8 0.60% 0.10% -1.68% 7.69% :-) nbody 0.16% 0.06% 8.69% 4.64% :-) json_dump_v2 0.20% 0.00% 2.35% 14.90% :-| normal_startup 1.85% -0.24% -1.95% 3.28% :-| ssbench 0.80% -0.65% 0.68% 1.31% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Fri Nov 6 11:02:50 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 06 Nov 2015 16:02:50 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325555=3A_Fix_pars?= =?utf-8?q?er_and_AST=3A_fill_lineno_and_col=5Foffset_of_=22arg=22_node_wh?= =?utf-8?q?en?= Message-ID: <20151106160233.39500.4961@psf.io> https://hg.python.org/cpython/rev/54d4290f0ec6 changeset: 98989:54d4290f0ec6 user: Victor Stinner date: Fri Nov 06 17:01:48 2015 +0100 summary: Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node when compiling AST from Python objects. files: Include/Python-ast.h | 5 +++-- Misc/NEWS | 3 +++ Parser/asdl_c.py | 12 ++++++++++-- Python/Python-ast.c | 31 +++++++++++++++++++++++++++++-- Python/ast.c | 9 +++------ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/Include/Python-ast.h b/Include/Python-ast.h --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -602,8 +602,9 @@ arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * defaults, PyArena *arena); -#define arg(a0, a1, a2) _Py_arg(a0, a1, a2) -arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena); +#define arg(a0, a1, a2, a3, a4) _Py_arg(a0, a1, a2, a3, a4) +arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset, + PyArena *arena); #define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); #define alias(a0, a1, a2) _Py_alias(a0, a1, a2) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node + when compiling AST from Python objects. + - Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -275,7 +275,9 @@ def visitProduct(self, prod, name): self.emit_function(name, get_c_type(name), - self.get_args(prod.fields), [], union=False) + self.get_args(prod.fields), + self.get_args(prod.attributes), + union=False) class FunctionVisitor(PrototypeVisitor): @@ -329,7 +331,8 @@ self.emit(s, depth, reflow) for argtype, argname, opt in args: emit("p->%s = %s;" % (argname, argname), 1) - assert not attrs + for argtype, argname, opt in attrs: + emit("p->%s = %s;" % (argname, argname), 1) class PickleVisitor(EmitVisitor): @@ -452,10 +455,15 @@ self.emit("PyObject* tmp = NULL;", 1) for f in prod.fields: self.visitFieldDeclaration(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitFieldDeclaration(a, name, prod=prod, depth=1) self.emit("", 0) for f in prod.fields: self.visitField(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitField(a, name, prod=prod, depth=1) args = [f.name for f in prod.fields] + args.extend([a.name for a in prod.attributes]) self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) self.emit("return 0;", 1) self.emit("failed:", 0) diff --git a/Python/Python-ast.c b/Python/Python-ast.c --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -2425,7 +2425,8 @@ } arg_ty -arg(identifier arg, expr_ty annotation, PyArena *arena) +arg(identifier arg, expr_ty annotation, int lineno, int col_offset, PyArena + *arena) { arg_ty p; if (!arg) { @@ -2438,6 +2439,8 @@ return NULL; p->arg = arg; p->annotation = annotation; + p->lineno = lineno; + p->col_offset = col_offset; return p; } @@ -7247,6 +7250,8 @@ PyObject* tmp = NULL; identifier arg; expr_ty annotation; + int lineno; + int col_offset; if (_PyObject_HasAttrId(obj, &PyId_arg)) { int res; @@ -7269,7 +7274,29 @@ } else { annotation = NULL; } - *out = arg(arg, annotation, arena); + if (_PyObject_HasAttrId(obj, &PyId_lineno)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_lineno); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_col_offset)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_col_offset); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg"); + return 1; + } + *out = arg(arg, annotation, lineno, col_offset, arena); return 0; failed: Py_XDECREF(tmp); diff --git a/Python/ast.c b/Python/ast.c --- a/Python/ast.c +++ b/Python/ast.c @@ -1181,11 +1181,9 @@ return NULL; } - ret = arg(name, annotation, c->c_arena); + ret = arg(name, annotation, LINENO(n), n->n_col_offset, c->c_arena); if (!ret) return NULL; - ret->lineno = LINENO(n); - ret->col_offset = n->n_col_offset; return ret; } @@ -1241,11 +1239,10 @@ goto error; if (forbidden_name(c, argname, ch, 0)) goto error; - arg = arg(argname, annotation, c->c_arena); + arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset, + c->c_arena); if (!arg) goto error; - arg->lineno = LINENO(ch); - arg->col_offset = ch->n_col_offset; asdl_seq_SET(kwonlyargs, j++, arg); i += 2; /* the name and the comma */ break; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 20:00:05 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 01:00:05 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325064=3A_Merge_tempfile_doc_from_3=2E5?= Message-ID: <20151107010005.58407.67193@psf.io> https://hg.python.org/cpython/rev/c495c9dd7726 changeset: 98991:c495c9dd7726 parent: 98989:54d4290f0ec6 parent: 98990:de79e483565c user: Martin Panter date: Sat Nov 07 00:56:56 2015 +0000 summary: Issue #25064: Merge tempfile doc from 3.5 files: Doc/library/tempfile.rst | 36 +++++++++++++-------------- Lib/tempfile.py | 17 +++++++------ 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -33,7 +33,7 @@ The module defines the following user-callable items: -.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) +.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) Return a :term:`file-like object` that can be used as a temporary storage area. The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon @@ -54,8 +54,8 @@ stored. *buffering*, *encoding* and *newline* are interpreted as for :func:`open`. - The *dir*, *prefix* and *suffix* parameters have the same meaning - as with :func:`mkstemp`. + The *dir*, *prefix* and *suffix* parameters have the same meaning and + defaults as with :func:`mkstemp`. The returned object is a true file object on POSIX platforms. On other platforms, it is a file-like object whose :attr:`!file` attribute is the @@ -69,7 +69,7 @@ The :py:data:`os.O_TMPFILE` flag is now used if available. -.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) +.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True) This function operates exactly as :func:`TemporaryFile` does, except that the file is guaranteed to have a visible name in the file system (on @@ -84,7 +84,7 @@ be used in a :keyword:`with` statement, just like a normal file. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) +.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) This function operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or @@ -106,7 +106,7 @@ the truncate method now accepts a ``size`` argument. -.. function:: TemporaryDirectory(suffix='', prefix='tmp', dir=None) +.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None) This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see @@ -138,15 +138,16 @@ Unlike :func:`TemporaryFile`, the user of :func:`mkstemp` is responsible for deleting the temporary file when done with it. - If *suffix* is specified, the file name will end with that suffix, + If *suffix* is not ``None``, the file name will end with that suffix, otherwise there will be no suffix. :func:`mkstemp` does not put a dot between the file name and the suffix; if you need one, put it at the beginning of *suffix*. - If *prefix* is specified, the file name will begin with that prefix; - otherwise, a default prefix is used. + If *prefix* is not ``None``, the file name will begin with that prefix; + otherwise, a default prefix is used. The default is the return value of + :func:`gettempprefix` or :func:`gettempprefixb`, as appropriate. - If *dir* is specified, the file will be created in that directory; + If *dir* is not ``None``, the file will be created in that directory; otherwise, a default directory is used. The default directory is chosen from a platform-dependent list, but the user of the application can control the directory location by setting the *TMPDIR*, *TEMP* or *TMP* @@ -154,16 +155,12 @@ filename will have any nice properties, such as not requiring quoting when passed to external commands via ``os.popen()``. - *suffix*, *prefix*, and *dir* must all contain the same type, if specified. + If any of *suffix*, *prefix*, and *dir* are not + ``None``, they must be the same type. If they are bytes, the returned name will be bytes instead of str. If you want to force a bytes return value with otherwise default behavior, pass ``suffix=b''``. - A *prefix* value of ``None`` means use the return value of - :func:`gettempprefix` or :func:`gettempprefixb` as appropriate. - - A *suffix* value of ``None`` means use an appropriate empty value. - If *text* is specified, it indicates whether to open the file in binary mode (the default) or text mode. On some platforms, this makes no difference. @@ -241,7 +238,7 @@ .. function:: gettempprefixb() - Same as :func:`gettempprefixb` but the return value is in bytes. + Same as :func:`gettempprefix` but the return value is in bytes. .. versionadded:: 3.5 @@ -314,8 +311,9 @@ Use :func:`mkstemp` instead. Return an absolute pathname of a file that did not exist at the time the - call is made. The *prefix*, *suffix*, and *dir* arguments are the same - as for :func:`mkstemp`. + call is made. The *prefix*, *suffix*, and *dir* arguments are similar + to those of :func:`mkstemp`, except that bytes file names, ``suffix=None`` + and ``prefix=None`` are not supported. .. warning:: diff --git a/Lib/tempfile.py b/Lib/tempfile.py --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -307,22 +307,22 @@ file. The return value is a pair (fd, name) where fd is the file descriptor returned by os.open, and name is the filename. - If 'suffix' is specified, the file name will end with that suffix, + If 'suffix' is not None, the file name will end with that suffix, otherwise there will be no suffix. - If 'prefix' is specified, the file name will begin with that prefix, + If 'prefix' is not None, the file name will begin with that prefix, otherwise a default prefix is used. - If 'dir' is specified, the file will be created in that directory, + If 'dir' is not None, the file will be created in that directory, otherwise a default directory is used. If 'text' is specified and true, the file is opened in text mode. Else (the default) the file is opened in binary mode. On some operating systems, this makes no difference. - suffix, prefix and dir must all contain the same type if specified. - If they are bytes, the returned name will be bytes; str otherwise. - A value of None will cause an appropriate default to be used. + If any of 'suffix', 'prefix' and 'dir' are not None, they must be the + same type. If they are bytes, the returned name will be bytes; str + otherwise. The file is readable and writable only by the creating user ID. If the operating system uses permission bits to indicate whether a @@ -385,8 +385,9 @@ """User-callable function to return a unique temporary file name. The file is not created. - Arguments are as for mkstemp, except that the 'text' argument is - not accepted. + Arguments are similar to mkstemp, except that the 'text' argument is + not accepted, and suffix=None, prefix=None and bytes file names are not + supported. THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 20:00:12 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 01:00:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1MDY0?= =?utf-8?q?=3A_Adjust_documentation_according_to_new_mkstemp_signature?= Message-ID: <20151107010005.10006.729@psf.io> https://hg.python.org/cpython/rev/de79e483565c changeset: 98990:de79e483565c branch: 3.5 parent: 98987:45ce4c6b4f36 user: Martin Panter date: Sat Nov 07 00:32:50 2015 +0000 summary: Issue #25064: Adjust documentation according to new mkstemp signature The mkstemp() and mkdtemp() signatures have already been updated, but the higher-level functions still suggest that the default values are forced to text strings. Also merged some paragraphs describing the "suffix" and "prefix" parameters, and pointed out that mktemp() does not support the new changes. files: Doc/library/tempfile.rst | 36 +++++++++++++-------------- Lib/tempfile.py | 17 +++++++------ 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/Doc/library/tempfile.rst b/Doc/library/tempfile.rst --- a/Doc/library/tempfile.rst +++ b/Doc/library/tempfile.rst @@ -33,7 +33,7 @@ The module defines the following user-callable items: -.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) +.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) Return a :term:`file-like object` that can be used as a temporary storage area. The file is created securely, using the same rules as :func:`mkstemp`. It will be destroyed as soon @@ -54,8 +54,8 @@ stored. *buffering*, *encoding* and *newline* are interpreted as for :func:`open`. - The *dir*, *prefix* and *suffix* parameters have the same meaning - as with :func:`mkstemp`. + The *dir*, *prefix* and *suffix* parameters have the same meaning and + defaults as with :func:`mkstemp`. The returned object is a true file object on POSIX platforms. On other platforms, it is a file-like object whose :attr:`!file` attribute is the @@ -69,7 +69,7 @@ The :py:data:`os.O_TMPFILE` flag is now used if available. -.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None, delete=True) +.. function:: NamedTemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True) This function operates exactly as :func:`TemporaryFile` does, except that the file is guaranteed to have a visible name in the file system (on @@ -84,7 +84,7 @@ be used in a :keyword:`with` statement, just like a normal file. -.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None) +.. function:: SpooledTemporaryFile(max_size=0, mode='w+b', buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None) This function operates exactly as :func:`TemporaryFile` does, except that data is spooled in memory until the file size exceeds *max_size*, or @@ -106,7 +106,7 @@ the truncate method now accepts a ``size`` argument. -.. function:: TemporaryDirectory(suffix='', prefix='tmp', dir=None) +.. function:: TemporaryDirectory(suffix=None, prefix=None, dir=None) This function securely creates a temporary directory using the same rules as :func:`mkdtemp`. The resulting object can be used as a context manager (see @@ -138,15 +138,16 @@ Unlike :func:`TemporaryFile`, the user of :func:`mkstemp` is responsible for deleting the temporary file when done with it. - If *suffix* is specified, the file name will end with that suffix, + If *suffix* is not ``None``, the file name will end with that suffix, otherwise there will be no suffix. :func:`mkstemp` does not put a dot between the file name and the suffix; if you need one, put it at the beginning of *suffix*. - If *prefix* is specified, the file name will begin with that prefix; - otherwise, a default prefix is used. + If *prefix* is not ``None``, the file name will begin with that prefix; + otherwise, a default prefix is used. The default is the return value of + :func:`gettempprefix` or :func:`gettempprefixb`, as appropriate. - If *dir* is specified, the file will be created in that directory; + If *dir* is not ``None``, the file will be created in that directory; otherwise, a default directory is used. The default directory is chosen from a platform-dependent list, but the user of the application can control the directory location by setting the *TMPDIR*, *TEMP* or *TMP* @@ -154,16 +155,12 @@ filename will have any nice properties, such as not requiring quoting when passed to external commands via ``os.popen()``. - *suffix*, *prefix*, and *dir* must all contain the same type, if specified. + If any of *suffix*, *prefix*, and *dir* are not + ``None``, they must be the same type. If they are bytes, the returned name will be bytes instead of str. If you want to force a bytes return value with otherwise default behavior, pass ``suffix=b''``. - A *prefix* value of ``None`` means use the return value of - :func:`gettempprefix` or :func:`gettempprefixb` as appropriate. - - A *suffix* value of ``None`` means use an appropriate empty value. - If *text* is specified, it indicates whether to open the file in binary mode (the default) or text mode. On some platforms, this makes no difference. @@ -241,7 +238,7 @@ .. function:: gettempprefixb() - Same as :func:`gettempprefixb` but the return value is in bytes. + Same as :func:`gettempprefix` but the return value is in bytes. .. versionadded:: 3.5 @@ -314,8 +311,9 @@ Use :func:`mkstemp` instead. Return an absolute pathname of a file that did not exist at the time the - call is made. The *prefix*, *suffix*, and *dir* arguments are the same - as for :func:`mkstemp`. + call is made. The *prefix*, *suffix*, and *dir* arguments are similar + to those of :func:`mkstemp`, except that bytes file names, ``suffix=None`` + and ``prefix=None`` are not supported. .. warning:: diff --git a/Lib/tempfile.py b/Lib/tempfile.py --- a/Lib/tempfile.py +++ b/Lib/tempfile.py @@ -307,22 +307,22 @@ file. The return value is a pair (fd, name) where fd is the file descriptor returned by os.open, and name is the filename. - If 'suffix' is specified, the file name will end with that suffix, + If 'suffix' is not None, the file name will end with that suffix, otherwise there will be no suffix. - If 'prefix' is specified, the file name will begin with that prefix, + If 'prefix' is not None, the file name will begin with that prefix, otherwise a default prefix is used. - If 'dir' is specified, the file will be created in that directory, + If 'dir' is not None, the file will be created in that directory, otherwise a default directory is used. If 'text' is specified and true, the file is opened in text mode. Else (the default) the file is opened in binary mode. On some operating systems, this makes no difference. - suffix, prefix and dir must all contain the same type if specified. - If they are bytes, the returned name will be bytes; str otherwise. - A value of None will cause an appropriate default to be used. + If any of 'suffix', 'prefix' and 'dir' are not None, they must be the + same type. If they are bytes, the returned name will be bytes; str + otherwise. The file is readable and writable only by the creating user ID. If the operating system uses permission bits to indicate whether a @@ -385,8 +385,9 @@ """User-callable function to return a unique temporary file name. The file is not created. - Arguments are as for mkstemp, except that the 'text' argument is - not accepted. + Arguments are similar to mkstemp, except that the 'text' argument is + not accepted, and suffix=None, prefix=None and bytes file names are not + supported. THIS FUNCTION IS UNSAFE AND SHOULD NOT BE USED. The file name may refer to a file that did not exist at some point, but by the time -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 22:33:09 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 03:33:09 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0ODAy?= =?utf-8?q?=3A_Copy_bytes-like_objects_to_null-terminated_buffers_if_neces?= =?utf-8?q?sary?= Message-ID: <20151107033309.16139.46960@psf.io> https://hg.python.org/cpython/rev/a75336ac40e0 changeset: 98992:a75336ac40e0 branch: 3.4 parent: 98978:9098731de840 user: Martin Panter date: Sat Nov 07 02:32:21 2015 +0000 summary: Issue #24802: Copy bytes-like objects to null-terminated buffers if necessary This avoids possible buffer overreads when int(), float(), compile(), exec() and eval() are passed bytes-like objects. Similar code is removed from the complex() constructor, where it was not reachable. Patch by John Leitch, Serhiy Storchaka and Martin Panter. files: Lib/test/test_compile.py | 21 ++++++++++++ Lib/test/test_float.py | 38 +++++++++++++++++++++- Lib/test/test_int.py | 42 +++++++++++++++++++----- Misc/NEWS | 4 ++ Objects/abstract.c | 22 +++++++++++- Objects/complexobject.c | 7 ---- Objects/floatobject.c | 15 ++++++++ Python/bltinmodule.c | 48 ++++++++++++++++++--------- 8 files changed, 161 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -530,6 +530,27 @@ check_limit("a", "[0]") check_limit("a", "*a") + def test_null_terminated(self): + # The source code is null-terminated internally, but bytes-like + # objects are accepted, which could be not terminated. + # Exception changed from TypeError to ValueError in 3.5 + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile("123\x00", "", "eval") + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile(memoryview(b"123\x00"), "", "eval") + code = compile(memoryview(b"123\x00")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"1234")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"$23$")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + + # Also test when eval() and exec() do the compilation step + self.assertEqual(eval(memoryview(b"1234")[1:-1]), 23) + namespace = dict() + exec(memoryview(b"ax = 123")[1:-1], namespace) + self.assertEqual(namespace['x'], 12) + class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -31,7 +31,6 @@ self.assertEqual(float(3.14), 3.14) self.assertEqual(float(314), 314.0) self.assertEqual(float(" 3.14 "), 3.14) - self.assertEqual(float(b" 3.14 "), 3.14) self.assertRaises(ValueError, float, " 0x3.1 ") self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertRaises(ValueError, float, " +0x3.p-1 ") @@ -43,7 +42,6 @@ self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.") - self.assertRaises(ValueError, float, b"-") self.assertRaises(TypeError, float, {}) self.assertRaisesRegex(TypeError, "not 'dict'", float, {}) # Lone surrogate @@ -57,6 +55,42 @@ float(b'.' + b'1'*1000) float('.' + '1'*1000) + def test_non_numeric_input_types(self): + # Test possible non-numeric types for the argument x, including + # subclasses of the explicitly documented accepted types. + class CustomStr(str): pass + class CustomBytes(bytes): pass + class CustomByteArray(bytearray): pass + + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) + + for f in factories: + x = f(b" 3.14 ") + with self.subTest(type(x)): + self.assertEqual(float(x), 3.14) + with self.assertRaisesRegex(ValueError, "could not convert"): + float(f(b'A' * 0x10)) + + def test_float_memoryview(self): + self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) + def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist: diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -276,16 +276,40 @@ class CustomBytes(bytes): pass class CustomByteArray(bytearray): pass - values = [b'100', - bytearray(b'100'), - CustomStr('100'), - CustomBytes(b'100'), - CustomByteArray(b'100')] + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) - for x in values: - msg = 'x has type %s' % type(x).__name__ - self.assertEqual(int(x), 100, msg=msg) - self.assertEqual(int(x, 2), 4, msg=msg) + for f in factories: + x = f(b'100') + with self.subTest(type(x)): + self.assertEqual(int(x), 100) + if isinstance(x, (str, bytes, bytearray)): + self.assertEqual(int(x, 2), 4) + else: + msg = "can't convert non-string" + with self.assertRaisesRegex(TypeError, msg): + int(x, 2) + with self.assertRaisesRegex(ValueError, 'invalid literal'): + int(f(b'A' * 0x10)) + + def test_int_memoryview(self): + self.assertEqual(int(memoryview(b'123')[1:3]), 23) + self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) + self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) + self.assertEqual(int(memoryview(b'123A')[1:3]), 23) + self.assertEqual(int(memoryview(b'1234')[1:3]), 23) def test_string_float(self): self.assertRaises(ValueError, int, '1.2') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + - Issue #24402: Fix input() to prompt to the redirected stdout when sys.stdout.fileno() fails. diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1264,12 +1264,30 @@ /* The below check is done in PyLong_FromUnicode(). */ return PyLong_FromUnicodeObject(o, 10); - if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + if (PyBytes_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular int('9\x005') must raise an * exception, not truncate at the null. */ - PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10); + return _PyLong_FromBytes(PyBytes_AS_STRING(o), + PyBytes_GET_SIZE(o), 10); + + if (PyByteArray_Check(o)) + return _PyLong_FromBytes(PyByteArray_AS_STRING(o), + PyByteArray_GET_SIZE(o), 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + PyObject *result, *bytes; + + /* Copy to NUL-terminated buffer. */ + bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len); + if (bytes == NULL) { + PyBuffer_Release(&view); + return NULL; + } + result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes), 10); + Py_DECREF(bytes); PyBuffer_Release(&view); return result; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -767,7 +767,6 @@ int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; - Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -777,10 +776,6 @@ if (s == NULL) goto error; } - else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { - s = (const char *)view.buf; - len = view.len; - } else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", @@ -895,7 +890,6 @@ if (s-start != len) goto parse_error; - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -903,7 +897,6 @@ PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -144,9 +144,24 @@ return NULL; } } + else if (PyBytes_Check(v)) { + s = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); + } + else if (PyByteArray_Check(v)) { + s = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); + } else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { s = (const char *)view.buf; len = view.len; + /* Copy to NUL-terminated buffer. */ + s_buffer = PyBytes_FromStringAndSize(s, len); + if (s_buffer == NULL) { + PyBuffer_Release(&view); + return NULL; + } + s = PyBytes_AS_STRING(s_buffer); } else { PyErr_Format(PyExc_TypeError, diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -560,20 +560,37 @@ static const char * -source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) { const char *str; Py_ssize_t size; + Py_buffer view; + *cmd_copy = NULL; if (PyUnicode_Check(cmd)) { cf->cf_flags |= PyCF_IGNORE_COOKIE; str = PyUnicode_AsUTF8AndSize(cmd, &size); if (str == NULL) return NULL; } - else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) { - str = (const char *)view->buf; - size = view->len; + else if (PyBytes_Check(cmd)) { + str = PyBytes_AS_STRING(cmd); + size = PyBytes_GET_SIZE(cmd); + } + else if (PyByteArray_Check(cmd)) { + str = PyByteArray_AS_STRING(cmd); + size = PyByteArray_GET_SIZE(cmd); + } + else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { + /* Copy to NUL-terminated buffer. */ + *cmd_copy = PyBytes_FromStringAndSize( + (const char *)view.buf, view.len); + PyBuffer_Release(&view); + if (*cmd_copy == NULL) { + return NULL; + } + str = PyBytes_AS_STRING(*cmd_copy); + size = PyBytes_GET_SIZE(*cmd_copy); } else { PyErr_Format(PyExc_TypeError, @@ -585,7 +602,7 @@ if (strlen(str) != size) { PyErr_SetString(PyExc_TypeError, "source code string cannot contain null bytes"); - PyBuffer_Release(view); + Py_CLEAR(*cmd_copy); return NULL; } return str; @@ -594,7 +611,7 @@ static PyObject * builtin_compile(PyObject *self, PyObject *args, PyObject *kwds) { - Py_buffer view = {NULL, NULL}; + PyObject *cmd_copy; const char *str; PyObject *filename; char *startstr; @@ -681,12 +698,12 @@ goto finally; } - str = source_as_string(cmd, "compile", "string, bytes or AST", &cf, &view); + str = source_as_string(cmd, "compile", "string, bytes or AST", &cf, &cmd_copy); if (str == NULL) goto error; result = Py_CompileStringObject(str, filename, start[mode], &cf, optimize); - PyBuffer_Release(&view); + Py_XDECREF(cmd_copy); goto finally; error: @@ -754,9 +771,8 @@ static PyObject * builtin_eval(PyObject *self, PyObject *args) { - PyObject *cmd, *result, *tmp = NULL; + PyObject *cmd, *result, *cmd_copy; PyObject *globals = Py_None, *locals = Py_None; - Py_buffer view = {NULL, NULL}; const char *str; PyCompilerFlags cf; @@ -806,7 +822,7 @@ } cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(cmd, "eval", "string, bytes or code", &cf, &view); + str = source_as_string(cmd, "eval", "string, bytes or code", &cf, &cmd_copy); if (str == NULL) return NULL; @@ -815,8 +831,7 @@ (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); - PyBuffer_Release(&view); - Py_XDECREF(tmp); + Py_XDECREF(cmd_copy); return result; } @@ -882,12 +897,13 @@ v = PyEval_EvalCode(prog, globals, locals); } else { - Py_buffer view = {NULL, NULL}; + PyObject *prog_copy; const char *str; PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; str = source_as_string(prog, "exec", - "string, bytes or code", &cf, &view); + "string, bytes or code", &cf, + &prog_copy); if (str == NULL) return NULL; if (PyEval_MergeCompilerFlags(&cf)) @@ -895,7 +911,7 @@ locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals); - PyBuffer_Release(&view); + Py_XDECREF(prog_copy); } if (v == NULL) return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 22:33:10 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 03:33:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2324802=3A_Merge_null_termination_fixes_from_3=2E4_into?= =?utf-8?q?_3=2E5?= Message-ID: <20151107033310.33548.45371@psf.io> https://hg.python.org/cpython/rev/95b9c07b27f7 changeset: 98993:95b9c07b27f7 branch: 3.5 parent: 98990:de79e483565c parent: 98992:a75336ac40e0 user: Martin Panter date: Sat Nov 07 02:56:11 2015 +0000 summary: Issue #24802: Merge null termination fixes from 3.4 into 3.5 files: Lib/test/test_compile.py | 21 ++++++++++++ Lib/test/test_float.py | 38 +++++++++++++++++++++- Lib/test/test_int.py | 42 +++++++++++++++++++----- Misc/NEWS | 4 ++ Objects/abstract.c | 22 +++++++++++- Objects/complexobject.c | 7 ---- Objects/floatobject.c | 15 ++++++++ Python/bltinmodule.c | 48 ++++++++++++++++++--------- 8 files changed, 161 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -542,6 +542,27 @@ check_limit("a", "[0]") check_limit("a", "*a") + def test_null_terminated(self): + # The source code is null-terminated internally, but bytes-like + # objects are accepted, which could be not terminated. + # Exception changed from TypeError to ValueError in 3.5 + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile("123\x00", "", "eval") + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile(memoryview(b"123\x00"), "", "eval") + code = compile(memoryview(b"123\x00")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"1234")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"$23$")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + + # Also test when eval() and exec() do the compilation step + self.assertEqual(eval(memoryview(b"1234")[1:-1]), 23) + namespace = dict() + exec(memoryview(b"ax = 123")[1:-1], namespace) + self.assertEqual(namespace['x'], 12) + class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -31,7 +31,6 @@ self.assertEqual(float(3.14), 3.14) self.assertEqual(float(314), 314.0) self.assertEqual(float(" 3.14 "), 3.14) - self.assertEqual(float(b" 3.14 "), 3.14) self.assertRaises(ValueError, float, " 0x3.1 ") self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertRaises(ValueError, float, " +0x3.p-1 ") @@ -43,7 +42,6 @@ self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.") - self.assertRaises(ValueError, float, b"-") self.assertRaises(TypeError, float, {}) self.assertRaisesRegex(TypeError, "not 'dict'", float, {}) # Lone surrogate @@ -57,6 +55,42 @@ float(b'.' + b'1'*1000) float('.' + '1'*1000) + def test_non_numeric_input_types(self): + # Test possible non-numeric types for the argument x, including + # subclasses of the explicitly documented accepted types. + class CustomStr(str): pass + class CustomBytes(bytes): pass + class CustomByteArray(bytearray): pass + + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) + + for f in factories: + x = f(b" 3.14 ") + with self.subTest(type(x)): + self.assertEqual(float(x), 3.14) + with self.assertRaisesRegex(ValueError, "could not convert"): + float(f(b'A' * 0x10)) + + def test_float_memoryview(self): + self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) + def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist: diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -276,16 +276,40 @@ class CustomBytes(bytes): pass class CustomByteArray(bytearray): pass - values = [b'100', - bytearray(b'100'), - CustomStr('100'), - CustomBytes(b'100'), - CustomByteArray(b'100')] + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) - for x in values: - msg = 'x has type %s' % type(x).__name__ - self.assertEqual(int(x), 100, msg=msg) - self.assertEqual(int(x, 2), 4, msg=msg) + for f in factories: + x = f(b'100') + with self.subTest(type(x)): + self.assertEqual(int(x), 100) + if isinstance(x, (str, bytes, bytearray)): + self.assertEqual(int(x, 2), 4) + else: + msg = "can't convert non-string" + with self.assertRaisesRegex(TypeError, msg): + int(x, 2) + with self.assertRaisesRegex(ValueError, 'invalid literal'): + int(f(b'A' * 0x10)) + + def test_int_memoryview(self): + self.assertEqual(int(memoryview(b'123')[1:3]), 23) + self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) + self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) + self.assertEqual(int(memoryview(b'123A')[1:3]), 23) + self.assertEqual(int(memoryview(b'1234')[1:3]), 23) def test_string_float(self): self.assertRaises(ValueError, int, '1.2') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,10 @@ Core and Builtins ----------------- +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + - Issue #24726: Fixed a crash and leaking NULL in repr() of OrderedDict that was mutated by direct calls of dict methods. diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1309,12 +1309,30 @@ /* The below check is done in PyLong_FromUnicode(). */ return PyLong_FromUnicodeObject(o, 10); - if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + if (PyBytes_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular int('9\x005') must raise an * exception, not truncate at the null. */ - PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10); + return _PyLong_FromBytes(PyBytes_AS_STRING(o), + PyBytes_GET_SIZE(o), 10); + + if (PyByteArray_Check(o)) + return _PyLong_FromBytes(PyByteArray_AS_STRING(o), + PyByteArray_GET_SIZE(o), 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + PyObject *result, *bytes; + + /* Copy to NUL-terminated buffer. */ + bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len); + if (bytes == NULL) { + PyBuffer_Release(&view); + return NULL; + } + result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes), 10); + Py_DECREF(bytes); PyBuffer_Release(&view); return result; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -767,7 +767,6 @@ int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; - Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -777,10 +776,6 @@ if (s == NULL) goto error; } - else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { - s = (const char *)view.buf; - len = view.len; - } else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", @@ -895,7 +890,6 @@ if (s-start != len) goto parse_error; - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -903,7 +897,6 @@ PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -144,9 +144,24 @@ return NULL; } } + else if (PyBytes_Check(v)) { + s = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); + } + else if (PyByteArray_Check(v)) { + s = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); + } else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { s = (const char *)view.buf; len = view.len; + /* Copy to NUL-terminated buffer. */ + s_buffer = PyBytes_FromStringAndSize(s, len); + if (s_buffer == NULL) { + PyBuffer_Release(&view); + return NULL; + } + s = PyBytes_AS_STRING(s_buffer); } else { PyErr_Format(PyExc_TypeError, diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -599,20 +599,37 @@ static const char * -source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) { const char *str; Py_ssize_t size; + Py_buffer view; + *cmd_copy = NULL; if (PyUnicode_Check(cmd)) { cf->cf_flags |= PyCF_IGNORE_COOKIE; str = PyUnicode_AsUTF8AndSize(cmd, &size); if (str == NULL) return NULL; } - else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) { - str = (const char *)view->buf; - size = view->len; + else if (PyBytes_Check(cmd)) { + str = PyBytes_AS_STRING(cmd); + size = PyBytes_GET_SIZE(cmd); + } + else if (PyByteArray_Check(cmd)) { + str = PyByteArray_AS_STRING(cmd); + size = PyByteArray_GET_SIZE(cmd); + } + else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { + /* Copy to NUL-terminated buffer. */ + *cmd_copy = PyBytes_FromStringAndSize( + (const char *)view.buf, view.len); + PyBuffer_Release(&view); + if (*cmd_copy == NULL) { + return NULL; + } + str = PyBytes_AS_STRING(*cmd_copy); + size = PyBytes_GET_SIZE(*cmd_copy); } else { PyErr_Format(PyExc_TypeError, @@ -624,7 +641,7 @@ if (strlen(str) != (size_t)size) { PyErr_SetString(PyExc_ValueError, "source code string cannot contain null bytes"); - PyBuffer_Release(view); + Py_CLEAR(*cmd_copy); return NULL; } return str; @@ -660,7 +677,7 @@ int dont_inherit, int optimize) /*[clinic end generated code: output=31881762c1bb90c4 input=9d53e8cfb3c86414]*/ { - Py_buffer view = {NULL, NULL}; + PyObject *source_copy; const char *str; int compile_mode = -1; int is_ast; @@ -732,12 +749,12 @@ goto finally; } - str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view); + str = source_as_string(source, "compile", "string, bytes or AST", &cf, &source_copy); if (str == NULL) goto error; result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); - PyBuffer_Release(&view); + Py_XDECREF(source_copy); goto finally; error: @@ -812,8 +829,7 @@ PyObject *locals) /*[clinic end generated code: output=7284501fb7b4d666 input=11ee718a8640e527]*/ { - PyObject *result, *tmp = NULL; - Py_buffer view = {NULL, NULL}; + PyObject *result, *source_copy; const char *str; PyCompilerFlags cf; @@ -861,7 +877,7 @@ } cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(source, "eval", "string, bytes or code", &cf, &view); + str = source_as_string(source, "eval", "string, bytes or code", &cf, &source_copy); if (str == NULL) return NULL; @@ -870,8 +886,7 @@ (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); - PyBuffer_Release(&view); - Py_XDECREF(tmp); + Py_XDECREF(source_copy); return result; } @@ -942,12 +957,13 @@ v = PyEval_EvalCode(source, globals, locals); } else { - Py_buffer view = {NULL, NULL}; + PyObject *source_copy; const char *str; PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; str = source_as_string(source, "exec", - "string, bytes or code", &cf, &view); + "string, bytes or code", &cf, + &source_copy); if (str == NULL) return NULL; if (PyEval_MergeCompilerFlags(&cf)) @@ -955,7 +971,7 @@ locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals); - PyBuffer_Release(&view); + Py_XDECREF(source_copy); } if (v == NULL) return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 6 22:33:10 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 03:33:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324802=3A_Merge_null_termination_fixes_from_3=2E?= =?utf-8?q?5?= Message-ID: <20151107033310.19508.74107@psf.io> https://hg.python.org/cpython/rev/4df1eaecb506 changeset: 98994:4df1eaecb506 parent: 98991:c495c9dd7726 parent: 98993:95b9c07b27f7 user: Martin Panter date: Sat Nov 07 03:15:32 2015 +0000 summary: Issue #24802: Merge null termination fixes from 3.5 files: Lib/test/test_compile.py | 21 ++++++++++++ Lib/test/test_float.py | 38 +++++++++++++++++++++- Lib/test/test_int.py | 42 +++++++++++++++++++----- Misc/NEWS | 8 ++++ Objects/abstract.c | 22 +++++++++++- Objects/complexobject.c | 7 ---- Objects/floatobject.c | 15 ++++++++ Python/bltinmodule.c | 48 ++++++++++++++++++--------- 8 files changed, 165 insertions(+), 36 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -542,6 +542,27 @@ check_limit("a", "[0]") check_limit("a", "*a") + def test_null_terminated(self): + # The source code is null-terminated internally, but bytes-like + # objects are accepted, which could be not terminated. + # Exception changed from TypeError to ValueError in 3.5 + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile("123\x00", "", "eval") + with self.assertRaisesRegex(Exception, "cannot contain null"): + compile(memoryview(b"123\x00"), "", "eval") + code = compile(memoryview(b"123\x00")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"1234")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + code = compile(memoryview(b"$23$")[1:-1], "", "eval") + self.assertEqual(eval(code), 23) + + # Also test when eval() and exec() do the compilation step + self.assertEqual(eval(memoryview(b"1234")[1:-1]), 23) + namespace = dict() + exec(memoryview(b"ax = 123")[1:-1], namespace) + self.assertEqual(namespace['x'], 12) + class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -31,7 +31,6 @@ self.assertEqual(float(3.14), 3.14) self.assertEqual(float(314), 314.0) self.assertEqual(float(" 3.14 "), 3.14) - self.assertEqual(float(b" 3.14 "), 3.14) self.assertRaises(ValueError, float, " 0x3.1 ") self.assertRaises(ValueError, float, " -0x3.p-1 ") self.assertRaises(ValueError, float, " +0x3.p-1 ") @@ -43,7 +42,6 @@ self.assertRaises(ValueError, float, "+.inf") self.assertRaises(ValueError, float, ".") self.assertRaises(ValueError, float, "-.") - self.assertRaises(ValueError, float, b"-") self.assertRaises(TypeError, float, {}) self.assertRaisesRegex(TypeError, "not 'dict'", float, {}) # Lone surrogate @@ -57,6 +55,42 @@ float(b'.' + b'1'*1000) float('.' + '1'*1000) + def test_non_numeric_input_types(self): + # Test possible non-numeric types for the argument x, including + # subclasses of the explicitly documented accepted types. + class CustomStr(str): pass + class CustomBytes(bytes): pass + class CustomByteArray(bytearray): pass + + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) + + for f in factories: + x = f(b" 3.14 ") + with self.subTest(type(x)): + self.assertEqual(float(x), 3.14) + with self.assertRaisesRegex(ValueError, "could not convert"): + float(f(b'A' * 0x10)) + + def test_float_memoryview(self): + self.assertEqual(float(memoryview(b'12.3')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3\x00')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3 ')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.3A')[1:4]), 2.3) + self.assertEqual(float(memoryview(b'12.34')[1:4]), 2.3) + def test_error_message(self): testlist = ('\xbd', '123\xbd', ' 123 456 ') for s in testlist: diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -276,16 +276,40 @@ class CustomBytes(bytes): pass class CustomByteArray(bytearray): pass - values = [b'100', - bytearray(b'100'), - CustomStr('100'), - CustomBytes(b'100'), - CustomByteArray(b'100')] + factories = [ + bytes, + bytearray, + lambda b: CustomStr(b.decode()), + CustomBytes, + CustomByteArray, + memoryview, + ] + try: + from array import array + except ImportError: + pass + else: + factories.append(lambda b: array('B', b)) - for x in values: - msg = 'x has type %s' % type(x).__name__ - self.assertEqual(int(x), 100, msg=msg) - self.assertEqual(int(x, 2), 4, msg=msg) + for f in factories: + x = f(b'100') + with self.subTest(type(x)): + self.assertEqual(int(x), 100) + if isinstance(x, (str, bytes, bytearray)): + self.assertEqual(int(x, 2), 4) + else: + msg = "can't convert non-string" + with self.assertRaisesRegex(TypeError, msg): + int(x, 2) + with self.assertRaisesRegex(ValueError, 'invalid literal'): + int(f(b'A' * 0x10)) + + def test_int_memoryview(self): + self.assertEqual(int(memoryview(b'123')[1:3]), 23) + self.assertEqual(int(memoryview(b'123\x00')[1:3]), 23) + self.assertEqual(int(memoryview(b'123 ')[1:3]), 23) + self.assertEqual(int(memoryview(b'123A')[1:3]), 23) + self.assertEqual(int(memoryview(b'1234')[1:3]), 23) def test_string_float(self): self.assertRaises(ValueError, int, '1.2') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + - Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node when compiling AST from Python objects. @@ -357,6 +361,10 @@ Core and Builtins ----------------- +- Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() + and eval() are passed bytes-like objects. These objects are not + necessarily terminated by a null byte, but the functions assumed they were. + - Issue #24402: Fix input() to prompt to the redirected stdout when sys.stdout.fileno() fails. diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1312,12 +1312,30 @@ /* The below check is done in PyLong_FromUnicode(). */ return PyLong_FromUnicodeObject(o, 10); - if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + if (PyBytes_Check(o)) /* need to do extra error checking that PyLong_FromString() * doesn't do. In particular int('9\x005') must raise an * exception, not truncate at the null. */ - PyObject *result = _PyLong_FromBytes(view.buf, view.len, 10); + return _PyLong_FromBytes(PyBytes_AS_STRING(o), + PyBytes_GET_SIZE(o), 10); + + if (PyByteArray_Check(o)) + return _PyLong_FromBytes(PyByteArray_AS_STRING(o), + PyByteArray_GET_SIZE(o), 10); + + if (PyObject_GetBuffer(o, &view, PyBUF_SIMPLE) == 0) { + PyObject *result, *bytes; + + /* Copy to NUL-terminated buffer. */ + bytes = PyBytes_FromStringAndSize((const char *)view.buf, view.len); + if (bytes == NULL) { + PyBuffer_Release(&view); + return NULL; + } + result = _PyLong_FromBytes(PyBytes_AS_STRING(bytes), + PyBytes_GET_SIZE(bytes), 10); + Py_DECREF(bytes); PyBuffer_Release(&view); return result; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -767,7 +767,6 @@ int got_bracket=0; PyObject *s_buffer = NULL; Py_ssize_t len; - Py_buffer view = {NULL, NULL}; if (PyUnicode_Check(v)) { s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v); @@ -777,10 +776,6 @@ if (s == NULL) goto error; } - else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { - s = (const char *)view.buf; - len = view.len; - } else { PyErr_Format(PyExc_TypeError, "complex() argument must be a string or a number, not '%.200s'", @@ -895,7 +890,6 @@ if (s-start != len) goto parse_error; - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return complex_subtype_from_doubles(type, x, y); @@ -903,7 +897,6 @@ PyErr_SetString(PyExc_ValueError, "complex() arg is a malformed string"); error: - PyBuffer_Release(&view); Py_XDECREF(s_buffer); return NULL; } diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -144,9 +144,24 @@ return NULL; } } + else if (PyBytes_Check(v)) { + s = PyBytes_AS_STRING(v); + len = PyBytes_GET_SIZE(v); + } + else if (PyByteArray_Check(v)) { + s = PyByteArray_AS_STRING(v); + len = PyByteArray_GET_SIZE(v); + } else if (PyObject_GetBuffer(v, &view, PyBUF_SIMPLE) == 0) { s = (const char *)view.buf; len = view.len; + /* Copy to NUL-terminated buffer. */ + s_buffer = PyBytes_FromStringAndSize(s, len); + if (s_buffer == NULL) { + PyBuffer_Release(&view); + return NULL; + } + s = PyBytes_AS_STRING(s_buffer); } else { PyErr_Format(PyExc_TypeError, diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -599,20 +599,37 @@ static const char * -source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, Py_buffer *view) +source_as_string(PyObject *cmd, const char *funcname, const char *what, PyCompilerFlags *cf, PyObject **cmd_copy) { const char *str; Py_ssize_t size; + Py_buffer view; + *cmd_copy = NULL; if (PyUnicode_Check(cmd)) { cf->cf_flags |= PyCF_IGNORE_COOKIE; str = PyUnicode_AsUTF8AndSize(cmd, &size); if (str == NULL) return NULL; } - else if (PyObject_GetBuffer(cmd, view, PyBUF_SIMPLE) == 0) { - str = (const char *)view->buf; - size = view->len; + else if (PyBytes_Check(cmd)) { + str = PyBytes_AS_STRING(cmd); + size = PyBytes_GET_SIZE(cmd); + } + else if (PyByteArray_Check(cmd)) { + str = PyByteArray_AS_STRING(cmd); + size = PyByteArray_GET_SIZE(cmd); + } + else if (PyObject_GetBuffer(cmd, &view, PyBUF_SIMPLE) == 0) { + /* Copy to NUL-terminated buffer. */ + *cmd_copy = PyBytes_FromStringAndSize( + (const char *)view.buf, view.len); + PyBuffer_Release(&view); + if (*cmd_copy == NULL) { + return NULL; + } + str = PyBytes_AS_STRING(*cmd_copy); + size = PyBytes_GET_SIZE(*cmd_copy); } else { PyErr_Format(PyExc_TypeError, @@ -624,7 +641,7 @@ if (strlen(str) != (size_t)size) { PyErr_SetString(PyExc_ValueError, "source code string cannot contain null bytes"); - PyBuffer_Release(view); + Py_CLEAR(*cmd_copy); return NULL; } return str; @@ -660,7 +677,7 @@ int dont_inherit, int optimize) /*[clinic end generated code: output=31881762c1bb90c4 input=9d53e8cfb3c86414]*/ { - Py_buffer view = {NULL, NULL}; + PyObject *source_copy; const char *str; int compile_mode = -1; int is_ast; @@ -732,12 +749,12 @@ goto finally; } - str = source_as_string(source, "compile", "string, bytes or AST", &cf, &view); + str = source_as_string(source, "compile", "string, bytes or AST", &cf, &source_copy); if (str == NULL) goto error; result = Py_CompileStringObject(str, filename, start[compile_mode], &cf, optimize); - PyBuffer_Release(&view); + Py_XDECREF(source_copy); goto finally; error: @@ -812,8 +829,7 @@ PyObject *locals) /*[clinic end generated code: output=7284501fb7b4d666 input=11ee718a8640e527]*/ { - PyObject *result, *tmp = NULL; - Py_buffer view = {NULL, NULL}; + PyObject *result, *source_copy; const char *str; PyCompilerFlags cf; @@ -861,7 +877,7 @@ } cf.cf_flags = PyCF_SOURCE_IS_UTF8; - str = source_as_string(source, "eval", "string, bytes or code", &cf, &view); + str = source_as_string(source, "eval", "string, bytes or code", &cf, &source_copy); if (str == NULL) return NULL; @@ -870,8 +886,7 @@ (void)PyEval_MergeCompilerFlags(&cf); result = PyRun_StringFlags(str, Py_eval_input, globals, locals, &cf); - PyBuffer_Release(&view); - Py_XDECREF(tmp); + Py_XDECREF(source_copy); return result; } @@ -942,12 +957,13 @@ v = PyEval_EvalCode(source, globals, locals); } else { - Py_buffer view = {NULL, NULL}; + PyObject *source_copy; const char *str; PyCompilerFlags cf; cf.cf_flags = PyCF_SOURCE_IS_UTF8; str = source_as_string(source, "exec", - "string, bytes or code", &cf, &view); + "string, bytes or code", &cf, + &source_copy); if (str == NULL) return NULL; if (PyEval_MergeCompilerFlags(&cf)) @@ -955,7 +971,7 @@ locals, &cf); else v = PyRun_String(str, Py_file_input, globals, locals); - PyBuffer_Release(&view); + Py_XDECREF(source_copy); } if (v == NULL) return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 01:00:59 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 07 Nov 2015 06:00:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzE4MDEw?= =?utf-8?q?=3A_Fix_pydoc_GUI_search_to_handle_package_exceptions?= Message-ID: <20151107060056.33558.74010@psf.io> https://hg.python.org/cpython/rev/1ab20d3c9dc6 changeset: 98995:1ab20d3c9dc6 branch: 2.7 parent: 98977:92dda5f00b0f user: Martin Panter date: Sat Nov 07 05:41:47 2015 +0000 summary: Issue #18010: Fix pydoc GUI search to handle package exceptions files: Lib/pydoc.py | 5 ++++- Misc/NEWS | 3 +++ 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Lib/pydoc.py b/Lib/pydoc.py --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -2244,8 +2244,11 @@ if self.scanner: self.scanner.quit = 1 self.scanner = ModuleScanner() + def onerror(modname): + pass threading.Thread(target=self.scanner.run, - args=(self.update, key, self.done)).start() + args=(self.update, key, self.done), + kwargs=dict(onerror=onerror)).start() def update(self, path, modname, desc): if modname[-9:] == '.__init__': diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,9 @@ Library ------- +- Issue #18010: Fix the pydoc GUI's search function to handle exceptions + from importing packages. + - Issue #25515: Always use os.urandom as a source of randomness in uuid.uuid4. - Issue #21827: Fixed textwrap.dedent() for the case when largest common -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sat Nov 7 03:44:05 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 07 Nov 2015 08:44:05 +0000 Subject: [Python-checkins] Daily reference leaks (4df1eaecb506): sum=7 Message-ID: <20151107084405.24924.90737@psf.io> results for 4df1eaecb506 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogupW0N9', '--timeout', '7200'] From python-checkins at python.org Sat Nov 7 04:17:37 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 09:17:37 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzg5Mjkw?= =?utf-8?q?2=3A_Added_new_tests_for_pickling_recursive_collections=2E?= Message-ID: <20151107091737.58415.15589@psf.io> https://hg.python.org/cpython/rev/2071d16ed5e6 changeset: 98997:2071d16ed5e6 branch: 3.4 parent: 98992:a75336ac40e0 user: Serhiy Storchaka date: Sat Nov 07 11:16:10 2015 +0200 summary: Issue #892902: Added new tests for pickling recursive collections. files: Lib/test/pickletester.py | 120 +++++++++++++++++++++++--- 1 files changed, 104 insertions(+), 16 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -103,6 +103,15 @@ class H(object): pass +# Hashable mutable key +class K(object): + def __init__(self, value): + self.value = value + + def __reduce__(self): + # Shouldn't support the recursion itself + return K, (self.value,) + import __main__ __main__.C = C C.__module__ = "__main__" @@ -112,6 +121,8 @@ E.__module__ = "__main__" __main__.H = H H.__module__ = "__main__" +__main__.K = K +K.__module__ = "__main__" class myint(int): def __init__(self, x): @@ -1041,9 +1052,9 @@ x = self.loads(s) self.assertIsInstance(x, list) self.assertEqual(len(x), 1) - self.assertTrue(x is x[0]) + self.assertIs(x[0], x) - def test_recursive_tuple(self): + def test_recursive_tuple_and_list(self): t = ([],) t[0].append(t) for proto in protocols: @@ -1051,8 +1062,9 @@ x = self.loads(s) self.assertIsInstance(x, tuple) self.assertEqual(len(x), 1) + self.assertIsInstance(x[0], list) self.assertEqual(len(x[0]), 1) - self.assertTrue(x is x[0][0]) + self.assertIs(x[0][0], x) def test_recursive_dict(self): d = {} @@ -1062,29 +1074,63 @@ x = self.loads(s) self.assertIsInstance(x, dict) self.assertEqual(list(x.keys()), [1]) - self.assertTrue(x[1] is x) + self.assertIs(x[1], x) + + def test_recursive_dict_key(self): + d = {} + k = K(d) + d[k] = 1 + for proto in protocols: + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, dict) + self.assertEqual(len(x.keys()), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_set(self): - h = H() - y = set({h}) - h.attr = y - for proto in protocols: + y = set() + k = K(y) + y.add(k) + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) self.assertIsInstance(x, set) - self.assertIs(list(x)[0].attr, x) self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], K) + self.assertIs(list(x)[0].value, x) - def test_recursive_frozenset(self): - h = H() - y = frozenset({h}) - h.attr = y - for proto in protocols: + def test_recursive_list_subclass(self): + y = MyList() + y.append(y) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) - self.assertIsInstance(x, frozenset) - self.assertIs(list(x)[0].attr, x) + self.assertIsInstance(x, MyList) self.assertEqual(len(x), 1) + self.assertIs(x[0], x) + + def test_recursive_dict_subclass(self): + d = MyDict() + d[1] = d + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(list(x.keys()), [1]) + self.assertIs(x[1], x) + + def test_recursive_dict_subclass_key(self): + d = MyDict() + k = K(d) + d[k] = 1 + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(len(list(x.keys())), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_inst(self): i = C() @@ -1111,6 +1157,48 @@ self.assertEqual(list(x[0].attr.keys()), [1]) self.assertTrue(x[0].attr[1] is x) + def check_recursive_collection_and_inst(self, factory): + h = H() + y = factory([h]) + h.attr = y + for proto in protocols: + s = self.dumps(y, proto) + x = self.loads(s) + self.assertIsInstance(x, type(y)) + self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], H) + self.assertIs(list(x)[0].attr, x) + + def test_recursive_list_and_inst(self): + self.check_recursive_collection_and_inst(list) + + def test_recursive_tuple_and_inst(self): + self.check_recursive_collection_and_inst(tuple) + + def test_recursive_dict_and_inst(self): + self.check_recursive_collection_and_inst(dict.fromkeys) + + def test_recursive_set_and_inst(self): + self.check_recursive_collection_and_inst(set) + + def test_recursive_frozenset_and_inst(self): + self.check_recursive_collection_and_inst(frozenset) + + def test_recursive_list_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyList) + + def test_recursive_tuple_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyTuple) + + def test_recursive_dict_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyDict.fromkeys) + + def test_recursive_set_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MySet) + + def test_recursive_frozenset_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyFrozenSet) + def test_unicode(self): endcases = ['', '<\\u>', '<\\\u1234>', '<\n>', '<\\>', '<\\\U00012345>', -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 04:17:37 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 09:17:37 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=23892902=3A_Added_new_tests_for_pickling_recursive_coll?= =?utf-8?q?ections=2E?= Message-ID: <20151107091737.33552.96697@psf.io> https://hg.python.org/cpython/rev/f33ce913220b changeset: 98998:f33ce913220b branch: 3.5 parent: 98993:95b9c07b27f7 parent: 98997:2071d16ed5e6 user: Serhiy Storchaka date: Sat Nov 07 11:17:02 2015 +0200 summary: Issue #892902: Added new tests for pickling recursive collections. files: Lib/test/pickletester.py | 120 +++++++++++++++++++++++--- 1 files changed, 104 insertions(+), 16 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -103,6 +103,15 @@ class H(object): pass +# Hashable mutable key +class K(object): + def __init__(self, value): + self.value = value + + def __reduce__(self): + # Shouldn't support the recursion itself + return K, (self.value,) + import __main__ __main__.C = C C.__module__ = "__main__" @@ -112,6 +121,8 @@ E.__module__ = "__main__" __main__.H = H H.__module__ = "__main__" +__main__.K = K +K.__module__ = "__main__" class myint(int): def __init__(self, x): @@ -1041,9 +1052,9 @@ x = self.loads(s) self.assertIsInstance(x, list) self.assertEqual(len(x), 1) - self.assertTrue(x is x[0]) + self.assertIs(x[0], x) - def test_recursive_tuple(self): + def test_recursive_tuple_and_list(self): t = ([],) t[0].append(t) for proto in protocols: @@ -1051,8 +1062,9 @@ x = self.loads(s) self.assertIsInstance(x, tuple) self.assertEqual(len(x), 1) + self.assertIsInstance(x[0], list) self.assertEqual(len(x[0]), 1) - self.assertTrue(x is x[0][0]) + self.assertIs(x[0][0], x) def test_recursive_dict(self): d = {} @@ -1062,29 +1074,63 @@ x = self.loads(s) self.assertIsInstance(x, dict) self.assertEqual(list(x.keys()), [1]) - self.assertTrue(x[1] is x) + self.assertIs(x[1], x) + + def test_recursive_dict_key(self): + d = {} + k = K(d) + d[k] = 1 + for proto in protocols: + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, dict) + self.assertEqual(len(x.keys()), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_set(self): - h = H() - y = set({h}) - h.attr = y - for proto in protocols: + y = set() + k = K(y) + y.add(k) + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) self.assertIsInstance(x, set) - self.assertIs(list(x)[0].attr, x) self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], K) + self.assertIs(list(x)[0].value, x) - def test_recursive_frozenset(self): - h = H() - y = frozenset({h}) - h.attr = y - for proto in protocols: + def test_recursive_list_subclass(self): + y = MyList() + y.append(y) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) - self.assertIsInstance(x, frozenset) - self.assertIs(list(x)[0].attr, x) + self.assertIsInstance(x, MyList) self.assertEqual(len(x), 1) + self.assertIs(x[0], x) + + def test_recursive_dict_subclass(self): + d = MyDict() + d[1] = d + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(list(x.keys()), [1]) + self.assertIs(x[1], x) + + def test_recursive_dict_subclass_key(self): + d = MyDict() + k = K(d) + d[k] = 1 + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(len(list(x.keys())), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_inst(self): i = C() @@ -1111,6 +1157,48 @@ self.assertEqual(list(x[0].attr.keys()), [1]) self.assertTrue(x[0].attr[1] is x) + def check_recursive_collection_and_inst(self, factory): + h = H() + y = factory([h]) + h.attr = y + for proto in protocols: + s = self.dumps(y, proto) + x = self.loads(s) + self.assertIsInstance(x, type(y)) + self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], H) + self.assertIs(list(x)[0].attr, x) + + def test_recursive_list_and_inst(self): + self.check_recursive_collection_and_inst(list) + + def test_recursive_tuple_and_inst(self): + self.check_recursive_collection_and_inst(tuple) + + def test_recursive_dict_and_inst(self): + self.check_recursive_collection_and_inst(dict.fromkeys) + + def test_recursive_set_and_inst(self): + self.check_recursive_collection_and_inst(set) + + def test_recursive_frozenset_and_inst(self): + self.check_recursive_collection_and_inst(frozenset) + + def test_recursive_list_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyList) + + def test_recursive_tuple_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyTuple) + + def test_recursive_dict_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyDict.fromkeys) + + def test_recursive_set_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MySet) + + def test_recursive_frozenset_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyFrozenSet) + def test_unicode(self): endcases = ['', '<\\u>', '<\\\u1234>', '<\n>', '<\\>', '<\\\U00012345>', -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 04:17:37 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 09:17:37 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzg5Mjkw?= =?utf-8?q?2=3A_Fixed_pickling_recursive_objects=2E?= Message-ID: <20151107091736.16161.65431@psf.io> https://hg.python.org/cpython/rev/9ad1fd251ddf changeset: 98996:9ad1fd251ddf branch: 2.7 user: Serhiy Storchaka date: Sat Nov 07 11:15:32 2015 +0200 summary: Issue #892902: Fixed pickling recursive objects. files: Lib/pickle.py | 8 +- Lib/test/pickletester.py | 105 +++++++++++++++++++++++++- Lib/test/test_cpickle.py | 39 +++------ Misc/NEWS | 2 + Modules/cPickle.c | 21 +++++ 5 files changed, 145 insertions(+), 30 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -402,7 +402,13 @@ write(REDUCE) if obj is not None: - self.memoize(obj) + # If the object is already in the memo, this means it is + # recursive. In this case, throw away everything we put on the + # stack, and fetch the object back from the memo. + if id(obj) in self.memo: + write(POP + self.get(self.memo[id(obj)][0])) + else: + self.memoize(obj) # More new special cases (that work with older protocols as # well): when __reduce__ returns a tuple with 4 or 5 items, diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -117,6 +117,18 @@ def __getinitargs__(self): return () +class H(object): + pass + +# Hashable mutable key +class K(object): + def __init__(self, value): + self.value = value + + def __reduce__(self): + # Shouldn't support the recursion itself + return K, (self.value,) + import __main__ __main__.C = C C.__module__ = "__main__" @@ -124,6 +136,10 @@ D.__module__ = "__main__" __main__.E = E E.__module__ = "__main__" +__main__.H = H +H.__module__ = "__main__" +__main__.K = K +K.__module__ = "__main__" class myint(int): def __init__(self, x): @@ -676,18 +692,21 @@ for proto in protocols: s = self.dumps(l, proto) x = self.loads(s) + self.assertIsInstance(x, list) self.assertEqual(len(x), 1) - self.assertTrue(x is x[0]) + self.assertIs(x[0], x) - def test_recursive_tuple(self): + def test_recursive_tuple_and_list(self): t = ([],) t[0].append(t) for proto in protocols: s = self.dumps(t, proto) x = self.loads(s) + self.assertIsInstance(x, tuple) self.assertEqual(len(x), 1) + self.assertIsInstance(x[0], list) self.assertEqual(len(x[0]), 1) - self.assertTrue(x is x[0][0]) + self.assertIs(x[0][0], x) def test_recursive_dict(self): d = {} @@ -695,8 +714,50 @@ for proto in protocols: s = self.dumps(d, proto) x = self.loads(s) + self.assertIsInstance(x, dict) self.assertEqual(x.keys(), [1]) - self.assertTrue(x[1] is x) + self.assertIs(x[1], x) + + def test_recursive_dict_key(self): + d = {} + k = K(d) + d[k] = 1 + for proto in protocols: + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, dict) + self.assertEqual(len(x.keys()), 1) + self.assertIsInstance(x.keys()[0], K) + self.assertIs(x.keys()[0].value, x) + + def test_recursive_list_subclass(self): + y = MyList() + y.append(y) + s = self.dumps(y, 2) + x = self.loads(s) + self.assertIsInstance(x, MyList) + self.assertEqual(len(x), 1) + self.assertIs(x[0], x) + + def test_recursive_dict_subclass(self): + d = MyDict() + d[1] = d + s = self.dumps(d, 2) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(x.keys(), [1]) + self.assertIs(x[1], x) + + def test_recursive_dict_subclass_key(self): + d = MyDict() + k = K(d) + d[k] = 1 + s = self.dumps(d, 2) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(len(x.keys()), 1) + self.assertIsInstance(x.keys()[0], K) + self.assertIs(x.keys()[0].value, x) def test_recursive_inst(self): i = C() @@ -721,6 +782,42 @@ self.assertEqual(x[0].attr.keys(), [1]) self.assertTrue(x[0].attr[1] is x) + def check_recursive_collection_and_inst(self, factory): + h = H() + y = factory([h]) + h.attr = y + for proto in protocols: + s = self.dumps(y, proto) + x = self.loads(s) + self.assertIsInstance(x, type(y)) + self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], H) + self.assertIs(list(x)[0].attr, x) + + def test_recursive_list_and_inst(self): + self.check_recursive_collection_and_inst(list) + + def test_recursive_tuple_and_inst(self): + self.check_recursive_collection_and_inst(tuple) + + def test_recursive_dict_and_inst(self): + self.check_recursive_collection_and_inst(dict.fromkeys) + + def test_recursive_set_and_inst(self): + self.check_recursive_collection_and_inst(set) + + def test_recursive_frozenset_and_inst(self): + self.check_recursive_collection_and_inst(frozenset) + + def test_recursive_list_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyList) + + def test_recursive_tuple_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyTuple) + + def test_recursive_dict_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyDict.fromkeys) + if have_unicode: def test_unicode(self): endcases = [u'', u'<\\u>', u'<\\\u1234>', u'<\n>', diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py --- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -1,6 +1,7 @@ import cPickle import cStringIO import io +import functools import unittest from test.pickletester import (AbstractUnpickleTests, AbstractPickleTests, @@ -151,31 +152,6 @@ finally: self.close(f) - def test_recursive_list(self): - self.assertRaises(ValueError, - AbstractPickleTests.test_recursive_list, - self) - - def test_recursive_tuple(self): - self.assertRaises(ValueError, - AbstractPickleTests.test_recursive_tuple, - self) - - def test_recursive_inst(self): - self.assertRaises(ValueError, - AbstractPickleTests.test_recursive_inst, - self) - - def test_recursive_dict(self): - self.assertRaises(ValueError, - AbstractPickleTests.test_recursive_dict, - self) - - def test_recursive_multi(self): - self.assertRaises(ValueError, - AbstractPickleTests.test_recursive_multi, - self) - def test_nonrecursive_deep(self): # If it's not cyclic, it should pickle OK even if the nesting # depth exceeds PY_CPICKLE_FAST_LIMIT. That happens to be @@ -187,6 +163,19 @@ b = self.loads(self.dumps(a)) self.assertEqual(a, b) +for name in dir(AbstractPickleTests): + if name.startswith('test_recursive_'): + func = getattr(AbstractPickleTests, name) + if '_subclass' in name and '_and_inst' not in name: + assert_args = RuntimeError, 'maximum recursion depth exceeded' + else: + assert_args = ValueError, "can't pickle cyclic objects" + def wrapper(self, func=func, assert_args=assert_args): + with self.assertRaisesRegexp(*assert_args): + func(self) + functools.update_wrapper(wrapper, func) + setattr(cPickleFastPicklerTests, name, wrapper) + class cStringIOCPicklerFastTests(cStringIOMixin, cPickleFastPicklerTests): pass diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,6 +46,8 @@ Library ------- +- Issue #892902: Fixed pickling recursive objects. + - Issue #18010: Fix the pydoc GUI's search function to handle exceptions from importing packages. diff --git a/Modules/cPickle.c b/Modules/cPickle.c --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -2533,6 +2533,27 @@ /* Memoize. */ /* XXX How can ob be NULL? */ if (ob != NULL) { + /* If the object is already in the memo, this means it is + recursive. In this case, throw away everything we put on the + stack, and fetch the object back from the memo. */ + if (Py_REFCNT(ob) > 1 && !self->fast) { + PyObject *py_ob_id = PyLong_FromVoidPtr(ob); + if (!py_ob_id) + return -1; + if (PyDict_GetItem(self->memo, py_ob_id)) { + const char pop_op = POP; + if (self->write_func(self, &pop_op, 1) < 0 || + get(self, py_ob_id) < 0) { + Py_DECREF(py_ob_id); + return -1; + } + Py_DECREF(py_ob_id); + return 0; + } + Py_DECREF(py_ob_id); + if (PyErr_Occurred()) + return -1; + } if (state && !PyDict_Check(state)) { if (put2(self, ob) < 0) return -1; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 04:17:42 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 09:17:42 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=23892902=3A_Added_new_tests_for_pickling_recursiv?= =?utf-8?q?e_collections=2E?= Message-ID: <20151107091742.24938.41731@psf.io> https://hg.python.org/cpython/rev/2c81a883d8ca changeset: 98999:2c81a883d8ca parent: 98994:4df1eaecb506 parent: 98998:f33ce913220b user: Serhiy Storchaka date: Sat Nov 07 11:17:15 2015 +0200 summary: Issue #892902: Added new tests for pickling recursive collections. files: Lib/test/pickletester.py | 120 +++++++++++++++++++++++--- 1 files changed, 104 insertions(+), 16 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -103,6 +103,15 @@ class H(object): pass +# Hashable mutable key +class K(object): + def __init__(self, value): + self.value = value + + def __reduce__(self): + # Shouldn't support the recursion itself + return K, (self.value,) + import __main__ __main__.C = C C.__module__ = "__main__" @@ -112,6 +121,8 @@ E.__module__ = "__main__" __main__.H = H H.__module__ = "__main__" +__main__.K = K +K.__module__ = "__main__" class myint(int): def __init__(self, x): @@ -1041,9 +1052,9 @@ x = self.loads(s) self.assertIsInstance(x, list) self.assertEqual(len(x), 1) - self.assertTrue(x is x[0]) + self.assertIs(x[0], x) - def test_recursive_tuple(self): + def test_recursive_tuple_and_list(self): t = ([],) t[0].append(t) for proto in protocols: @@ -1051,8 +1062,9 @@ x = self.loads(s) self.assertIsInstance(x, tuple) self.assertEqual(len(x), 1) + self.assertIsInstance(x[0], list) self.assertEqual(len(x[0]), 1) - self.assertTrue(x is x[0][0]) + self.assertIs(x[0][0], x) def test_recursive_dict(self): d = {} @@ -1062,29 +1074,63 @@ x = self.loads(s) self.assertIsInstance(x, dict) self.assertEqual(list(x.keys()), [1]) - self.assertTrue(x[1] is x) + self.assertIs(x[1], x) + + def test_recursive_dict_key(self): + d = {} + k = K(d) + d[k] = 1 + for proto in protocols: + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, dict) + self.assertEqual(len(x.keys()), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_set(self): - h = H() - y = set({h}) - h.attr = y - for proto in protocols: + y = set() + k = K(y) + y.add(k) + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) self.assertIsInstance(x, set) - self.assertIs(list(x)[0].attr, x) self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], K) + self.assertIs(list(x)[0].value, x) - def test_recursive_frozenset(self): - h = H() - y = frozenset({h}) - h.attr = y - for proto in protocols: + def test_recursive_list_subclass(self): + y = MyList() + y.append(y) + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = self.dumps(y, proto) x = self.loads(s) - self.assertIsInstance(x, frozenset) - self.assertIs(list(x)[0].attr, x) + self.assertIsInstance(x, MyList) self.assertEqual(len(x), 1) + self.assertIs(x[0], x) + + def test_recursive_dict_subclass(self): + d = MyDict() + d[1] = d + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(list(x.keys()), [1]) + self.assertIs(x[1], x) + + def test_recursive_dict_subclass_key(self): + d = MyDict() + k = K(d) + d[k] = 1 + for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + s = self.dumps(d, proto) + x = self.loads(s) + self.assertIsInstance(x, MyDict) + self.assertEqual(len(list(x.keys())), 1) + self.assertIsInstance(list(x.keys())[0], K) + self.assertIs(list(x.keys())[0].value, x) def test_recursive_inst(self): i = C() @@ -1111,6 +1157,48 @@ self.assertEqual(list(x[0].attr.keys()), [1]) self.assertTrue(x[0].attr[1] is x) + def check_recursive_collection_and_inst(self, factory): + h = H() + y = factory([h]) + h.attr = y + for proto in protocols: + s = self.dumps(y, proto) + x = self.loads(s) + self.assertIsInstance(x, type(y)) + self.assertEqual(len(x), 1) + self.assertIsInstance(list(x)[0], H) + self.assertIs(list(x)[0].attr, x) + + def test_recursive_list_and_inst(self): + self.check_recursive_collection_and_inst(list) + + def test_recursive_tuple_and_inst(self): + self.check_recursive_collection_and_inst(tuple) + + def test_recursive_dict_and_inst(self): + self.check_recursive_collection_and_inst(dict.fromkeys) + + def test_recursive_set_and_inst(self): + self.check_recursive_collection_and_inst(set) + + def test_recursive_frozenset_and_inst(self): + self.check_recursive_collection_and_inst(frozenset) + + def test_recursive_list_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyList) + + def test_recursive_tuple_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyTuple) + + def test_recursive_dict_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyDict.fromkeys) + + def test_recursive_set_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MySet) + + def test_recursive_frozenset_subclass_and_inst(self): + self.check_recursive_collection_and_inst(MyFrozenSet) + def test_unicode(self): endcases = ['', '<\\u>', '<\\\u1234>', '<\n>', '<\\>', '<\\\U00012345>', -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 08:43:05 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 13:43:05 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325558=3A_Use_comp?= =?utf-8?q?ile-time_asserts=2E?= Message-ID: <20151107134304.58407.13370@psf.io> https://hg.python.org/cpython/rev/45a404d33c2d changeset: 99000:45a404d33c2d user: Serhiy Storchaka date: Sat Nov 07 15:42:38 2015 +0200 summary: Issue #25558: Use compile-time asserts. files: Include/pymacro.h | 4 ++++ Modules/_ctypes/_ctypes.c | 2 +- Modules/_datetimemodule.c | 6 +++--- Modules/_pickle.c | 2 +- Modules/pyexpat.c | 3 ++- Python/pytime.c | 25 ++++++++++++------------- Python/random.c | 2 +- 7 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Include/pymacro.h b/Include/pymacro.h --- a/Include/pymacro.h +++ b/Include/pymacro.h @@ -36,6 +36,10 @@ #define Py_BUILD_ASSERT_EXPR(cond) \ (sizeof(char [1 - 2*!(cond)]) - 1) +#define Py_BUILD_ASSERT(cond) do { \ + (void)Py_BUILD_ASSERT_EXPR(cond); \ + } while(0) + /* Get the number of elements in a visible array This does not work on pointers, or arrays declared as [], or function diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2386,7 +2386,7 @@ char *cp = string; size_t bytes_left; - assert(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); + Py_BUILD_ASSERT(sizeof(string) - 1 > sizeof(Py_ssize_t) * 2); cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int)); while (target->b_base) { bytes_left = sizeof(string) - (cp - string) - 1; diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c +++ b/Modules/_datetimemodule.c @@ -5329,19 +5329,19 @@ /* A 4-year cycle has an extra leap day over what we'd get from * pasting together 4 single years. */ - assert(DI4Y == 4 * 365 + 1); + Py_BUILD_ASSERT(DI4Y == 4 * 365 + 1); assert(DI4Y == days_before_year(4+1)); /* Similarly, a 400-year cycle has an extra leap day over what we'd * get from pasting together 4 100-year cycles. */ - assert(DI400Y == 4 * DI100Y + 1); + Py_BUILD_ASSERT(DI400Y == 4 * DI100Y + 1); assert(DI400Y == days_before_year(400+1)); /* OTOH, a 100-year cycle has one fewer leap day than we'd get from * pasting together 25 4-year cycles. */ - assert(DI100Y == 25 * DI4Y - 1); + Py_BUILD_ASSERT(DI100Y == 25 * DI4Y - 1); assert(DI100Y == days_before_year(100+1)); one = PyLong_FromLong(1); diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -874,7 +874,7 @@ { size_t i; - assert(sizeof(size_t) <= 8); + Py_BUILD_ASSERT(sizeof(size_t) <= 8); for (i = 0; i < sizeof(size_t); i++) { out[i] = (unsigned char)((value >> (8 * i)) & 0xff); diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -747,7 +747,8 @@ s += MAX_CHUNK_SIZE; slen -= MAX_CHUNK_SIZE; } - assert(MAX_CHUNK_SIZE < INT_MAX && slen < INT_MAX); + Py_BUILD_ASSERT(MAX_CHUNK_SIZE <= INT_MAX); + assert(slen <= INT_MAX); rc = XML_Parse(self->itself, s, (int)slen, isfinal); done: diff --git a/Python/pytime.c b/Python/pytime.c --- a/Python/pytime.c +++ b/Python/pytime.c @@ -43,7 +43,7 @@ val = PyLong_AsLongLong(obj); #else long val; - assert(sizeof(time_t) <= sizeof(long)); + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); val = PyLong_AsLong(obj); #endif if (val == -1 && PyErr_Occurred()) { @@ -60,7 +60,7 @@ #if defined(HAVE_LONG_LONG) && SIZEOF_TIME_T == SIZEOF_LONG_LONG return PyLong_FromLongLong((PY_LONG_LONG)t); #else - assert(sizeof(time_t) <= sizeof(long)); + Py_BUILD_ASSERT(sizeof(time_t) <= sizeof(long)); return PyLong_FromLong((long)t); #endif } @@ -209,6 +209,8 @@ /* ensure that integer overflow cannot happen, int type should have 32 bits, whereas _PyTime_t type has at least 64 bits (SEC_TO_MS takes 30 bits). */ + Py_BUILD_ASSERT(INT_MAX <= _PyTime_MAX / SEC_TO_NS); + Py_BUILD_ASSERT(INT_MIN >= _PyTime_MIN / SEC_TO_NS); assert((t >= 0 && t <= _PyTime_MAX / SEC_TO_NS) || (t < 0 && t >= _PyTime_MIN / SEC_TO_NS)); t *= SEC_TO_NS; @@ -219,7 +221,7 @@ _PyTime_FromNanoseconds(PY_LONG_LONG ns) { _PyTime_t t; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); t = Py_SAFE_DOWNCAST(ns, PY_LONG_LONG, _PyTime_t); return t; } @@ -231,7 +233,7 @@ _PyTime_t t; int res = 0; - assert(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(ts->tv_sec) <= sizeof(_PyTime_t)); t = (_PyTime_t)ts->tv_sec; if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { @@ -253,7 +255,7 @@ _PyTime_t t; int res = 0; - assert(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(tv->tv_sec) <= sizeof(_PyTime_t)); t = (_PyTime_t)tv->tv_sec; if (_PyTime_check_mul_overflow(t, SEC_TO_NS)) { @@ -304,12 +306,12 @@ else { #ifdef HAVE_LONG_LONG PY_LONG_LONG sec; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); sec = PyLong_AsLongLong(obj); #else long sec; - assert(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) <= sizeof(_PyTime_t)); sec = PyLong_AsLong(obj); #endif @@ -364,10 +366,10 @@ _PyTime_AsNanosecondsObject(_PyTime_t t) { #ifdef HAVE_LONG_LONG - assert(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(PY_LONG_LONG) >= sizeof(_PyTime_t)); return PyLong_FromLongLong((PY_LONG_LONG)t); #else - assert(sizeof(long) >= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(long) >= sizeof(_PyTime_t)); return PyLong_FromLong((long)t); #endif } @@ -650,7 +652,7 @@ assert(info == NULL || raise); ticks = GetTickCount64(); - assert(sizeof(ticks) <= sizeof(_PyTime_t)); + Py_BUILD_ASSERT(sizeof(ticks) <= sizeof(_PyTime_t)); t = (_PyTime_t)ticks; if (_PyTime_check_mul_overflow(t, MS_TO_NS)) { @@ -774,8 +776,5 @@ if (_PyTime_GetMonotonicClockWithInfo(&t, NULL) < 0) return -1; - /* check that _PyTime_FromSeconds() cannot overflow */ - assert(INT_MAX <= _PyTime_MAX / SEC_TO_NS); - assert(INT_MIN >= _PyTime_MIN / SEC_TO_NS); return 0; } diff --git a/Python/random.c b/Python/random.c --- a/Python/random.c +++ b/Python/random.c @@ -379,7 +379,7 @@ char *env; unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc; Py_ssize_t secret_size = sizeof(_Py_HashSecret_t); - assert(secret_size == sizeof(_Py_HashSecret.uc)); + Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc)); if (_Py_HashSecret_Initialized) return; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 09:56:00 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 14:56:00 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2322643=3A_Skip_test=5Fcase=5Foperation=5Foverflow_on_c?= =?utf-8?q?omputers_with_low_memory=2E?= Message-ID: <20151107145600.24932.77434@psf.io> https://hg.python.org/cpython/rev/6b00bee218ff changeset: 99002:6b00bee218ff branch: 3.5 parent: 98998:f33ce913220b parent: 99001:5fae49ef94fd user: Serhiy Storchaka date: Sat Nov 07 16:55:16 2015 +0200 summary: Issue #22643: Skip test_case_operation_overflow on computers with low memory. files: Lib/test/test_unicode.py | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -849,7 +849,15 @@ @support.cpython_only def test_case_operation_overflow(self): # Issue #22643 - self.assertRaises(OverflowError, ("?"*(2**32//12 + 1)).upper) + size = 2**32//12 + 1 + try: + s = "?" * size + except MemoryError: + self.skipTest('no enough memory (%.0f MiB required)' % (size / 2**20)) + try: + self.assertRaises(OverflowError, s.upper) + finally: + del s def test_contains(self): # Testing Unicode contains method -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 09:56:00 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 14:56:00 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIyNjQz?= =?utf-8?q?=3A_Skip_test=5Fcase=5Foperation=5Foverflow_on_computers_with_l?= =?utf-8?q?ow_memory=2E?= Message-ID: <20151107145600.115898.58294@psf.io> https://hg.python.org/cpython/rev/5fae49ef94fd changeset: 99001:5fae49ef94fd branch: 3.4 parent: 98997:2071d16ed5e6 user: Serhiy Storchaka date: Sat Nov 07 16:54:48 2015 +0200 summary: Issue #22643: Skip test_case_operation_overflow on computers with low memory. files: Lib/test/test_unicode.py | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -820,7 +820,15 @@ @support.cpython_only def test_case_operation_overflow(self): # Issue #22643 - self.assertRaises(OverflowError, ("?"*(2**32//12 + 1)).upper) + size = 2**32//12 + 1 + try: + s = "?" * size + except MemoryError: + self.skipTest('no enough memory (%.0f MiB required)' % (size / 2**20)) + try: + self.assertRaises(OverflowError, s.upper) + finally: + del s def test_contains(self): # Testing Unicode contains method -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 09:56:00 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 14:56:00 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2322643=3A_Skip_test=5Fcase=5Foperation=5Foverflo?= =?utf-8?q?w_on_computers_with_low_memory=2E?= Message-ID: <20151107145600.103684.91949@psf.io> https://hg.python.org/cpython/rev/b1c5949a3af4 changeset: 99003:b1c5949a3af4 parent: 99000:45a404d33c2d parent: 99002:6b00bee218ff user: Serhiy Storchaka date: Sat Nov 07 16:55:39 2015 +0200 summary: Issue #22643: Skip test_case_operation_overflow on computers with low memory. files: Lib/test/test_unicode.py | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -849,7 +849,15 @@ @support.cpython_only def test_case_operation_overflow(self): # Issue #22643 - self.assertRaises(OverflowError, ("?"*(2**32//12 + 1)).upper) + size = 2**32//12 + 1 + try: + s = "?" * size + except MemoryError: + self.skipTest('no enough memory (%.0f MiB required)' % (size / 2**20)) + try: + self.assertRaises(OverflowError, s.upper) + finally: + del s def test_contains(self): # Testing Unicode contains method -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 11:06:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 16:06:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325263=3A_Trying_t?= =?utf-8?q?o_fix_test=5Fuse_on_Windows=2E?= Message-ID: <20151107160653.19536.95972@psf.io> https://hg.python.org/cpython/rev/d70026504feb changeset: 99004:d70026504feb user: Serhiy Storchaka date: Sat Nov 07 18:06:24 2015 +0200 summary: Issue #25263: Trying to fix test_use on Windows. files: Lib/tkinter/test/test_tkinter/test_widgets.py | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py --- a/Lib/tkinter/test/test_tkinter/test_widgets.py +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py @@ -91,9 +91,10 @@ widget = self.create() self.assertEqual(widget['use'], '') parent = self.create(container=True) - wid = parent.winfo_id() - widget2 = self.create(use=wid) - self.assertEqual(int(widget2['use']), wid) + wid = hex(parent.winfo_id()) + with self.subTest(wid=wid): + widget2 = self.create(use=wid) + self.assertEqual(widget2['use'], wid) @add_standard_options(StandardOptionsTests) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 13:05:40 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 07 Nov 2015 18:05:40 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzg5Mjkw?= =?utf-8?q?2=3A_Disable_newly_added_tests_in_test=5Fxpickle=2E?= Message-ID: <20151107180540.19516.99155@psf.io> https://hg.python.org/cpython/rev/77184a429dae changeset: 99005:77184a429dae branch: 2.7 parent: 98996:9ad1fd251ddf user: Serhiy Storchaka date: Sat Nov 07 20:04:46 2015 +0200 summary: Issue #892902: Disable newly added tests in test_xpickle. files: Lib/test/test_xpickle.py | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_xpickle.py b/Lib/test/test_xpickle.py --- a/Lib/test/test_xpickle.py +++ b/Lib/test/test_xpickle.py @@ -169,6 +169,14 @@ u2 = self.loads(p) self.assertEqual(u2, u) + # The ability to pickle recursive objects was added in 2.7.11 to fix + # a crash in CPickle (issue #892902). + test_recursive_list_subclass_and_inst = None + test_recursive_tuple_subclass_and_inst = None + test_recursive_dict_subclass_and_inst = None + test_recursive_set_and_inst = None + test_recursive_frozenset_and_inst = None + # Test backwards compatibility with Python 2.4. class CPicklePython24Compat(AbstractCompatTests): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 13:09:32 2015 From: python-checkins at python.org (steve.dower) Date: Sat, 07 Nov 2015 18:09:32 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0MzA2?= =?utf-8?q?=3A_Sets_component_ID_for_launcher_to_match_3=2E5_and_later_to_?= =?utf-8?q?avoid?= Message-ID: <20151107180932.16161.74246@psf.io> https://hg.python.org/cpython/rev/6181476b5534 changeset: 99006:6181476b5534 branch: 3.4 parent: 99001:5fae49ef94fd user: Steve Dower date: Sat Nov 07 10:07:04 2015 -0800 summary: Issue #24306: Sets component ID for launcher to match 3.5 and later to avoid downgrading. files: Misc/NEWS | 3 +++ Tools/msi/msi.py | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -708,6 +708,9 @@ Windows ------- +- Issue #24306: Sets component ID for launcher to match 3.5 and later + to avoid downgrading. + - Issue #25022: Removed very outdated PC/example_nt/ directory. diff --git a/Tools/msi/msi.py b/Tools/msi/msi.py --- a/Tools/msi/msi.py +++ b/Tools/msi/msi.py @@ -998,12 +998,14 @@ if launchersrc.lower() == 'pcbuild\\amd64': launchersrc = 'PCBuild' launcher = os.path.join(srcdir, launchersrc, "py.exe") - launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe") + launcherdir.start_component("launcher", flags = 8+256, keyfile="py.exe", + uuid="{B5107402-6958-461B-8B0A-4037D3327160}") launcherdir.add_file(launcher, version=installer.FileVersion(launcher, 0), language=installer.FileVersion(launcher, 1)) launcherw = os.path.join(srcdir, launchersrc, "pyw.exe") - launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe") + launcherdir.start_component("launcherw", flags = 8+256, keyfile="pyw.exe", + uuid="{8E52B8CD-48BB-4D74-84CD-6238BCD11F20}") launcherdir.add_file(launcherw, version=installer.FileVersion(launcherw, 0), language=installer.FileVersion(launcherw, 1)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 13:09:32 2015 From: python-checkins at python.org (steve.dower) Date: Sat, 07 Nov 2015 18:09:32 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Null_merge_from_3=2E4?= Message-ID: <20151107180932.58419.26885@psf.io> https://hg.python.org/cpython/rev/9cd9615263a2 changeset: 99007:9cd9615263a2 branch: 3.5 parent: 99002:6b00bee218ff parent: 99006:6181476b5534 user: Steve Dower date: Sat Nov 07 10:08:04 2015 -0800 summary: Null merge from 3.4 files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 7 13:09:32 2015 From: python-checkins at python.org (steve.dower) Date: Sat, 07 Nov 2015 18:09:32 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Null_merge_from_3=2E4?= Message-ID: <20151107180932.16161.92578@psf.io> https://hg.python.org/cpython/rev/13550b3ca1a6 changeset: 99008:13550b3ca1a6 parent: 99004:d70026504feb parent: 99007:9cd9615263a2 user: Steve Dower date: Sat Nov 07 10:08:53 2015 -0800 summary: Null merge from 3.4 files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 8 01:06:01 2015 From: python-checkins at python.org (r.david.murray) Date: Sun, 08 Nov 2015 06:06:01 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge=3A_=2325446=3A_Fix_regression_in_smtplib=27s_AUTH_?= =?utf-8?q?LOGIN_support=2E?= Message-ID: <20151108060601.16143.95618@psf.io> https://hg.python.org/cpython/rev/7368b86432c6 changeset: 99010:7368b86432c6 parent: 99008:13550b3ca1a6 parent: 99009:d13263ecf0c6 user: R David Murray date: Sun Nov 08 01:05:11 2015 -0500 summary: Merge: #25446: Fix regression in smtplib's AUTH LOGIN support. files: Lib/smtplib.py | 19 +- Lib/test/test_smtplib.py | 179 ++++++++++++++++++-------- Misc/NEWS | 2 + 3 files changed, 132 insertions(+), 68 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -630,12 +630,12 @@ (code, resp) = self.docmd("AUTH", mechanism + " " + response) else: (code, resp) = self.docmd("AUTH", mechanism) - # Server replies with 334 (challenge) or 535 (not supported) - if code == 334: - challenge = base64.decodebytes(resp) - response = encode_base64( - authobject(challenge).encode('ascii'), eol='') - (code, resp) = self.docmd(response) + # If server responds with a challenge, send the response. + if code == 334: + challenge = base64.decodebytes(resp) + response = encode_base64( + authobject(challenge).encode('ascii'), eol='') + (code, resp) = self.docmd(response) if code in (235, 503): return (code, resp) raise SMTPAuthenticationError(code, resp) @@ -657,11 +657,10 @@ def auth_login(self, challenge=None): """ Authobject to use with LOGIN authentication. Requires self.user and self.password to be set.""" - (code, resp) = self.docmd( - encode_base64(self.user.encode('ascii'), eol='')) - if code == 334: + if challenge is None: + return self.user + else: return self.password - raise SMTPAuthenticationError(code, resp) def login(self, user, password, *, initial_response_ok=True): """Log in on an SMTP server that requires authentication. diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1,8 +1,10 @@ import asyncore +import base64 import email.mime.text from email.message import EmailMessage from email.base64mime import body_encode as encode_base64 import email.utils +import hmac import socket import smtpd import smtplib @@ -623,20 +625,12 @@ sim_auth = ('Mr.A at somewhere.com', 'somepassword') sim_cram_md5_challenge = ('PENCeUxFREJoU0NnbmhNWitOMjNGNn' 'dAZWx3b29kLmlubm9zb2Z0LmNvbT4=') -sim_auth_credentials = { - 'login': 'TXIuQUBzb21ld2hlcmUuY29t', - 'plain': 'AE1yLkFAc29tZXdoZXJlLmNvbQBzb21lcGFzc3dvcmQ=', - 'cram-md5': ('TXIUQUBZB21LD2HLCMUUY29TIDG4OWQ0MJ' - 'KWZGQ4ODNMNDA4NTGXMDRLZWMYZJDMODG1'), - } -sim_auth_login_user = 'TXIUQUBZB21LD2HLCMUUY29T' -sim_auth_plain = 'AE1YLKFAC29TZXDOZXJLLMNVBQBZB21LCGFZC3DVCMQ=' - sim_lists = {'list-1':['Mr.A at somewhere.com','Mrs.C at somewhereesle.com'], 'list-2':['Ms.B at xn--fo-fka.com',], } # Simulated SMTP channel & server +class ResponseException(Exception): pass class SimSMTPChannel(smtpd.SMTPChannel): quit_response = None @@ -646,12 +640,109 @@ rcpt_count = 0 rset_count = 0 disconnect = 0 + AUTH = 99 # Add protocol state to enable auth testing. + authenticated_user = None def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( [ "250-{0}\r\n".format(x) for x in extra_features ]) super(SimSMTPChannel, self).__init__(*args, **kw) + # AUTH related stuff. It would be nice if support for this were in smtpd. + def found_terminator(self): + if self.smtp_state == self.AUTH: + line = self._emptystring.join(self.received_lines) + print('Data:', repr(line), file=smtpd.DEBUGSTREAM) + self.received_lines = [] + try: + self.auth_object(line) + except ResponseException as e: + self.smtp_state = self.COMMAND + self.push('%s %s' % (e.smtp_code, e.smtp_error)) + return + super().found_terminator() + + + def smtp_AUTH(self, arg): + if not self.seen_greeting: + self.push('503 Error: send EHLO first') + return + if not self.extended_smtp or 'AUTH' not in self._extrafeatures: + self.push('500 Error: command "AUTH" not recognized') + return + if self.authenticated_user is not None: + self.push( + '503 Bad sequence of commands: already authenticated') + return + args = arg.split() + if len(args) not in [1, 2]: + self.push('501 Syntax: AUTH [initial-response]') + return + auth_object_name = '_auth_%s' % args[0].lower().replace('-', '_') + try: + self.auth_object = getattr(self, auth_object_name) + except AttributeError: + self.push('504 Command parameter not implemented: unsupported ' + ' authentication mechanism {!r}'.format(auth_object_name)) + return + self.smtp_state = self.AUTH + self.auth_object(args[1] if len(args) == 2 else None) + + def _authenticated(self, user, valid): + if valid: + self.authenticated_user = user + self.push('235 Authentication Succeeded') + else: + self.push('535 Authentication credentials invalid') + self.smtp_state = self.COMMAND + + def _decode_base64(self, string): + return base64.decodebytes(string.encode('ascii')).decode('utf-8') + + def _auth_plain(self, arg=None): + if arg is None: + self.push('334 ') + else: + logpass = self._decode_base64(arg) + try: + *_, user, password = logpass.split('\0') + except ValueError as e: + self.push('535 Splitting response {!r} into user and password' + ' failed: {}'.format(logpass, e)) + return + self._authenticated(user, password == sim_auth[1]) + + def _auth_login(self, arg=None): + if arg is None: + # base64 encoded 'Username:' + self.push('334 VXNlcm5hbWU6') + elif not hasattr(self, '_auth_login_user'): + self._auth_login_user = self._decode_base64(arg) + # base64 encoded 'Password:' + self.push('334 UGFzc3dvcmQ6') + else: + password = self._decode_base64(arg) + self._authenticated(self._auth_login_user, password == sim_auth[1]) + del self._auth_login_user + + def _auth_cram_md5(self, arg=None): + if arg is None: + self.push('334 {}'.format(sim_cram_md5_challenge)) + else: + logpass = self._decode_base64(arg) + try: + user, hashed_pass = logpass.split() + except ValueError as e: + self.push('535 Splitting response {!r} into user and password' + 'failed: {}'.format(logpass, e)) + return False + valid_hashed_pass = hmac.HMAC( + sim_auth[1].encode('ascii'), + self._decode_base64(sim_cram_md5_challenge).encode('ascii'), + 'md5').hexdigest() + self._authenticated(user, hashed_pass == valid_hashed_pass) + # end AUTH related stuff. + def smtp_EHLO(self, arg): resp = ('250-testhost\r\n' '250-EXPN\r\n' @@ -683,20 +774,6 @@ else: self.push('550 No access for you!') - def smtp_AUTH(self, arg): - mech = arg.strip().lower() - if mech=='cram-md5': - self.push('334 {}'.format(sim_cram_md5_challenge)) - elif mech not in sim_auth_credentials: - self.push('504 auth type unimplemented') - return - elif mech=='plain': - self.push('334 ') - elif mech=='login': - self.push('334 ') - else: - self.push('550 No access for you!') - def smtp_QUIT(self, arg): if self.quit_response is None: super(SimSMTPChannel, self).smtp_QUIT(arg) @@ -841,63 +918,49 @@ self.assertEqual(smtp.expn(u), expected_unknown) smtp.quit() - # SimSMTPChannel doesn't fully support AUTH because it requires a - # synchronous read to obtain the credentials...so instead smtpd - # sees the credential sent by smtplib's login method as an unknown command, - # which results in smtplib raising an auth error. Fortunately the error - # message contains the encoded credential, so we can partially check that it - # was generated correctly (partially, because the 'word' is uppercased in - # the error message). - def testAUTH_PLAIN(self): self.serv.add_feature("AUTH PLAIN") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1], initial_response_ok=False) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_plain, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_LOGIN(self): self.serv.add_feature("AUTH LOGIN") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_user, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_CRAM_MD5(self): self.serv.add_feature("AUTH CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_credentials['cram-md5'], str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_multiple(self): # Test that multiple authentication methods are tried. self.serv.add_feature("AUTH BOGUS PLAIN LOGIN CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_user, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def test_auth_function(self): - smtp = smtplib.SMTP(HOST, self.port, - local_hostname='localhost', timeout=15) - self.serv.add_feature("AUTH CRAM-MD5") - smtp.user, smtp.password = sim_auth[0], sim_auth[1] - supported = {'CRAM-MD5': smtp.auth_cram_md5, - 'PLAIN': smtp.auth_plain, - 'LOGIN': smtp.auth_login, - } - for mechanism, method in supported.items(): - try: smtp.auth(mechanism, method, initial_response_ok=False) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_credentials[mechanism.lower()].upper(), - str(err)) - smtp.close() + supported = {'CRAM-MD5', 'PLAIN', 'LOGIN'} + for mechanism in supported: + self.serv.add_feature("AUTH {}".format(mechanism)) + for mechanism in supported: + with self.subTest(mechanism=mechanism): + smtp = smtplib.SMTP(HOST, self.port, + local_hostname='localhost', timeout=15) + smtp.ehlo('foo') + smtp.user, smtp.password = sim_auth[0], sim_auth[1] + method = 'auth_' + mechanism.lower().replace('-', '_') + resp = smtp.auth(mechanism, getattr(smtp, method)) + self.assertEqual(resp, (235, b'Authentication Succeeded')) + smtp.close() def test_quit_resets_greeting(self): smtp = smtplib.SMTP(HOST, self.port, diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -79,6 +79,8 @@ Library ------- +- Issue #25446: Fix regression in smtplib's AUTH LOGIN support. + - Issue #18010: Fix the pydoc web server's module search function to handle exceptions from importing packages. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 8 01:06:01 2015 From: python-checkins at python.org (r.david.murray) Date: Sun, 08 Nov 2015 06:06:01 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogIzI1NDQ2OiBGaXgg?= =?utf-8?q?regression_in_smtplib=27s_AUTH_LOGIN_support=2E?= Message-ID: <20151108060601.115884.54051@psf.io> https://hg.python.org/cpython/rev/d13263ecf0c6 changeset: 99009:d13263ecf0c6 branch: 3.5 parent: 99007:9cd9615263a2 user: R David Murray date: Sun Nov 08 01:03:52 2015 -0500 summary: #25446: Fix regression in smtplib's AUTH LOGIN support. The auth method tests simply weren't adequate because of the fact that smtpd doesn't support authentication. I borrowed some of Milan's code for that from issue #21935 and added it to the smtplib tests. Also discovered that the direct test for the 'auth' method wasn't actually testing anything and fixed it. The fix makes the new authobject mechanism work the way it is documented...the problem was that wasn't checking for a 334 return code if an initial-response was provided, which works fine for auth plain and cram-md5, but not for auth login. files: Lib/smtplib.py | 19 +- Lib/test/test_smtplib.py | 179 ++++++++++++++++++-------- Misc/NEWS | 2 + 3 files changed, 132 insertions(+), 68 deletions(-) diff --git a/Lib/smtplib.py b/Lib/smtplib.py --- a/Lib/smtplib.py +++ b/Lib/smtplib.py @@ -630,12 +630,12 @@ (code, resp) = self.docmd("AUTH", mechanism + " " + response) else: (code, resp) = self.docmd("AUTH", mechanism) - # Server replies with 334 (challenge) or 535 (not supported) - if code == 334: - challenge = base64.decodebytes(resp) - response = encode_base64( - authobject(challenge).encode('ascii'), eol='') - (code, resp) = self.docmd(response) + # If server responds with a challenge, send the response. + if code == 334: + challenge = base64.decodebytes(resp) + response = encode_base64( + authobject(challenge).encode('ascii'), eol='') + (code, resp) = self.docmd(response) if code in (235, 503): return (code, resp) raise SMTPAuthenticationError(code, resp) @@ -657,11 +657,10 @@ def auth_login(self, challenge=None): """ Authobject to use with LOGIN authentication. Requires self.user and self.password to be set.""" - (code, resp) = self.docmd( - encode_base64(self.user.encode('ascii'), eol='')) - if code == 334: + if challenge is None: + return self.user + else: return self.password - raise SMTPAuthenticationError(code, resp) def login(self, user, password, *, initial_response_ok=True): """Log in on an SMTP server that requires authentication. diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -1,8 +1,10 @@ import asyncore +import base64 import email.mime.text from email.message import EmailMessage from email.base64mime import body_encode as encode_base64 import email.utils +import hmac import socket import smtpd import smtplib @@ -623,20 +625,12 @@ sim_auth = ('Mr.A at somewhere.com', 'somepassword') sim_cram_md5_challenge = ('PENCeUxFREJoU0NnbmhNWitOMjNGNn' 'dAZWx3b29kLmlubm9zb2Z0LmNvbT4=') -sim_auth_credentials = { - 'login': 'TXIuQUBzb21ld2hlcmUuY29t', - 'plain': 'AE1yLkFAc29tZXdoZXJlLmNvbQBzb21lcGFzc3dvcmQ=', - 'cram-md5': ('TXIUQUBZB21LD2HLCMUUY29TIDG4OWQ0MJ' - 'KWZGQ4ODNMNDA4NTGXMDRLZWMYZJDMODG1'), - } -sim_auth_login_user = 'TXIUQUBZB21LD2HLCMUUY29T' -sim_auth_plain = 'AE1YLKFAC29TZXDOZXJLLMNVBQBZB21LCGFZC3DVCMQ=' - sim_lists = {'list-1':['Mr.A at somewhere.com','Mrs.C at somewhereesle.com'], 'list-2':['Ms.B at xn--fo-fka.com',], } # Simulated SMTP channel & server +class ResponseException(Exception): pass class SimSMTPChannel(smtpd.SMTPChannel): quit_response = None @@ -646,12 +640,109 @@ rcpt_count = 0 rset_count = 0 disconnect = 0 + AUTH = 99 # Add protocol state to enable auth testing. + authenticated_user = None def __init__(self, extra_features, *args, **kw): self._extrafeatures = ''.join( [ "250-{0}\r\n".format(x) for x in extra_features ]) super(SimSMTPChannel, self).__init__(*args, **kw) + # AUTH related stuff. It would be nice if support for this were in smtpd. + def found_terminator(self): + if self.smtp_state == self.AUTH: + line = self._emptystring.join(self.received_lines) + print('Data:', repr(line), file=smtpd.DEBUGSTREAM) + self.received_lines = [] + try: + self.auth_object(line) + except ResponseException as e: + self.smtp_state = self.COMMAND + self.push('%s %s' % (e.smtp_code, e.smtp_error)) + return + super().found_terminator() + + + def smtp_AUTH(self, arg): + if not self.seen_greeting: + self.push('503 Error: send EHLO first') + return + if not self.extended_smtp or 'AUTH' not in self._extrafeatures: + self.push('500 Error: command "AUTH" not recognized') + return + if self.authenticated_user is not None: + self.push( + '503 Bad sequence of commands: already authenticated') + return + args = arg.split() + if len(args) not in [1, 2]: + self.push('501 Syntax: AUTH [initial-response]') + return + auth_object_name = '_auth_%s' % args[0].lower().replace('-', '_') + try: + self.auth_object = getattr(self, auth_object_name) + except AttributeError: + self.push('504 Command parameter not implemented: unsupported ' + ' authentication mechanism {!r}'.format(auth_object_name)) + return + self.smtp_state = self.AUTH + self.auth_object(args[1] if len(args) == 2 else None) + + def _authenticated(self, user, valid): + if valid: + self.authenticated_user = user + self.push('235 Authentication Succeeded') + else: + self.push('535 Authentication credentials invalid') + self.smtp_state = self.COMMAND + + def _decode_base64(self, string): + return base64.decodebytes(string.encode('ascii')).decode('utf-8') + + def _auth_plain(self, arg=None): + if arg is None: + self.push('334 ') + else: + logpass = self._decode_base64(arg) + try: + *_, user, password = logpass.split('\0') + except ValueError as e: + self.push('535 Splitting response {!r} into user and password' + ' failed: {}'.format(logpass, e)) + return + self._authenticated(user, password == sim_auth[1]) + + def _auth_login(self, arg=None): + if arg is None: + # base64 encoded 'Username:' + self.push('334 VXNlcm5hbWU6') + elif not hasattr(self, '_auth_login_user'): + self._auth_login_user = self._decode_base64(arg) + # base64 encoded 'Password:' + self.push('334 UGFzc3dvcmQ6') + else: + password = self._decode_base64(arg) + self._authenticated(self._auth_login_user, password == sim_auth[1]) + del self._auth_login_user + + def _auth_cram_md5(self, arg=None): + if arg is None: + self.push('334 {}'.format(sim_cram_md5_challenge)) + else: + logpass = self._decode_base64(arg) + try: + user, hashed_pass = logpass.split() + except ValueError as e: + self.push('535 Splitting response {!r} into user and password' + 'failed: {}'.format(logpass, e)) + return False + valid_hashed_pass = hmac.HMAC( + sim_auth[1].encode('ascii'), + self._decode_base64(sim_cram_md5_challenge).encode('ascii'), + 'md5').hexdigest() + self._authenticated(user, hashed_pass == valid_hashed_pass) + # end AUTH related stuff. + def smtp_EHLO(self, arg): resp = ('250-testhost\r\n' '250-EXPN\r\n' @@ -683,20 +774,6 @@ else: self.push('550 No access for you!') - def smtp_AUTH(self, arg): - mech = arg.strip().lower() - if mech=='cram-md5': - self.push('334 {}'.format(sim_cram_md5_challenge)) - elif mech not in sim_auth_credentials: - self.push('504 auth type unimplemented') - return - elif mech=='plain': - self.push('334 ') - elif mech=='login': - self.push('334 ') - else: - self.push('550 No access for you!') - def smtp_QUIT(self, arg): if self.quit_response is None: super(SimSMTPChannel, self).smtp_QUIT(arg) @@ -841,63 +918,49 @@ self.assertEqual(smtp.expn(u), expected_unknown) smtp.quit() - # SimSMTPChannel doesn't fully support AUTH because it requires a - # synchronous read to obtain the credentials...so instead smtpd - # sees the credential sent by smtplib's login method as an unknown command, - # which results in smtplib raising an auth error. Fortunately the error - # message contains the encoded credential, so we can partially check that it - # was generated correctly (partially, because the 'word' is uppercased in - # the error message). - def testAUTH_PLAIN(self): self.serv.add_feature("AUTH PLAIN") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1], initial_response_ok=False) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_plain, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_LOGIN(self): self.serv.add_feature("AUTH LOGIN") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_user, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_CRAM_MD5(self): self.serv.add_feature("AUTH CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_credentials['cram-md5'], str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def testAUTH_multiple(self): # Test that multiple authentication methods are tried. self.serv.add_feature("AUTH BOGUS PLAIN LOGIN CRAM-MD5") smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) - try: smtp.login(sim_auth[0], sim_auth[1]) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_login_user, str(err)) + resp = smtp.login(sim_auth[0], sim_auth[1]) + self.assertEqual(resp, (235, b'Authentication Succeeded')) smtp.close() def test_auth_function(self): - smtp = smtplib.SMTP(HOST, self.port, - local_hostname='localhost', timeout=15) - self.serv.add_feature("AUTH CRAM-MD5") - smtp.user, smtp.password = sim_auth[0], sim_auth[1] - supported = {'CRAM-MD5': smtp.auth_cram_md5, - 'PLAIN': smtp.auth_plain, - 'LOGIN': smtp.auth_login, - } - for mechanism, method in supported.items(): - try: smtp.auth(mechanism, method, initial_response_ok=False) - except smtplib.SMTPAuthenticationError as err: - self.assertIn(sim_auth_credentials[mechanism.lower()].upper(), - str(err)) - smtp.close() + supported = {'CRAM-MD5', 'PLAIN', 'LOGIN'} + for mechanism in supported: + self.serv.add_feature("AUTH {}".format(mechanism)) + for mechanism in supported: + with self.subTest(mechanism=mechanism): + smtp = smtplib.SMTP(HOST, self.port, + local_hostname='localhost', timeout=15) + smtp.ehlo('foo') + smtp.user, smtp.password = sim_auth[0], sim_auth[1] + method = 'auth_' + mechanism.lower().replace('-', '_') + resp = smtp.auth(mechanism, getattr(smtp, method)) + self.assertEqual(resp, (235, b'Authentication Succeeded')) + smtp.close() def test_quit_resets_greeting(self): smtp = smtplib.SMTP(HOST, self.port, diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -58,6 +58,8 @@ Library ------- +- Issue #25446: Fix regression in smtplib's AUTH LOGIN support. + - Issue #18010: Fix the pydoc web server's module search function to handle exceptions from importing packages. -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sun Nov 8 03:45:01 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 08 Nov 2015 08:45:01 +0000 Subject: [Python-checkins] Daily reference leaks (13550b3ca1a6): sum=7 Message-ID: <20151108084501.115882.63338@psf.io> results for 13550b3ca1a6 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogaGm2OF', '--timeout', '7200'] From python-checkins at python.org Sun Nov 8 06:30:42 2015 From: python-checkins at python.org (martin.panter) Date: Sun, 08 Nov 2015 11:30:42 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI0ODAy?= =?utf-8?q?=3A_Update_test_case_for_ValueError_in_3=2E5?= Message-ID: <20151108113042.2126.48403@psf.io> https://hg.python.org/cpython/rev/a13d9656f954 changeset: 99011:a13d9656f954 branch: 3.5 parent: 99009:d13263ecf0c6 user: Martin Panter date: Sun Nov 08 11:09:13 2015 +0000 summary: Issue #24802: Update test case for ValueError in 3.5 files: Lib/test/test_compile.py | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -545,10 +545,9 @@ def test_null_terminated(self): # The source code is null-terminated internally, but bytes-like # objects are accepted, which could be not terminated. - # Exception changed from TypeError to ValueError in 3.5 - with self.assertRaisesRegex(Exception, "cannot contain null"): + with self.assertRaisesRegex(ValueError, "cannot contain null"): compile("123\x00", "", "eval") - with self.assertRaisesRegex(Exception, "cannot contain null"): + with self.assertRaisesRegex(ValueError, "cannot contain null"): compile(memoryview(b"123\x00"), "", "eval") code = compile(memoryview(b"123\x00")[1:-1], "", "eval") self.assertEqual(eval(code), 23) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 8 06:30:42 2015 From: python-checkins at python.org (martin.panter) Date: Sun, 08 Nov 2015 11:30:42 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324802=3A_Merge_ValueError_test_case_from_3=2E5?= Message-ID: <20151108113042.33532.82828@psf.io> https://hg.python.org/cpython/rev/96cdd2532034 changeset: 99012:96cdd2532034 parent: 99010:7368b86432c6 parent: 99011:a13d9656f954 user: Martin Panter date: Sun Nov 08 11:09:37 2015 +0000 summary: Issue #24802: Merge ValueError test case from 3.5 files: Lib/test/test_compile.py | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -545,10 +545,9 @@ def test_null_terminated(self): # The source code is null-terminated internally, but bytes-like # objects are accepted, which could be not terminated. - # Exception changed from TypeError to ValueError in 3.5 - with self.assertRaisesRegex(Exception, "cannot contain null"): + with self.assertRaisesRegex(ValueError, "cannot contain null"): compile("123\x00", "", "eval") - with self.assertRaisesRegex(Exception, "cannot contain null"): + with self.assertRaisesRegex(ValueError, "cannot contain null"): compile(memoryview(b"123\x00"), "", "eval") code = compile(memoryview(b"123\x00")[1:-1], "", "eval") self.assertEqual(eval(code), 23) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Mon Nov 9 03:44:48 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 09 Nov 2015 08:44:48 +0000 Subject: [Python-checkins] Daily reference leaks (96cdd2532034): sum=7 Message-ID: <20151109084448.16133.67173@psf.io> results for 96cdd2532034 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogtMs0kl', '--timeout', '7200'] From python-checkins at python.org Mon Nov 9 06:22:19 2015 From: python-checkins at python.org (victor.stinner) Date: Mon, 09 Nov 2015 11:22:19 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzcyNjc6?= =?utf-8?q?_format=28int=2C_=27c=27=29_now_raises_OverflowError_when_the_a?= =?utf-8?q?rgument_is_not?= Message-ID: <20151109112219.10022.94151@psf.io> https://hg.python.org/cpython/rev/2f2c52c9ff38 changeset: 99013:2f2c52c9ff38 branch: 2.7 parent: 99005:77184a429dae user: Victor Stinner date: Mon Nov 09 12:21:09 2015 +0100 summary: Issue #7267: format(int, 'c') now raises OverflowError when the argument is not in range(0, 256). files: Lib/test/test_str.py | 5 +++++ Misc/NEWS | 3 +++ Objects/stringlib/formatter.h | 8 ++++++++ 3 files changed, 16 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -428,6 +428,11 @@ self.assertEqual('{:{f}}{g}{}'.format(1, 3, g='g', f=2), ' 1g3') self.assertEqual('{f:{}}{}{g}'.format(2, 4, f=1, g='g'), ' 14g') + def test_format_c_overflow(self): + # issue #7267 + self.assertRaises(OverflowError, '{0:c}'.format, -1) + self.assertRaises(OverflowError, '{0:c}'.format, 256) + def test_buffer_is_readonly(self): self.assertRaises(TypeError, sys.stdin.readinto, b"") diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #7267: format(int, 'c') now raises OverflowError when the argument is + not in range(0, 256). + - Issue #24806: Prevent builtin types that are not allowed to be subclassed from being subclassed through multiple inheritance. diff --git a/Objects/stringlib/formatter.h b/Objects/stringlib/formatter.h --- a/Objects/stringlib/formatter.h +++ b/Objects/stringlib/formatter.h @@ -789,6 +789,7 @@ x = PyLong_AsLong(value); if (x == -1 && PyErr_Occurred()) goto done; +#if STRINGLIB_IS_UNICODE #ifdef Py_UNICODE_WIDE if (x < 0 || x > 0x10ffff) { PyErr_SetString(PyExc_OverflowError, @@ -804,6 +805,13 @@ goto done; } #endif +#else + if (x < 0 || x > 0xff) { + PyErr_SetString(PyExc_OverflowError, + "%c arg not in range(0x100)"); + goto done; + } +#endif numeric_char = (STRINGLIB_CHAR)x; pnumeric_chars = &numeric_char; n_digits = 1; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 07:31:38 2015 From: python-checkins at python.org (steve.dower) Date: Mon, 09 Nov 2015 12:31:38 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fixes_installe?= =?utf-8?q?r_not_allowing_launcher_to_be_selected=2E?= Message-ID: <20151109123138.24910.48918@psf.io> https://hg.python.org/cpython/rev/0c704864b917 changeset: 99014:0c704864b917 branch: 3.5 parent: 99011:a13d9656f954 user: Steve Dower date: Mon Nov 09 07:31:05 2015 -0500 summary: Fixes installer not allowing launcher to be selected. files: Tools/msi/bundle/bundle.wxs | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -70,7 +70,7 @@ - + -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 07:31:43 2015 From: python-checkins at python.org (steve.dower) Date: Mon, 09 Nov 2015 12:31:43 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fixes_installer_not_allowing_launcher_to_be_selected=2E?= Message-ID: <20151109123143.58405.28527@psf.io> https://hg.python.org/cpython/rev/aca512f451a8 changeset: 99015:aca512f451a8 parent: 99012:96cdd2532034 parent: 99014:0c704864b917 user: Steve Dower date: Mon Nov 09 07:31:20 2015 -0500 summary: Fixes installer not allowing launcher to be selected. files: Tools/msi/bundle/bundle.wxs | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/msi/bundle/bundle.wxs b/Tools/msi/bundle/bundle.wxs --- a/Tools/msi/bundle/bundle.wxs +++ b/Tools/msi/bundle/bundle.wxs @@ -26,7 +26,7 @@ - + @@ -52,7 +52,7 @@ - + @@ -70,7 +70,7 @@ - + -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 07:44:02 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 12:44:02 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325263=3A_Trying_t?= =?utf-8?q?o_fix_test=5Fuse_on_Windows=2E?= Message-ID: <20151109124401.24918.18522@psf.io> https://hg.python.org/cpython/rev/3f8998c2fbf9 changeset: 99016:3f8998c2fbf9 user: Serhiy Storchaka date: Mon Nov 09 14:43:31 2015 +0200 summary: Issue #25263: Trying to fix test_use on Windows. Avoid possible weird behavior of WideInt convertion. "winfo id" always returns string hexadecimal representation. files: Lib/tkinter/__init__.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -845,8 +845,7 @@ self.tk.call('winfo', 'height', self._w)) def winfo_id(self): """Return identifier ID for this widget.""" - return self.tk.getint( - self.tk.call('winfo', 'id', self._w)) + return int(self.tk.call('winfo', 'id', self._w), 0) def winfo_interps(self, displayof=0): """Return the name of all Tcl interpreters for this display.""" args = ('winfo', 'interps') + self._displayof(displayof) -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Mon Nov 9 08:55:46 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 9 Nov 2015 13:55:46 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-09 Message-ID: <7b9225c0-fc57-4493-a406-67ffd92bae6f@irsmsx103.ger.corp.intel.com> Results for project Python default, build date 2015-11-09 04:02:19 +0000 commit: 96cdd2532034211fa14f444c159801d349067d73 revision date: 2015-11-08 11:09:37 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.34% 2.57% 10.58% 13.48% :-| pybench 0.14% 0.38% -1.72% 8.67% :-( regex_v8 3.33% -1.00% -6.28% 7.76% :-| nbody 0.06% 0.42% 0.90% 8.92% :-| json_dump_v2 0.21% 1.13% -0.09% 11.52% :-| normal_startup 0.67% 0.43% 0.64% 4.73% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Mon Nov 9 08:56:34 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 9 Nov 2015 13:56:34 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-09 Message-ID: Results for project Python 2.7, build date 2015-11-09 04:51:10 +0000 commit: 77184a429dae77759538436581fff235c59ae36c revision date: 2015-11-07 18:04:46 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.17% -0.60% 2.55% 10.86% :-) pybench 0.24% -0.01% 6.59% 6.72% :-| regex_v8 0.52% -0.14% -1.75% 7.18% :-) nbody 0.26% -0.12% 8.62% 5.43% :-) json_dump_v2 0.27% -0.22% 2.10% 15.02% :-| normal_startup 1.81% 0.19% -1.46% 3.14% :-| ssbench 0.39% 0.81% 0.82% 1.48% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Mon Nov 9 11:37:12 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 09 Nov 2015 16:37:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151109162635.19524.86033@psf.io> https://hg.python.org/cpython/rev/a4c4b356a27c changeset: 99018:a4c4b356a27c parent: 99016:3f8998c2fbf9 parent: 99017:6e6ebe9cd441 user: Raymond Hettinger date: Mon Nov 09 08:26:28 2015 -0800 summary: merge files: Doc/library/collections.rst | 4 ++-- Doc/whatsnew/3.5.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -929,10 +929,10 @@ fields: >>> Book = namedtuple('Book', ['id', 'title', 'authors']) - >>> Book.__doc__ = 'Hardcover book in active collection' + >>> Book.__doc__ += ': Hardcover book in active collection' >>> Book.id.__doc__ = '13-digit ISBN' >>> Book.title.__doc__ = 'Title of first printing' - >>> Book.author.__doc__ = 'List of authors sorted by last name' + >>> Book.authors.__doc__ = 'List of authors sorted by last name' Default values can be implemented by using :meth:`_replace` to customize a prototype instance: diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -865,7 +865,7 @@ Docstrings produced by :func:`~collections.namedtuple` can now be updated:: Point = namedtuple('Point', ['x', 'y']) - Point.__doc__ = 'ordered pair' + Point.__doc__ += ': Cartesian coodinate' Point.x.__doc__ = 'abscissa' Point.y.__doc__ = 'ordinate' -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 11:37:12 2015 From: python-checkins at python.org (raymond.hettinger) Date: Mon, 09 Nov 2015 16:37:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Improve_namedt?= =?utf-8?q?uple_doc_string_examples?= Message-ID: <20151109162635.24928.26863@psf.io> https://hg.python.org/cpython/rev/6e6ebe9cd441 changeset: 99017:6e6ebe9cd441 branch: 3.5 parent: 99014:0c704864b917 user: Raymond Hettinger date: Mon Nov 09 08:24:53 2015 -0800 summary: Improve namedtuple doc string examples files: Doc/library/collections.rst | 4 ++-- Doc/whatsnew/3.5.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -929,10 +929,10 @@ fields: >>> Book = namedtuple('Book', ['id', 'title', 'authors']) - >>> Book.__doc__ = 'Hardcover book in active collection' + >>> Book.__doc__ += ': Hardcover book in active collection' >>> Book.id.__doc__ = '13-digit ISBN' >>> Book.title.__doc__ = 'Title of first printing' - >>> Book.author.__doc__ = 'List of authors sorted by last name' + >>> Book.authors.__doc__ = 'List of authors sorted by last name' Default values can be implemented by using :meth:`_replace` to customize a prototype instance: diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -865,7 +865,7 @@ Docstrings produced by :func:`~collections.namedtuple` can now be updated:: Point = namedtuple('Point', ['x', 'y']) - Point.__doc__ = 'ordered pair' + Point.__doc__ += ': Cartesian coodinate' Point.x.__doc__ = 'abscissa' Point.y.__doc__ = 'ordinate' -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:34:22 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 20:34:22 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NTgy?= =?utf-8?q?=3A_Fixed_100_MB_memory_leak_in_test=5Fctypes=2E?= Message-ID: <20151109203422.27695.84330@psf.io> https://hg.python.org/cpython/rev/f14f6bce3321 changeset: 99020:f14f6bce3321 branch: 2.7 parent: 99013:2f2c52c9ff38 user: Serhiy Storchaka date: Mon Nov 09 22:31:10 2015 +0200 summary: Issue #25582: Fixed 100 MB memory leak in test_ctypes. files: Lib/ctypes/test/test_pointers.py | 12 +++++++++++- Lib/ctypes/test/test_win32.py | 4 ++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -192,9 +192,19 @@ LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) self.assertTrue(POINTER(LargeNamedType)) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[LargeNamedType] + def test_pointer_type_str_name(self): large_string = 'T' * 2 ** 25 - self.assertTrue(POINTER(large_string)) + P = POINTER(large_string) + self.assertTrue(P) + + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[id(P)] + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -114,5 +114,9 @@ self.assertEqual(ret.top, top.value) self.assertEqual(ret.bottom, bottom.value) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[RECT] + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:34:22 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 20:34:22 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325582=3A_Fixed_100_MB_memory_leak_in_test=5Fcty?= =?utf-8?q?pes=2E?= Message-ID: <20151109203422.21710.12056@psf.io> https://hg.python.org/cpython/rev/a6f6d8a6152f changeset: 99022:a6f6d8a6152f parent: 99018:a4c4b356a27c parent: 99021:ad4c6f4af909 user: Serhiy Storchaka date: Mon Nov 09 22:33:39 2015 +0200 summary: Issue #25582: Fixed 100 MB memory leak in test_ctypes. files: Lib/ctypes/test/test_pointers.py | 12 +++++++++++- Lib/ctypes/test/test_win32.py | 4 ++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -195,9 +195,19 @@ LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) self.assertTrue(POINTER(LargeNamedType)) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[LargeNamedType] + def test_pointer_type_str_name(self): large_string = 'T' * 2 ** 25 - self.assertTrue(POINTER(large_string)) + P = POINTER(large_string) + self.assertTrue(P) + + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[id(P)] + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -135,5 +135,9 @@ self.assertEqual(ret.top, top.value) self.assertEqual(ret.bottom, bottom.value) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[RECT] + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:34:23 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 20:34:23 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325582=3A_Fixed_100_MB_memory_leak_in_test=5Fctypes=2E?= Message-ID: <20151109203422.33556.69774@psf.io> https://hg.python.org/cpython/rev/ad4c6f4af909 changeset: 99021:ad4c6f4af909 branch: 3.5 parent: 99017:6e6ebe9cd441 parent: 99019:e5d7cf9d6469 user: Serhiy Storchaka date: Mon Nov 09 22:32:23 2015 +0200 summary: Issue #25582: Fixed 100 MB memory leak in test_ctypes. files: Lib/ctypes/test/test_pointers.py | 12 +++++++++++- Lib/ctypes/test/test_win32.py | 4 ++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -195,9 +195,19 @@ LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) self.assertTrue(POINTER(LargeNamedType)) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[LargeNamedType] + def test_pointer_type_str_name(self): large_string = 'T' * 2 ** 25 - self.assertTrue(POINTER(large_string)) + P = POINTER(large_string) + self.assertTrue(P) + + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[id(P)] + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -135,5 +135,9 @@ self.assertEqual(ret.top, top.value) self.assertEqual(ret.bottom, bottom.value) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[RECT] + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:34:23 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 20:34:23 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTgy?= =?utf-8?q?=3A_Fixed_100_MB_memory_leak_in_test=5Fctypes=2E?= Message-ID: <20151109203422.92462.71937@psf.io> https://hg.python.org/cpython/rev/e5d7cf9d6469 changeset: 99019:e5d7cf9d6469 branch: 3.4 parent: 99006:6181476b5534 user: Serhiy Storchaka date: Mon Nov 09 22:31:10 2015 +0200 summary: Issue #25582: Fixed 100 MB memory leak in test_ctypes. files: Lib/ctypes/test/test_pointers.py | 12 +++++++++++- Lib/ctypes/test/test_win32.py | 4 ++++ 2 files changed, 15 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -192,9 +192,19 @@ LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) self.assertTrue(POINTER(LargeNamedType)) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[LargeNamedType] + def test_pointer_type_str_name(self): large_string = 'T' * 2 ** 25 - self.assertTrue(POINTER(large_string)) + P = POINTER(large_string) + self.assertTrue(P) + + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[id(P)] + if __name__ == '__main__': unittest.main() diff --git a/Lib/ctypes/test/test_win32.py b/Lib/ctypes/test/test_win32.py --- a/Lib/ctypes/test/test_win32.py +++ b/Lib/ctypes/test/test_win32.py @@ -135,5 +135,9 @@ self.assertEqual(ret.top, top.value) self.assertEqual(ret.bottom, bottom.value) + # to not leak references, we must clean _pointer_type_cache + from ctypes import _pointer_type_cache + del _pointer_type_cache[RECT] + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:56:09 2015 From: python-checkins at python.org (victor.stinner) Date: Mon, 09 Nov 2015 20:56:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Null_merge_3=2E5?= Message-ID: <20151109205609.21724.7216@psf.io> https://hg.python.org/cpython/rev/c87738735107 changeset: 99024:c87738735107 parent: 99022:a6f6d8a6152f parent: 99023:2d8988f64cea user: Victor Stinner date: Mon Nov 09 21:55:13 2015 +0100 summary: Null merge 3.5 files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 15:56:09 2015 From: python-checkins at python.org (victor.stinner) Date: Mon, 09 Nov 2015 20:56:09 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTU1?= =?utf-8?q?=3A_Fix_parser_and_AST=3A_fill_lineno_and_col=5Foffset_of_=22ar?= =?utf-8?q?g=22_node_when?= Message-ID: <20151109205609.27699.16569@psf.io> https://hg.python.org/cpython/rev/2d8988f64cea changeset: 99023:2d8988f64cea branch: 3.5 parent: 99021:ad4c6f4af909 user: Victor Stinner date: Fri Nov 06 17:01:48 2015 +0100 summary: Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node when compiling AST from Python objects. files: Include/Python-ast.h | 5 +++-- Misc/NEWS | 3 +++ Parser/asdl_c.py | 12 ++++++++++-- Python/Python-ast.c | 31 +++++++++++++++++++++++++++++-- Python/ast.c | 9 +++------ 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/Include/Python-ast.h b/Include/Python-ast.h --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -585,8 +585,9 @@ arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq * defaults, PyArena *arena); -#define arg(a0, a1, a2) _Py_arg(a0, a1, a2) -arg_ty _Py_arg(identifier arg, expr_ty annotation, PyArena *arena); +#define arg(a0, a1, a2, a3, a4) _Py_arg(a0, a1, a2, a3, a4) +arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset, + PyArena *arena); #define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2) keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena); #define alias(a0, a1, a2) _Py_alias(a0, a1, a2) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25555: Fix parser and AST: fill lineno and col_offset of "arg" node + when compiling AST from Python objects. + - Issue #24802: Avoid buffer overreads when int(), float(), compile(), exec() and eval() are passed bytes-like objects. These objects are not necessarily terminated by a null byte, but the functions assumed they were. diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -275,7 +275,9 @@ def visitProduct(self, prod, name): self.emit_function(name, get_c_type(name), - self.get_args(prod.fields), [], union=False) + self.get_args(prod.fields), + self.get_args(prod.attributes), + union=False) class FunctionVisitor(PrototypeVisitor): @@ -329,7 +331,8 @@ self.emit(s, depth, reflow) for argtype, argname, opt in args: emit("p->%s = %s;" % (argname, argname), 1) - assert not attrs + for argtype, argname, opt in attrs: + emit("p->%s = %s;" % (argname, argname), 1) class PickleVisitor(EmitVisitor): @@ -452,10 +455,15 @@ self.emit("PyObject* tmp = NULL;", 1) for f in prod.fields: self.visitFieldDeclaration(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitFieldDeclaration(a, name, prod=prod, depth=1) self.emit("", 0) for f in prod.fields: self.visitField(f, name, prod=prod, depth=1) + for a in prod.attributes: + self.visitField(a, name, prod=prod, depth=1) args = [f.name for f in prod.fields] + args.extend([a.name for a in prod.attributes]) self.emit("*out = %s(%s);" % (name, self.buildArgs(args)), 1) self.emit("return 0;", 1) self.emit("failed:", 0) diff --git a/Python/Python-ast.c b/Python/Python-ast.c --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -2372,7 +2372,8 @@ } arg_ty -arg(identifier arg, expr_ty annotation, PyArena *arena) +arg(identifier arg, expr_ty annotation, int lineno, int col_offset, PyArena + *arena) { arg_ty p; if (!arg) { @@ -2385,6 +2386,8 @@ return NULL; p->arg = arg; p->annotation = annotation; + p->lineno = lineno; + p->col_offset = col_offset; return p; } @@ -7086,6 +7089,8 @@ PyObject* tmp = NULL; identifier arg; expr_ty annotation; + int lineno; + int col_offset; if (_PyObject_HasAttrId(obj, &PyId_arg)) { int res; @@ -7108,7 +7113,29 @@ } else { annotation = NULL; } - *out = arg(arg, annotation, arena); + if (_PyObject_HasAttrId(obj, &PyId_lineno)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_lineno); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &lineno, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from arg"); + return 1; + } + if (_PyObject_HasAttrId(obj, &PyId_col_offset)) { + int res; + tmp = _PyObject_GetAttrId(obj, &PyId_col_offset); + if (tmp == NULL) goto failed; + res = obj2ast_int(tmp, &col_offset, arena); + if (res != 0) goto failed; + Py_CLEAR(tmp); + } else { + PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from arg"); + return 1; + } + *out = arg(arg, annotation, lineno, col_offset, arena); return 0; failed: Py_XDECREF(tmp); diff --git a/Python/ast.c b/Python/ast.c --- a/Python/ast.c +++ b/Python/ast.c @@ -1173,11 +1173,9 @@ return NULL; } - ret = arg(name, annotation, c->c_arena); + ret = arg(name, annotation, LINENO(n), n->n_col_offset, c->c_arena); if (!ret) return NULL; - ret->lineno = LINENO(n); - ret->col_offset = n->n_col_offset; return ret; } @@ -1233,11 +1231,10 @@ goto error; if (forbidden_name(c, argname, ch, 0)) goto error; - arg = arg(argname, annotation, c->c_arena); + arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset, + c->c_arena); if (!arg) goto error; - arg->lineno = LINENO(ch); - arg->col_offset = ch->n_col_offset; asdl_seq_SET(kwonlyargs, j++, arg); i += 2; /* the name and the comma */ break; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:19:27 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:19:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTg0?= =?utf-8?q?=3A_Fixed_recursive_glob=28=29_with_patterns_starting_with_=27*?= =?utf-8?b?Kicu?= Message-ID: <20151109211927.29435.93547@psf.io> https://hg.python.org/cpython/rev/4532c4f37429 changeset: 99025:4532c4f37429 branch: 3.5 parent: 99023:2d8988f64cea user: Serhiy Storchaka date: Mon Nov 09 23:12:07 2015 +0200 summary: Issue #25584: Fixed recursive glob() with patterns starting with '**'. files: Lib/glob.py | 13 +++++++++---- Lib/test/test_glob.py | 21 +++++++++++++++------ Misc/NEWS | 2 ++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -30,6 +30,13 @@ If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ + it = _iglob(pathname, recursive) + if recursive and _isrecursive(pathname): + s = next(it) # skip empty string + assert not s + return it + +def _iglob(pathname, recursive): dirname, basename = os.path.split(pathname) if not has_magic(pathname): if basename: @@ -50,7 +57,7 @@ # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = iglob(dirname, recursive=recursive) + dirs = _iglob(dirname, recursive) else: dirs = [dirname] if has_magic(basename): @@ -98,12 +105,10 @@ def glob2(dirname, pattern): assert _isrecursive(pattern) - if dirname: - yield pattern[:0] + yield pattern[:0] yield from _rlistdir(dirname) # Recursively yields relative pathnames inside a literal directory. - def _rlistdir(dirname): if not dirname: if isinstance(dirname, bytes): diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -31,6 +31,7 @@ self.mktemp('.bb', 'H') self.mktemp('aaa', 'zzzF') self.mktemp('ZZZ') + self.mktemp('EF') self.mktemp('a', 'bcd', 'EF') self.mktemp('a', 'bcd', 'efg', 'ha') if can_symlink(): @@ -200,7 +201,7 @@ def test_recursive_glob(self): eq = self.assertSequencesEqual_noorder - full = [('ZZZ',), + full = [('EF',), ('ZZZ',), ('a',), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), @@ -217,8 +218,8 @@ ('sym3', 'efg', 'ha'), ] eq(self.rglob('**'), self.joins(('',), *full)) - eq(self.rglob('.', '**'), self.joins(('.',''), - *(('.',) + i for i in full))) + eq(self.rglob(os.curdir, '**'), + self.joins((os.curdir, ''), *((os.curdir,) + i for i in full))) dirs = [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''), ('aaa', ''), ('aab', '')] if can_symlink(): @@ -229,11 +230,11 @@ ('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'))) eq(self.rglob('a**'), self.joins(('a',), ('aaa',), ('aab',))) - expect = [('a', 'bcd', 'EF')] + expect = [('a', 'bcd', 'EF'), ('EF',)] if can_symlink(): expect += [('sym3', 'EF')] eq(self.rglob('**', 'EF'), self.joins(*expect)) - expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F')] + expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'), ('EF',)] if can_symlink(): expect += [('sym3', 'EF')] eq(self.rglob('**', '*F'), self.joins(*expect)) @@ -247,10 +248,18 @@ eq(glob.glob('**', recursive=True), [join(*i) for i in full]) eq(glob.glob(join('**', ''), recursive=True), [join(*i) for i in dirs]) + eq(glob.glob(join('**', '*'), recursive=True), + [join(*i) for i in full]) + eq(glob.glob(join(os.curdir, '**'), recursive=True), + [join(os.curdir, '')] + [join(os.curdir, *i) for i in full]) + eq(glob.glob(join(os.curdir, '**', ''), recursive=True), + [join(os.curdir, '')] + [join(os.curdir, *i) for i in dirs]) + eq(glob.glob(join(os.curdir, '**', '*'), recursive=True), + [join(os.curdir, *i) for i in full]) eq(glob.glob(join('**','zz*F'), recursive=True), [join('aaa', 'zzzF')]) eq(glob.glob('**zz*F', recursive=True), []) - expect = [join('a', 'bcd', 'EF')] + expect = [join('a', 'bcd', 'EF'), 'EF'] if can_symlink(): expect += [join('sym3', 'EF')] eq(glob.glob(join('**', 'EF'), recursive=True), expect) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -61,6 +61,8 @@ Library ------- +- Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. + - Issue #25446: Fix regression in smtplib's AUTH LOGIN support. - Issue #18010: Fix the pydoc web server's module search function to handle -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:19:27 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:19:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTg0?= =?utf-8?q?=3A_Added_=22escape=22_to_the_=5F=5Fall=5F=5F_list_in_the_glob_?= =?utf-8?q?module=2E?= Message-ID: <20151109211927.27699.51131@psf.io> https://hg.python.org/cpython/rev/fefc10de2775 changeset: 99027:fefc10de2775 branch: 3.5 parent: 99025:4532c4f37429 user: Serhiy Storchaka date: Mon Nov 09 23:18:19 2015 +0200 summary: Issue #25584: Added "escape" to the __all__ list in the glob module. From patch by Xavier de Gaye. files: Lib/glob.py | 2 +- Misc/NEWS | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -4,7 +4,7 @@ import re import fnmatch -__all__ = ["glob", "iglob"] +__all__ = ["glob", "iglob", "escape"] def glob(pathname, *, recursive=False): """Return a list of paths matching a pathname pattern. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -61,6 +61,8 @@ Library ------- +- Issue #25584: Added "escape" to the __all__ list in the glob module. + - Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. - Issue #25446: Fix regression in smtplib's AUTH LOGIN support. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:19:27 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:19:27 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogSXNzdWUgIzI1NTg0OiBBZGRlZCAiZXNjYXBlIiB0byB0aGUgX19hbGxf?= =?utf-8?q?=5F_list_in_the_glob_module=2E?= Message-ID: <20151109211927.21710.56492@psf.io> https://hg.python.org/cpython/rev/128e61cb3de2 changeset: 99028:128e61cb3de2 parent: 99026:175cd763de57 parent: 99027:fefc10de2775 user: Serhiy Storchaka date: Mon Nov 09 23:18:32 2015 +0200 summary: Issue #25584: Added "escape" to the __all__ list in the glob module. From patch by Xavier de Gaye. files: Lib/glob.py | 2 +- Misc/NEWS | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -4,7 +4,7 @@ import re import fnmatch -__all__ = ["glob", "iglob"] +__all__ = ["glob", "iglob", "escape"] def glob(pathname, *, recursive=False): """Return a list of paths matching a pathname pattern. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -79,6 +79,8 @@ Library ------- +- Issue #25584: Added "escape" to the __all__ list in the glob module. + - Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. - Issue #25446: Fix regression in smtplib's AUTH LOGIN support. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:19:31 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:19:31 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325584=3A_Fixed_recursive_glob=28=29_with_patter?= =?utf-8?q?ns_starting_with_=27**=27=2E?= Message-ID: <20151109211927.58391.35719@psf.io> https://hg.python.org/cpython/rev/175cd763de57 changeset: 99026:175cd763de57 parent: 99024:c87738735107 parent: 99025:4532c4f37429 user: Serhiy Storchaka date: Mon Nov 09 23:12:28 2015 +0200 summary: Issue #25584: Fixed recursive glob() with patterns starting with '**'. files: Lib/glob.py | 13 +++++++++---- Lib/test/test_glob.py | 21 +++++++++++++++------ Misc/NEWS | 2 ++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Lib/glob.py b/Lib/glob.py --- a/Lib/glob.py +++ b/Lib/glob.py @@ -30,6 +30,13 @@ If recursive is true, the pattern '**' will match any files and zero or more directories and subdirectories. """ + it = _iglob(pathname, recursive) + if recursive and _isrecursive(pathname): + s = next(it) # skip empty string + assert not s + return it + +def _iglob(pathname, recursive): dirname, basename = os.path.split(pathname) if not has_magic(pathname): if basename: @@ -50,7 +57,7 @@ # drive or UNC path. Prevent an infinite recursion if a drive or UNC path # contains magic characters (i.e. r'\\?\C:'). if dirname != pathname and has_magic(dirname): - dirs = iglob(dirname, recursive=recursive) + dirs = _iglob(dirname, recursive) else: dirs = [dirname] if has_magic(basename): @@ -98,12 +105,10 @@ def glob2(dirname, pattern): assert _isrecursive(pattern) - if dirname: - yield pattern[:0] + yield pattern[:0] yield from _rlistdir(dirname) # Recursively yields relative pathnames inside a literal directory. - def _rlistdir(dirname): if not dirname: if isinstance(dirname, bytes): diff --git a/Lib/test/test_glob.py b/Lib/test/test_glob.py --- a/Lib/test/test_glob.py +++ b/Lib/test/test_glob.py @@ -31,6 +31,7 @@ self.mktemp('.bb', 'H') self.mktemp('aaa', 'zzzF') self.mktemp('ZZZ') + self.mktemp('EF') self.mktemp('a', 'bcd', 'EF') self.mktemp('a', 'bcd', 'efg', 'ha') if can_symlink(): @@ -200,7 +201,7 @@ def test_recursive_glob(self): eq = self.assertSequencesEqual_noorder - full = [('ZZZ',), + full = [('EF',), ('ZZZ',), ('a',), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), @@ -217,8 +218,8 @@ ('sym3', 'efg', 'ha'), ] eq(self.rglob('**'), self.joins(('',), *full)) - eq(self.rglob('.', '**'), self.joins(('.',''), - *(('.',) + i for i in full))) + eq(self.rglob(os.curdir, '**'), + self.joins((os.curdir, ''), *((os.curdir,) + i for i in full))) dirs = [('a', ''), ('a', 'bcd', ''), ('a', 'bcd', 'efg', ''), ('aaa', ''), ('aab', '')] if can_symlink(): @@ -229,11 +230,11 @@ ('a', ''), ('a', 'D'), ('a', 'bcd'), ('a', 'bcd', 'EF'), ('a', 'bcd', 'efg'), ('a', 'bcd', 'efg', 'ha'))) eq(self.rglob('a**'), self.joins(('a',), ('aaa',), ('aab',))) - expect = [('a', 'bcd', 'EF')] + expect = [('a', 'bcd', 'EF'), ('EF',)] if can_symlink(): expect += [('sym3', 'EF')] eq(self.rglob('**', 'EF'), self.joins(*expect)) - expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F')] + expect = [('a', 'bcd', 'EF'), ('aaa', 'zzzF'), ('aab', 'F'), ('EF',)] if can_symlink(): expect += [('sym3', 'EF')] eq(self.rglob('**', '*F'), self.joins(*expect)) @@ -247,10 +248,18 @@ eq(glob.glob('**', recursive=True), [join(*i) for i in full]) eq(glob.glob(join('**', ''), recursive=True), [join(*i) for i in dirs]) + eq(glob.glob(join('**', '*'), recursive=True), + [join(*i) for i in full]) + eq(glob.glob(join(os.curdir, '**'), recursive=True), + [join(os.curdir, '')] + [join(os.curdir, *i) for i in full]) + eq(glob.glob(join(os.curdir, '**', ''), recursive=True), + [join(os.curdir, '')] + [join(os.curdir, *i) for i in dirs]) + eq(glob.glob(join(os.curdir, '**', '*'), recursive=True), + [join(os.curdir, *i) for i in full]) eq(glob.glob(join('**','zz*F'), recursive=True), [join('aaa', 'zzzF')]) eq(glob.glob('**zz*F', recursive=True), []) - expect = [join('a', 'bcd', 'EF')] + expect = [join('a', 'bcd', 'EF'), 'EF'] if can_symlink(): expect += [join('sym3', 'EF')] eq(glob.glob(join('**', 'EF'), recursive=True), expect) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -79,6 +79,8 @@ Library ------- +- Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. + - Issue #25446: Fix regression in smtplib's AUTH LOGIN support. - Issue #18010: Fix the pydoc web server's module search function to handle -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:52:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:52:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Fixed_markup_in_Misc/NEWS=2E?= Message-ID: <20151109215214.27677.70729@psf.io> https://hg.python.org/cpython/rev/90b45da566aa changeset: 99030:90b45da566aa branch: 3.5 parent: 99027:fefc10de2775 parent: 99029:9fb26bf91459 user: Serhiy Storchaka date: Mon Nov 09 23:43:56 2015 +0200 summary: Fixed markup in Misc/NEWS. files: Misc/NEWS | 21 +++++++++++---------- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -364,7 +364,7 @@ - Issue #23919: Prevents assert dialogs appearing in the test suite. -- PCbuild\rt.bat now accepts an unlimited number of arguments to pass along +- ``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass along to regrtest.py. Previously there was a limit of 9. Build @@ -1885,7 +1885,7 @@ and does not require to carry long the spark.py parser-generator library; spark.py was removed from the source base. -- Issue #12546: Allow \x00 to be used as a fill character when using str, int, +- Issue #12546: Allow ``\x00`` to be used as a fill character when using str, int, float, and complex __format__ methods. - Issue #20480: Add ipaddress.reverse_pointer. Patch by Leon Weber. @@ -2565,7 +2565,7 @@ Patch by Tom Flanagan. - Issue #19884: readline: Disable the meta modifier key if stdout is not - a terminal to not write the ANSI sequence "\033[1034h" into stdout. This + a terminal to not write the ANSI sequence ``"\033[1034h"`` into stdout. This sequence is used on some terminal (ex: TERM=xterm-256color") to enable support of 8 bit characters. @@ -2768,7 +2768,7 @@ - Issue #21486: Optimize parsing of netmasks in ipaddress.IPv4Network and ipaddress.IPv6Network. -- Issue #13916: Disallowed the surrogatepass error handler for non UTF-* +- Issue #13916: Disallowed the surrogatepass error handler for non UTF-\* encodings. - Issue #20998: Fixed re.fullmatch() of repeated single character pattern @@ -4941,7 +4941,7 @@ upgrade pip by default, using the bundled pip provided by the new ensurepip module. A new configure option, --with-ensurepip[=upgrade|install|no], is available to override the default ensurepip "--upgrade" option. The option - can also be set with "make [alt]install ENSUREPIP=[upgrade|install\no]". + can also be set with "make [alt]install ENSUREPIP=[upgrade|install|no]". - Issue #19551: PEP 453 - the OS X installer now installs pip by default. @@ -5110,7 +5110,7 @@ - Issue #10712: 2to3 has a new "asserts" fixer that replaces deprecated names of unittest methods (e.g. failUnlessEqual -> assertEqual). -- Issue #18037: 2to3 now escapes '\u' and '\U' in native strings. +- Issue #18037: 2to3 now escapes ``'\u'`` and ``'\U'`` in native strings. - Issue #17839: base64.decodebytes and base64.encodebytes now accept any object that exports a 1 dimensional array of bytes (this means the same @@ -5777,7 +5777,7 @@ - Issue #5308: Raise ValueError when marshalling too large object (a sequence with size >= 2**31), instead of producing illegal marshal data. -- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError +- Issue #12983: Bytes literals with invalid ``\x`` escape now raise a SyntaxError and a full traceback including line number. - Issue #16967: In function definition, evaluate positional defaults before @@ -6148,7 +6148,7 @@ loaded X.509 certs, X.509 CA certs and CRLs. - Issue #18167: cgi.FieldStorage no longer fails to handle multipart/form-data - when \r\n appears at end of 65535 bytes without other newlines. + when ``\r\n`` appears at end of 65535 bytes without other newlines. - Issue #18076: Introduce importlib.util.decode_source(). @@ -6761,8 +6761,9 @@ - Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. -- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals - when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. +- Issue #13899: ``\A``, ``\Z``, and ``\B`` now correctly match the A, Z, + and B literals when used inside character classes (e.g. ``'[\A]'``). + Patch by Matthew Barnett. - Issue #15545: Fix regression in sqlite3's iterdump method where it was failing if the connection used a row factory (such as sqlite3.Row) that -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:52:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:52:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Fixed_markup_i?= =?utf-8?q?n_Misc/NEWS=2E?= Message-ID: <20151109215214.29439.18974@psf.io> https://hg.python.org/cpython/rev/9fb26bf91459 changeset: 99029:9fb26bf91459 branch: 3.4 parent: 99019:e5d7cf9d6469 user: Serhiy Storchaka date: Mon Nov 09 23:41:39 2015 +0200 summary: Fixed markup in Misc/NEWS. files: Misc/NEWS | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1675,7 +1675,7 @@ - Issue #20637: Key-sharing now also works for instance dictionaries of subclasses. Patch by Peter Ingebretson. -- Issue #12546: Allow \x00 to be used as a fill character when using str, int, +- Issue #12546: Allow ``\x00`` to be used as a fill character when using str, int, float, and complex __format__ methods. - Issue #13598: Modify string.Formatter to support auto-numbering of @@ -3418,7 +3418,7 @@ upgrade pip by default, using the bundled pip provided by the new ensurepip module. A new configure option, --with-ensurepip[=upgrade|install|no], is available to override the default ensurepip "--upgrade" option. The option - can also be set with "make [alt]install ENSUREPIP=[upgrade|install\no]". + can also be set with "make [alt]install ENSUREPIP=[upgrade|install|no]". - Issue #19551: PEP 453 - the OS X installer now installs pip by default. @@ -3587,7 +3587,7 @@ - Issue #10712: 2to3 has a new "asserts" fixer that replaces deprecated names of unittest methods (e.g. failUnlessEqual -> assertEqual). -- Issue #18037: 2to3 now escapes '\u' and '\U' in native strings. +- Issue #18037: 2to3 now escapes ``'\u'`` and ``'\U'`` in native strings. - Issue #17839: base64.decodebytes and base64.encodebytes now accept any object that exports a 1 dimensional array of bytes (this means the same @@ -4254,7 +4254,7 @@ - Issue #5308: Raise ValueError when marshalling too large object (a sequence with size >= 2**31), instead of producing illegal marshal data. -- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError +- Issue #12983: Bytes literals with invalid ``\x`` escape now raise a SyntaxError and a full traceback including line number. - Issue #16967: In function definition, evaluate positional defaults before @@ -4625,7 +4625,7 @@ loaded X.509 certs, X.509 CA certs and CRLs. - Issue #18167: cgi.FieldStorage no longer fails to handle multipart/form-data - when \r\n appears at end of 65535 bytes without other newlines. + when ``\r\n`` appears at end of 65535 bytes without other newlines. - Issue #18076: Introduce importlib.util.decode_source(). @@ -5238,8 +5238,9 @@ - Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. -- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals - when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. +- Issue #13899: ``\A``, ``\Z``, and ``\B`` now correctly match the A, Z, + and B literals when used inside character classes (e.g. ``'[\A]'``). + Patch by Matthew Barnett. - Issue #15545: Fix regression in sqlite3's iterdump method where it was failing if the connection used a row factory (such as sqlite3.Row) that -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 16:52:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 21:52:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fixed_markup_in_Misc/NEWS=2E?= Message-ID: <20151109215214.29421.48720@psf.io> https://hg.python.org/cpython/rev/32ba463c238d changeset: 99031:32ba463c238d parent: 99028:128e61cb3de2 parent: 99030:90b45da566aa user: Serhiy Storchaka date: Mon Nov 09 23:44:31 2015 +0200 summary: Fixed markup in Misc/NEWS. files: Misc/NEWS | 25 +++++++++++++------------ 1 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -46,7 +46,7 @@ - Issue #24806: Prevent builtin types that are not allowed to be subclassed from being subclassed through multiple inheritance. -* Issue #25301: The UTF-8 decoder is now up to 15 times as fast for error +- Issue #25301: The UTF-8 decoder is now up to 15 times as fast for error handlers: ``ignore``, ``replace`` and ``surrogateescape``. - Issue #24848: Fixed a number of bugs in UTF-7 decoding of misformed data. @@ -336,7 +336,7 @@ - Issue #25260: Fix ``python -m test --coverage`` on Windows. Remove the list of ignored directories. -- PCbuild\rt.bat now accepts an unlimited number of arguments to pass along +- ``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass along to regrtest.py. Previously there was a limit of 9. Build @@ -541,7 +541,7 @@ - Issue #23919: Prevents assert dialogs appearing in the test suite. -- PCbuild\rt.bat now accepts an unlimited number of arguments to pass along +- ``PCbuild\rt.bat`` now accepts an unlimited number of arguments to pass along to regrtest.py. Previously there was a limit of 9. Build @@ -2057,7 +2057,7 @@ and does not require to carry long the spark.py parser-generator library; spark.py was removed from the source base. -- Issue #12546: Allow \x00 to be used as a fill character when using str, int, +- Issue #12546: Allow ``\x00`` to be used as a fill character when using str, int, float, and complex __format__ methods. - Issue #20480: Add ipaddress.reverse_pointer. Patch by Leon Weber. @@ -2737,7 +2737,7 @@ Patch by Tom Flanagan. - Issue #19884: readline: Disable the meta modifier key if stdout is not - a terminal to not write the ANSI sequence "\033[1034h" into stdout. This + a terminal to not write the ANSI sequence ``"\033[1034h"`` into stdout. This sequence is used on some terminal (ex: TERM=xterm-256color") to enable support of 8 bit characters. @@ -2940,7 +2940,7 @@ - Issue #21486: Optimize parsing of netmasks in ipaddress.IPv4Network and ipaddress.IPv6Network. -- Issue #13916: Disallowed the surrogatepass error handler for non UTF-* +- Issue #13916: Disallowed the surrogatepass error handler for non UTF-\* encodings. - Issue #20998: Fixed re.fullmatch() of repeated single character pattern @@ -5113,7 +5113,7 @@ upgrade pip by default, using the bundled pip provided by the new ensurepip module. A new configure option, --with-ensurepip[=upgrade|install|no], is available to override the default ensurepip "--upgrade" option. The option - can also be set with "make [alt]install ENSUREPIP=[upgrade|install\no]". + can also be set with "make [alt]install ENSUREPIP=[upgrade|install|no]". - Issue #19551: PEP 453 - the OS X installer now installs pip by default. @@ -5282,7 +5282,7 @@ - Issue #10712: 2to3 has a new "asserts" fixer that replaces deprecated names of unittest methods (e.g. failUnlessEqual -> assertEqual). -- Issue #18037: 2to3 now escapes '\u' and '\U' in native strings. +- Issue #18037: 2to3 now escapes ``'\u'`` and ``'\U'`` in native strings. - Issue #17839: base64.decodebytes and base64.encodebytes now accept any object that exports a 1 dimensional array of bytes (this means the same @@ -5949,7 +5949,7 @@ - Issue #5308: Raise ValueError when marshalling too large object (a sequence with size >= 2**31), instead of producing illegal marshal data. -- Issue #12983: Bytes literals with invalid \x escape now raise a SyntaxError +- Issue #12983: Bytes literals with invalid ``\x`` escape now raise a SyntaxError and a full traceback including line number. - Issue #16967: In function definition, evaluate positional defaults before @@ -6320,7 +6320,7 @@ loaded X.509 certs, X.509 CA certs and CRLs. - Issue #18167: cgi.FieldStorage no longer fails to handle multipart/form-data - when \r\n appears at end of 65535 bytes without other newlines. + when ``\r\n`` appears at end of 65535 bytes without other newlines. - Issue #18076: Introduce importlib.util.decode_source(). @@ -6933,8 +6933,9 @@ - Issue #16900: Issue a ResourceWarning when an ssl socket is left unclosed. -- Issue #13899: \A, \Z, and \B now correctly match the A, Z, and B literals - when used inside character classes (e.g. '[\A]'). Patch by Matthew Barnett. +- Issue #13899: ``\A``, ``\Z``, and ``\B`` now correctly match the A, Z, + and B literals when used inside character classes (e.g. ``'[\A]'``). + Patch by Matthew Barnett. - Issue #15545: Fix regression in sqlite3's iterdump method where it was failing if the connection used a row factory (such as sqlite3.Row) that -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 17:32:24 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 22:32:24 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Added_missed_periods_at_the_ends_of_sentences_in_Misc/NEWS=2E?= Message-ID: <20151109223223.27675.15212@psf.io> https://hg.python.org/cpython/rev/37ebf174e9f0 changeset: 99033:37ebf174e9f0 branch: 3.5 parent: 99030:90b45da566aa parent: 99032:e3d0b3eebff4 user: Serhiy Storchaka date: Tue Nov 10 00:31:10 2015 +0200 summary: Added missed periods at the ends of sentences in Misc/NEWS. files: Misc/NEWS | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1164,7 +1164,7 @@ - Issue #23703: Fix a regression in urljoin() introduced in 901e4e52b20a. Patch by Demian Brecht. -- Issue #4254: Adds _curses.update_lines_cols() Patch by Arnon Yaari +- Issue #4254: Adds _curses.update_lines_cols(). Patch by Arnon Yaari - Issue #19933: Provide default argument for ndigits in round. Patch by Vajrasky Kok. @@ -6380,7 +6380,7 @@ - Issue #17016: Get rid of possible pointer wraparounds and integer overflows in the re module. Patch by Nickolai Zeldovich. -- Issue #16658: add missing return to HTTPConnection.send() +- Issue #16658: add missing return to HTTPConnection.send(). Patch by Jeff Knupp. - Issue #9556: the logging package now allows specifying a time-of-day for a @@ -6978,7 +6978,7 @@ - Issue #16431: Use the type information when constructing a Decimal subtype from a Decimal argument. -- Issue #15641: Clean up deprecated classes from importlib +- Issue #15641: Clean up deprecated classes from importlib. Patch by Taras Lyapun. - Issue #16350: zlib.decompressobj().decompress() now accumulates data from @@ -7247,7 +7247,7 @@ - Issue #16511: Use default IDLE width and height if config param is not valid. Patch Serhiy Storchaka. -- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu. Patch by Todd Rovito. - Issue #16123: IDLE - deprecate running without a subprocess. @@ -7760,7 +7760,7 @@ - Issue #16549: Make json.tool work again on Python 3 and add tests. Initial patch by Berker Peksag and Serhiy Storchaka. -- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py. Patch by Serhiy Storchaka. Windows -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 17:32:24 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 22:32:24 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Added_missed_periods_at_the_ends_of_sentences_in_Misc/NE?= =?utf-8?b?V1Mu?= Message-ID: <20151109223223.21736.99918@psf.io> https://hg.python.org/cpython/rev/1e77ce67699e changeset: 99034:1e77ce67699e parent: 99031:32ba463c238d parent: 99033:37ebf174e9f0 user: Serhiy Storchaka date: Tue Nov 10 00:31:28 2015 +0200 summary: Added missed periods at the ends of sentences in Misc/NEWS. files: Misc/NEWS | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1336,7 +1336,7 @@ - Issue #23703: Fix a regression in urljoin() introduced in 901e4e52b20a. Patch by Demian Brecht. -- Issue #4254: Adds _curses.update_lines_cols() Patch by Arnon Yaari +- Issue #4254: Adds _curses.update_lines_cols(). Patch by Arnon Yaari - Issue #19933: Provide default argument for ndigits in round. Patch by Vajrasky Kok. @@ -6552,7 +6552,7 @@ - Issue #17016: Get rid of possible pointer wraparounds and integer overflows in the re module. Patch by Nickolai Zeldovich. -- Issue #16658: add missing return to HTTPConnection.send() +- Issue #16658: add missing return to HTTPConnection.send(). Patch by Jeff Knupp. - Issue #9556: the logging package now allows specifying a time-of-day for a @@ -7150,7 +7150,7 @@ - Issue #16431: Use the type information when constructing a Decimal subtype from a Decimal argument. -- Issue #15641: Clean up deprecated classes from importlib +- Issue #15641: Clean up deprecated classes from importlib. Patch by Taras Lyapun. - Issue #16350: zlib.decompressobj().decompress() now accumulates data from @@ -7419,7 +7419,7 @@ - Issue #16511: Use default IDLE width and height if config param is not valid. Patch Serhiy Storchaka. -- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu. Patch by Todd Rovito. - Issue #16123: IDLE - deprecate running without a subprocess. @@ -7932,7 +7932,7 @@ - Issue #16549: Make json.tool work again on Python 3 and add tests. Initial patch by Berker Peksag and Serhiy Storchaka. -- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py. Patch by Serhiy Storchaka. Windows -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 17:32:24 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 22:32:24 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Added_missed_p?= =?utf-8?q?eriods_at_the_ends_of_sentences_in_Misc/NEWS=2E?= Message-ID: <20151109223224.29423.58353@psf.io> https://hg.python.org/cpython/rev/b35c57bbef1c changeset: 99035:b35c57bbef1c branch: 2.7 parent: 99020:f14f6bce3321 user: Serhiy Storchaka date: Tue Nov 10 00:31:41 2015 +0200 summary: Added missed periods at the ends of sentences in Misc/NEWS. files: Misc/NEWS | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -3076,7 +3076,7 @@ - Issue #16504: IDLE now catches SyntaxErrors raised by tokenizer. Patch by Roger Serwy. -- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu. Patch by Todd Rovito. - Issue #13052: Fix IDLE crashing when replace string in Search/Replace dialog @@ -3272,7 +3272,7 @@ - Issue #16476: Fix json.tool to avoid including trailing whitespace. -- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py. Patch by Serhiy Storchaka. Documentation -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 9 17:32:33 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 09 Nov 2015 22:32:33 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Added_missed_p?= =?utf-8?q?eriods_at_the_ends_of_sentences_in_Misc/NEWS=2E?= Message-ID: <20151109223223.115886.58196@psf.io> https://hg.python.org/cpython/rev/e3d0b3eebff4 changeset: 99032:e3d0b3eebff4 branch: 3.4 parent: 99029:9fb26bf91459 user: Serhiy Storchaka date: Tue Nov 10 00:20:43 2015 +0200 summary: Added missed periods at the ends of sentences in Misc/NEWS. files: Misc/NEWS | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -4857,7 +4857,7 @@ - Issue #17016: Get rid of possible pointer wraparounds and integer overflows in the re module. Patch by Nickolai Zeldovich. -- Issue #16658: add missing return to HTTPConnection.send() +- Issue #16658: add missing return to HTTPConnection.send(). Patch by Jeff Knupp. - Issue #9556: the logging package now allows specifying a time-of-day for a @@ -5455,7 +5455,7 @@ - Issue #16431: Use the type information when constructing a Decimal subtype from a Decimal argument. -- Issue #15641: Clean up deprecated classes from importlib +- Issue #15641: Clean up deprecated classes from importlib. Patch by Taras Lyapun. - Issue #16350: zlib.decompressobj().decompress() now accumulates data from @@ -5724,7 +5724,7 @@ - Issue #16511: Use default IDLE width and height if config param is not valid. Patch Serhiy Storchaka. -- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu +- Issue #1207589: Add Cut/Copy/Paste items to IDLE right click Context Menu. Patch by Todd Rovito. - Issue #16123: IDLE - deprecate running without a subprocess. @@ -6233,7 +6233,7 @@ - Issue #16549: Make json.tool work again on Python 3 and add tests. Initial patch by Berker Peksag and Serhiy Storchaka. -- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py +- Issue #13301: use ast.literal_eval() instead of eval() in Tools/i18n/msgfmt.py. Patch by Serhiy Storchaka. Windows -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 03:00:23 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2015 08:00:23 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Remove_confusi?= =?utf-8?q?ng_section_from_named_tuple_recipes=2E?= Message-ID: <20151110080023.19473.91068@psf.io> https://hg.python.org/cpython/rev/d71da4496f62 changeset: 99036:d71da4496f62 branch: 3.5 parent: 99033:37ebf174e9f0 user: Raymond Hettinger date: Tue Nov 10 00:00:00 2015 -0800 summary: Remove confusing section from named tuple recipes. files: Doc/library/collections.rst | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -942,16 +942,6 @@ >>> johns_account = default_account._replace(owner='John') >>> janes_account = default_account._replace(owner='Jane') -Enumerated constants can be implemented with named tuples, but it is simpler -and more efficient to use a simple :class:`~enum.Enum`: - - >>> Status = namedtuple('Status', 'open pending closed')._make(range(3)) - >>> Status.open, Status.pending, Status.closed - (0, 1, 2) - >>> from enum import Enum - >>> class Status(Enum): - ... open, pending, closed = range(3) - .. seealso:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 03:00:23 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2015 08:00:23 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151110080023.17071.35332@psf.io> https://hg.python.org/cpython/rev/0a5b5bc8476e changeset: 99037:0a5b5bc8476e parent: 99034:1e77ce67699e parent: 99036:d71da4496f62 user: Raymond Hettinger date: Tue Nov 10 00:00:17 2015 -0800 summary: merge files: Doc/library/collections.rst | 10 ---------- 1 files changed, 0 insertions(+), 10 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -942,16 +942,6 @@ >>> johns_account = default_account._replace(owner='John') >>> janes_account = default_account._replace(owner='Jane') -Enumerated constants can be implemented with named tuples, but it is simpler -and more efficient to use a simple :class:`~enum.Enum`: - - >>> Status = namedtuple('Status', 'open pending closed')._make(range(3)) - >>> Status.open, Status.pending, Status.closed - (0, 1, 2) - >>> from enum import Enum - >>> class Status(Enum): - ... open, pending, closed = range(3) - .. seealso:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 03:09:54 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2015 08:09:54 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Improve_appear?= =?utf-8?q?ance_of_example_code?= Message-ID: <20151110080954.19477.95918@psf.io> https://hg.python.org/cpython/rev/15f51b495feb changeset: 99038:15f51b495feb branch: 3.5 parent: 99036:d71da4496f62 user: Raymond Hettinger date: Tue Nov 10 00:09:34 2015 -0800 summary: Improve appearance of example code files: Doc/library/collections.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -905,15 +905,15 @@ a fixed-width print format: >>> class Point(namedtuple('Point', 'x y')): - __slots__ = () - @property - def hypot(self): - return (self.x ** 2 + self.y ** 2) ** 0.5 - def __str__(self): - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + __slots__ = () + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) >>> for p in Point(3, 4), Point(14, 5/7): - print(p) + print(p) Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 03:09:55 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 10 Nov 2015 08:09:55 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151110080955.33534.48243@psf.io> https://hg.python.org/cpython/rev/5da42b87e660 changeset: 99039:5da42b87e660 parent: 99037:0a5b5bc8476e parent: 99038:15f51b495feb user: Raymond Hettinger date: Tue Nov 10 00:09:49 2015 -0800 summary: merge files: Doc/library/collections.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -905,15 +905,15 @@ a fixed-width print format: >>> class Point(namedtuple('Point', 'x y')): - __slots__ = () - @property - def hypot(self): - return (self.x ** 2 + self.y ** 2) ** 0.5 - def __str__(self): - return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) + __slots__ = () + @property + def hypot(self): + return (self.x ** 2 + self.y ** 2) ** 0.5 + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) >>> for p in Point(3, 4), Point(14, 5/7): - print(p) + print(p) Point: x= 3.000 y= 4.000 hypot= 5.000 Point: x=14.000 y= 0.714 hypot=14.018 -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Tue Nov 10 03:44:44 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 10 Nov 2015 08:44:44 +0000 Subject: [Python-checkins] Daily reference leaks (1e77ce67699e): sum=7 Message-ID: <20151110084444.21712.32734@psf.io> results for 1e77ce67699e on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogsCZXNS', '--timeout', '7200'] From python-checkins at python.org Tue Nov 10 06:12:35 2015 From: python-checkins at python.org (victor.stinner) Date: Tue, 10 Nov 2015 11:12:35 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogcHl0aW1lLmM6IHJl?= =?utf-8?q?name_pygettimeofday=5Fnew=28=29_to_pygettimeofday=28=29?= Message-ID: <20151110111235.27697.84621@psf.io> https://hg.python.org/cpython/rev/330cec28f6ff changeset: 99040:330cec28f6ff branch: 3.5 parent: 99038:15f51b495feb user: Victor Stinner date: Tue Nov 10 12:11:39 2015 +0100 summary: pytime.c: rename pygettimeofday_new() to pygettimeofday() I forgot to rename it in my previous refactoring of pytime.c. files: Python/pytime.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Python/pytime.c b/Python/pytime.c --- a/Python/pytime.c +++ b/Python/pytime.c @@ -449,7 +449,7 @@ #endif static int -pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise) { #ifdef MS_WINDOWS FILETIME system_time; @@ -541,7 +541,7 @@ _PyTime_GetSystemClock(void) { _PyTime_t t; - if (pygettimeofday_new(&t, NULL, 0) < 0) { + if (pygettimeofday(&t, NULL, 0) < 0) { /* should not happen, _PyTime_Init() checked the clock at startup */ assert(0); @@ -554,7 +554,7 @@ int _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) { - return pygettimeofday_new(t, info, 1); + return pygettimeofday(t, info, 1); } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 06:12:37 2015 From: python-checkins at python.org (victor.stinner) Date: Tue, 10 Nov 2015 11:12:37 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41IChweXRpbWUp?= Message-ID: <20151110111235.92474.83295@psf.io> https://hg.python.org/cpython/rev/4c903ceeb4d1 changeset: 99041:4c903ceeb4d1 parent: 99039:5da42b87e660 parent: 99040:330cec28f6ff user: Victor Stinner date: Tue Nov 10 12:11:52 2015 +0100 summary: Merge 3.5 (pytime) files: Python/pytime.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Python/pytime.c b/Python/pytime.c --- a/Python/pytime.c +++ b/Python/pytime.c @@ -534,7 +534,7 @@ #endif static int -pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise) +pygettimeofday(_PyTime_t *tp, _Py_clock_info_t *info, int raise) { #ifdef MS_WINDOWS FILETIME system_time; @@ -626,7 +626,7 @@ _PyTime_GetSystemClock(void) { _PyTime_t t; - if (pygettimeofday_new(&t, NULL, 0) < 0) { + if (pygettimeofday(&t, NULL, 0) < 0) { /* should not happen, _PyTime_Init() checked the clock at startup */ assert(0); @@ -639,7 +639,7 @@ int _PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info) { - return pygettimeofday_new(t, info, 1); + return pygettimeofday(t, info, 1); } static int -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 08:33:25 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 13:33:25 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1MjYz?= =?utf-8?q?=3A_Fixed_the_tkinter=2Etest=2Etest=5Ftkinter=2Etest=5Ffont=2EF?= =?utf-8?q?ontTest_test?= Message-ID: <20151110133324.19459.85253@psf.io> https://hg.python.org/cpython/rev/385b3aaf8401 changeset: 99042:385b3aaf8401 branch: 3.4 parent: 99032:e3d0b3eebff4 user: Serhiy Storchaka date: Tue Nov 10 15:30:35 2015 +0200 summary: Issue #25263: Fixed the tkinter.test.test_tkinter.test_font.FontTest test failure when the test is ran the second time. The root attribute was set in parent class in setUpClass and then overridded in child class in tearDownClass. files: Lib/tkinter/test/support.py | 2 +- Lib/tkinter/test/test_tkinter/test_font.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -23,7 +23,7 @@ def tearDownClass(cls): cls.root.update_idletasks() cls.root.destroy() - cls.root = None + del cls.root tkinter._default_root = None tkinter._support_default_root = cls._old_support_default_root diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -12,7 +12,7 @@ @classmethod def setUpClass(cls): - AbstractTkTest.setUpClass() + AbstractTkTest.setUpClass.__func__(cls) try: cls.font = font.Font(root=cls.root, name=fontname, exists=True) except tkinter.TclError: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 08:33:25 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 13:33:25 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325263=3A_Fixed_the_tkinter=2Etest=2Etest=5Ftkinter=2E?= =?utf-8?q?test=5Ffont=2EFontTest_test?= Message-ID: <20151110133324.17059.47888@psf.io> https://hg.python.org/cpython/rev/db168611c6c8 changeset: 99043:db168611c6c8 branch: 3.5 parent: 99040:330cec28f6ff parent: 99042:385b3aaf8401 user: Serhiy Storchaka date: Tue Nov 10 15:31:38 2015 +0200 summary: Issue #25263: Fixed the tkinter.test.test_tkinter.test_font.FontTest test failure when the test is ran the second time. The root attribute was set in parent class in setUpClass and then overridded in child class in tearDownClass. files: Lib/tkinter/test/support.py | 2 +- Lib/tkinter/test/test_tkinter/test_font.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -23,7 +23,7 @@ def tearDownClass(cls): cls.root.update_idletasks() cls.root.destroy() - cls.root = None + del cls.root tkinter._default_root = None tkinter._support_default_root = cls._old_support_default_root diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -12,7 +12,7 @@ @classmethod def setUpClass(cls): - AbstractTkTest.setUpClass() + AbstractTkTest.setUpClass.__func__(cls) try: cls.font = font.Font(root=cls.root, name=fontname, exists=True) except tkinter.TclError: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 08:33:28 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 13:33:28 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325263=3A_Fixed_the_tkinter=2Etest=2Etest=5Ftkin?= =?utf-8?q?ter=2Etest=5Ffont=2EFontTest_test?= Message-ID: <20151110133324.115884.31403@psf.io> https://hg.python.org/cpython/rev/0632642c30dd changeset: 99044:0632642c30dd parent: 99041:4c903ceeb4d1 parent: 99043:db168611c6c8 user: Serhiy Storchaka date: Tue Nov 10 15:31:52 2015 +0200 summary: Issue #25263: Fixed the tkinter.test.test_tkinter.test_font.FontTest test failure when the test is ran the second time. The root attribute was set in parent class in setUpClass and then overridded in child class in tearDownClass. files: Lib/tkinter/test/support.py | 2 +- Lib/tkinter/test/test_tkinter/test_font.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/tkinter/test/support.py b/Lib/tkinter/test/support.py --- a/Lib/tkinter/test/support.py +++ b/Lib/tkinter/test/support.py @@ -23,7 +23,7 @@ def tearDownClass(cls): cls.root.update_idletasks() cls.root.destroy() - cls.root = None + del cls.root tkinter._default_root = None tkinter._support_default_root = cls._old_support_default_root diff --git a/Lib/tkinter/test/test_tkinter/test_font.py b/Lib/tkinter/test/test_tkinter/test_font.py --- a/Lib/tkinter/test/test_tkinter/test_font.py +++ b/Lib/tkinter/test/test_tkinter/test_font.py @@ -12,7 +12,7 @@ @classmethod def setUpClass(cls): - AbstractTkTest.setUpClass() + AbstractTkTest.setUpClass.__func__(cls) try: cls.font = font.Font(root=cls.root, name=fontname, exists=True) except tkinter.TclError: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 08:33:29 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 13:33:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1MjYz?= =?utf-8?q?=3A_Fixed_the_tkinter=2Etest=2Etest=5Ftkinter=2Etest=5Ffont=2EF?= =?utf-8?q?ontTest_test?= Message-ID: <20151110133324.58393.85369@psf.io> https://hg.python.org/cpython/rev/f81e357b2318 changeset: 99045:f81e357b2318 branch: 2.7 parent: 99035:b35c57bbef1c user: Serhiy Storchaka date: Tue Nov 10 15:32:54 2015 +0200 summary: Issue #25263: Fixed the tkinter.test.test_tkinter.test_font.FontTest test failure when the test is ran the second time. The root attribute was set in parent class in setUpClass and then overridded in child class in tearDownClass. files: Lib/lib-tk/test/test_tkinter/test_font.py | 2 +- Lib/lib-tk/test/test_ttk/support.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/lib-tk/test/test_tkinter/test_font.py b/Lib/lib-tk/test/test_tkinter/test_font.py --- a/Lib/lib-tk/test/test_tkinter/test_font.py +++ b/Lib/lib-tk/test/test_tkinter/test_font.py @@ -12,7 +12,7 @@ @classmethod def setUpClass(cls): - AbstractTkTest.setUpClass() + AbstractTkTest.setUpClass.__func__(cls) try: cls.font = font.Font(root=cls.root, name=fontname, exists=True) except tkinter.TclError: diff --git a/Lib/lib-tk/test/test_ttk/support.py b/Lib/lib-tk/test/test_ttk/support.py --- a/Lib/lib-tk/test/test_ttk/support.py +++ b/Lib/lib-tk/test/test_ttk/support.py @@ -23,7 +23,7 @@ def tearDownClass(cls): cls.root.update_idletasks() cls.root.destroy() - cls.root = None + del cls.root tkinter._default_root = None tkinter._support_default_root = cls._old_support_default_root -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Tue Nov 10 10:15:44 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 10 Nov 2015 15:15:44 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-10 Message-ID: Results for project Python default, build date 2015-11-10 04:02:30 +0000 commit: 1e77ce67699e4d39bf16ae15c2dd806ca5bf292a revision date: 2015-11-09 22:31:28 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% -0.06% 10.53% 14.89% :-| pybench 0.14% -0.08% -1.80% 8.17% :-( regex_v8 3.41% -0.67% -6.99% 7.33% :-| nbody 0.07% 0.00% 0.90% 8.05% :-| json_dump_v2 0.22% -0.49% -0.59% 11.16% :-| normal_startup 1.00% -0.36% 0.13% 5.28% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Tue Nov 10 10:16:27 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 10 Nov 2015 15:16:27 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-10 Message-ID: <8ce7f766-6962-4063-9a21-3562f9ae9bb9@irsmsx103.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-10 04:51:28 +0000 commit: b35c57bbef1cbb95e3e6f3ff7afc0a066b5188b0 revision date: 2015-11-09 22:31:41 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.33% 1.47% 3.99% 9.11% :-) pybench 0.26% 0.15% 6.73% 6.95% :-| regex_v8 0.57% 0.11% -1.64% 6.42% :-) nbody 0.19% 0.05% 8.66% 5.61% :-) json_dump_v2 0.29% 0.46% 2.55% 13.60% :-| normal_startup 1.85% 0.25% -1.21% 2.50% :-| ssbench 0.41% -1.14% -0.33% 2.37% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Tue Nov 10 12:19:08 2015 From: python-checkins at python.org (stefan.krah) Date: Tue, 10 Nov 2015 17:19:08 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSWFhdWUgIzI1NTk4?= =?utf-8?q?=3A_Fix_memory=5Fhex_from_=239951_for_non-contiguous_buffers=2E?= Message-ID: <20151110171907.21726.53432@psf.io> https://hg.python.org/cpython/rev/f3d8bb3ffa98 changeset: 99046:f3d8bb3ffa98 branch: 3.5 parent: 99043:db168611c6c8 user: Stefan Krah date: Tue Nov 10 18:17:22 2015 +0100 summary: Iaaue #25598: Fix memory_hex from #9951 for non-contiguous buffers. files: Lib/test/test_buffer.py | 5 +++++ Lib/test/test_memoryview.py | 7 +++++++ Objects/memoryobject.c | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -841,6 +841,11 @@ # test tobytes() self.assertEqual(result.tobytes(), b) + # test hex() + m = memoryview(result) + h = "".join("%02x" % c for c in b) + self.assertEqual(m.hex(), h) + # lst := expected multi-dimensional logical representation # flatten(lst) := elements in C-order ff = fmt if fmt else 'B' diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -512,6 +512,13 @@ m[2:] = memoryview(p6).cast(format)[2:] self.assertEqual(d.value, 0.6) + def test_memoryview_hex(self): + # Issue #9951: memoryview.hex() segfaults with non-contiguous buffers. + x = b'0' * 200000 + m1 = memoryview(x) + m2 = m1[::-1] + self.assertEqual(m2.hex(), '30' * 200000) + if __name__ == "__main__": unittest.main() diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -2156,8 +2156,23 @@ memory_hex(PyMemoryViewObject *self, PyObject *dummy) { Py_buffer *src = VIEW_ADDR(self); + PyObject *bytes; + PyObject *ret; + CHECK_RELEASED(self); - return _Py_strhex(src->buf, src->len); + + if (MV_C_CONTIGUOUS(self->flags)) { + return _Py_strhex(src->buf, src->len); + } + + bytes = memory_tobytes(self, dummy); + if (bytes == NULL) + return NULL; + + ret = _Py_strhex(PyBytes_AS_STRING(bytes), Py_SIZE(bytes)); + Py_DECREF(bytes); + + return ret; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:19:16 2015 From: python-checkins at python.org (stefan.krah) Date: Tue, 10 Nov 2015 17:19:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41Lg==?= Message-ID: <20151110171907.115884.28256@psf.io> https://hg.python.org/cpython/rev/1f253802435e changeset: 99047:1f253802435e parent: 99044:0632642c30dd parent: 99046:f3d8bb3ffa98 user: Stefan Krah date: Tue Nov 10 18:18:07 2015 +0100 summary: Merge 3.5. files: Lib/test/test_buffer.py | 5 +++++ Lib/test/test_memoryview.py | 7 +++++++ Objects/memoryobject.c | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_buffer.py b/Lib/test/test_buffer.py --- a/Lib/test/test_buffer.py +++ b/Lib/test/test_buffer.py @@ -841,6 +841,11 @@ # test tobytes() self.assertEqual(result.tobytes(), b) + # test hex() + m = memoryview(result) + h = "".join("%02x" % c for c in b) + self.assertEqual(m.hex(), h) + # lst := expected multi-dimensional logical representation # flatten(lst) := elements in C-order ff = fmt if fmt else 'B' diff --git a/Lib/test/test_memoryview.py b/Lib/test/test_memoryview.py --- a/Lib/test/test_memoryview.py +++ b/Lib/test/test_memoryview.py @@ -512,6 +512,13 @@ m[2:] = memoryview(p6).cast(format)[2:] self.assertEqual(d.value, 0.6) + def test_memoryview_hex(self): + # Issue #9951: memoryview.hex() segfaults with non-contiguous buffers. + x = b'0' * 200000 + m1 = memoryview(x) + m2 = m1[::-1] + self.assertEqual(m2.hex(), '30' * 200000) + if __name__ == "__main__": unittest.main() diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -2156,8 +2156,23 @@ memory_hex(PyMemoryViewObject *self, PyObject *dummy) { Py_buffer *src = VIEW_ADDR(self); + PyObject *bytes; + PyObject *ret; + CHECK_RELEASED(self); - return _Py_strhex(src->buf, src->len); + + if (MV_C_CONTIGUOUS(self->flags)) { + return _Py_strhex(src->buf, src->len); + } + + bytes = memory_tobytes(self, dummy); + if (bytes == NULL) + return NULL; + + ret = _Py_strhex(PyBytes_AS_STRING(bytes), Py_SIZE(bytes)); + Py_DECREF(bytes); + + return ret; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:36:18 2015 From: python-checkins at python.org (stefan.krah) Date: Tue, 10 Nov 2015 17:36:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fix_Visual_Stu?= =?utf-8?q?dio_warning=2E?= Message-ID: <20151110173614.58393.87033@psf.io> https://hg.python.org/cpython/rev/e445ebe2ec0c changeset: 99048:e445ebe2ec0c branch: 3.5 parent: 99046:f3d8bb3ffa98 user: Stefan Krah date: Tue Nov 10 18:35:19 2015 +0100 summary: Fix Visual Studio warning. files: Objects/memoryobject.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -2242,7 +2242,7 @@ PyExc_IndexError); if (index == -1 && PyErr_Occurred()) return NULL; - ptr = lookup_dimension(view, ptr, dim, index); + ptr = lookup_dimension(view, ptr, (int)dim, index); if (ptr == NULL) return NULL; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:36:19 2015 From: python-checkins at python.org (stefan.krah) Date: Tue, 10 Nov 2015 17:36:19 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41Lg==?= Message-ID: <20151110173614.58413.78697@psf.io> https://hg.python.org/cpython/rev/7ef2d85fc1a7 changeset: 99049:7ef2d85fc1a7 parent: 99047:1f253802435e parent: 99048:e445ebe2ec0c user: Stefan Krah date: Tue Nov 10 18:35:47 2015 +0100 summary: Merge 3.5. files: Objects/memoryobject.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -2242,7 +2242,7 @@ PyExc_IndexError); if (index == -1 && PyErr_Occurred()) return NULL; - ptr = lookup_dimension(view, ptr, dim, index); + ptr = lookup_dimension(view, ptr, (int)dim, index); if (ptr == NULL) return NULL; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:54:08 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 17:54:08 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=236598=3A_Avoid_clock_wrapping_around_in_test=5Fmake=5F?= =?utf-8?q?msgid=5Fcollisions=2E?= Message-ID: <20151110175407.19483.67116@psf.io> https://hg.python.org/cpython/rev/e259c0ab7a69 changeset: 99051:e259c0ab7a69 branch: 3.5 parent: 99048:e445ebe2ec0c parent: 99050:3c0a817ab616 user: Serhiy Storchaka date: Tue Nov 10 19:51:56 2015 +0200 summary: Issue #6598: Avoid clock wrapping around in test_make_msgid_collisions. Use time.monotonic instead of time.clock. files: Lib/test/test_email/test_email.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3179,7 +3179,7 @@ self.msgids = [] append = self.msgids.append make_msgid = utils.make_msgid - clock = time.clock + clock = time.monotonic tfin = clock() + 3.0 while clock() < tfin: append(make_msgid(domain='testdomain-string')) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:54:12 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 17:54:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzY1OTg6?= =?utf-8?q?_Avoid_clock_wrapping_around_in_test=5Fmake=5Fmsgid=5Fcollision?= =?utf-8?q?s=2E?= Message-ID: <20151110175407.33532.98101@psf.io> https://hg.python.org/cpython/rev/3c0a817ab616 changeset: 99050:3c0a817ab616 branch: 3.4 parent: 99042:385b3aaf8401 user: Serhiy Storchaka date: Tue Nov 10 19:50:14 2015 +0200 summary: Issue #6598: Avoid clock wrapping around in test_make_msgid_collisions. Use time.monotonic or time.time instead of time.clock. files: Lib/test/test_email/test_email.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3164,7 +3164,10 @@ self.msgids = [] append = self.msgids.append make_msgid = utils.make_msgid - clock = time.clock + try: + clock = time.monotonic + except AttributeError: + clock = time.time tfin = clock() + 3.0 while clock() < tfin: append(make_msgid(domain='testdomain-string')) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:54:13 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 17:54:13 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzY1OTg6?= =?utf-8?q?_Avoid_clock_wrapping_around_in_test=5Fmake=5Fmsgid=5Fcollision?= =?utf-8?q?s=2E?= Message-ID: <20151110175413.21734.43469@psf.io> https://hg.python.org/cpython/rev/bdd257d60da2 changeset: 99053:bdd257d60da2 branch: 2.7 parent: 99045:f81e357b2318 user: Serhiy Storchaka date: Tue Nov 10 19:53:37 2015 +0200 summary: Issue #6598: Avoid clock wrapping around in test_make_msgid_collisions. Use time.time instead of time.clock. files: Lib/email/test/test_email.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/email/test/test_email.py b/Lib/email/test/test_email.py --- a/Lib/email/test/test_email.py +++ b/Lib/email/test/test_email.py @@ -2424,7 +2424,7 @@ self.msgids = [] append = self.msgids.append make_msgid = Utils.make_msgid - clock = time.clock + clock = time.time tfin = clock() + 3.0 while clock() < tfin: append(make_msgid()) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 10 12:54:15 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Tue, 10 Nov 2015 17:54:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=236598=3A_Avoid_clock_wrapping_around_in_test=5Fm?= =?utf-8?q?ake=5Fmsgid=5Fcollisions=2E?= Message-ID: <20151110175413.58405.2983@psf.io> https://hg.python.org/cpython/rev/d1c11a78b43a changeset: 99052:d1c11a78b43a parent: 99049:7ef2d85fc1a7 parent: 99051:e259c0ab7a69 user: Serhiy Storchaka date: Tue Nov 10 19:52:20 2015 +0200 summary: Issue #6598: Avoid clock wrapping around in test_make_msgid_collisions. Use time.monotonic instead of time.clock. files: Lib/test/test_email/test_email.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_email/test_email.py b/Lib/test/test_email/test_email.py --- a/Lib/test/test_email/test_email.py +++ b/Lib/test/test_email/test_email.py @@ -3179,7 +3179,7 @@ self.msgids = [] append = self.msgids.append make_msgid = utils.make_msgid - clock = time.clock + clock = time.monotonic tfin = clock() + 3.0 while clock() < tfin: append(make_msgid(domain='testdomain-string')) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 11 01:27:32 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 11 Nov 2015 06:27:32 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325595=3A_Fixed_test=5Fdeleted=5Fcwd_in_test=5Fi?= =?utf-8?q?mportlib_on_AIX=2E?= Message-ID: <20151111062732.19477.16785@psf.io> https://hg.python.org/cpython/rev/3f392050d519 changeset: 99055:3f392050d519 parent: 99052:d1c11a78b43a parent: 99054:d4dc36586f24 user: Serhiy Storchaka date: Wed Nov 11 08:27:13 2015 +0200 summary: Issue #25595: Fixed test_deleted_cwd in test_importlib on AIX. files: Lib/test/test_importlib/import_/test_path.py | 22 ++++++--- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -3,7 +3,6 @@ importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') -import errno import os import sys import tempfile @@ -160,17 +159,24 @@ got = self.machinery.PathFinder.find_spec('whatever', [path]) self.assertEqual(got, success_finder.spec) - @unittest.skipIf(sys.platform == 'win32', "cwd can't not exist on Windows") def test_deleted_cwd(self): # Issue #22834 - self.addCleanup(os.chdir, os.getcwd()) + old_dir = os.getcwd() + self.addCleanup(os.chdir, old_dir) + new_dir = tempfile.mkdtemp() try: - with tempfile.TemporaryDirectory() as path: - os.chdir(path) - except OSError as exc: - if exc.errno == errno.EINVAL: - self.skipTest("platform does not allow the deletion of the cwd") + os.chdir(new_dir) + try: + os.rmdir(new_dir) + except OSError: + # EINVAL on Solaris, EBUSY on AIX, ENOTEMPTY on Windows + self.skipTest("platform does not allow " + "the deletion of the cwd") + except: + os.chdir(old_dir) + os.rmdir(new_dir) raise + with util.import_state(path=['']): # Do not want FileNotFoundError raised. self.assertIsNone(self.machinery.PathFinder.find_spec('whatever')) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 11 01:27:32 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 11 Nov 2015 06:27:32 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NTk1?= =?utf-8?q?=3A_Fixed_test=5Fdeleted=5Fcwd_in_test=5Fimportlib_on_AIX=2E?= Message-ID: <20151111062732.27699.24705@psf.io> https://hg.python.org/cpython/rev/d4dc36586f24 changeset: 99054:d4dc36586f24 branch: 3.5 parent: 99051:e259c0ab7a69 user: Serhiy Storchaka date: Wed Nov 11 08:26:59 2015 +0200 summary: Issue #25595: Fixed test_deleted_cwd in test_importlib on AIX. files: Lib/test/test_importlib/import_/test_path.py | 22 ++++++--- 1 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_importlib/import_/test_path.py b/Lib/test/test_importlib/import_/test_path.py --- a/Lib/test/test_importlib/import_/test_path.py +++ b/Lib/test/test_importlib/import_/test_path.py @@ -3,7 +3,6 @@ importlib = util.import_importlib('importlib') machinery = util.import_importlib('importlib.machinery') -import errno import os import sys import tempfile @@ -160,17 +159,24 @@ got = self.machinery.PathFinder.find_spec('whatever', [path]) self.assertEqual(got, success_finder.spec) - @unittest.skipIf(sys.platform == 'win32', "cwd can't not exist on Windows") def test_deleted_cwd(self): # Issue #22834 - self.addCleanup(os.chdir, os.getcwd()) + old_dir = os.getcwd() + self.addCleanup(os.chdir, old_dir) + new_dir = tempfile.mkdtemp() try: - with tempfile.TemporaryDirectory() as path: - os.chdir(path) - except OSError as exc: - if exc.errno == errno.EINVAL: - self.skipTest("platform does not allow the deletion of the cwd") + os.chdir(new_dir) + try: + os.rmdir(new_dir) + except OSError: + # EINVAL on Solaris, EBUSY on AIX, ENOTEMPTY on Windows + self.skipTest("platform does not allow " + "the deletion of the cwd") + except: + os.chdir(old_dir) + os.rmdir(new_dir) raise + with util.import_state(path=['']): # Do not want FileNotFoundError raised. self.assertIsNone(self.machinery.PathFinder.find_spec('whatever')) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Wed Nov 11 03:58:53 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 11 Nov 2015 08:58:53 +0000 Subject: [Python-checkins] Daily reference leaks (d1c11a78b43a): sum=10 Message-ID: <20151111085853.29427.10617@psf.io> results for d1c11a78b43a on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_capi leaked [1, 1, 1] references, sum=3 test_collections leaked [-6, 0, 0] references, sum=-6 test_collections leaked [-3, 1, 0] memory blocks, sum=-2 test_functools leaked [0, 2, 2] memory blocks, sum=4 test_imaplib leaked [0, 2, 0] references, sum=2 test_imaplib leaked [0, 5, 1] memory blocks, sum=6 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogqURxYS', '--timeout', '7200'] From lp_benchmark_robot at intel.com Wed Nov 11 10:16:15 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 11 Nov 2015 15:16:15 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-11 Message-ID: <60651ce4-feff-44e9-872a-af746c3ed64b@irsmsx102.ger.corp.intel.com> Results for project Python default, build date 2015-11-11 04:02:39 +0000 commit: d1c11a78b43a7a56a7c68211306ca5964afdcadf revision date: 2015-11-10 17:52:20 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.16% -2.95% 7.89% 17.60% :-| pybench 0.13% 0.32% -1.48% 8.75% :-( regex_v8 2.84% 2.13% -4.71% 6.12% :-( nbody 0.08% -4.24% -3.30% 11.09% :-| json_dump_v2 0.34% 0.72% 0.13% 10.68% :-| normal_startup 0.83% 0.38% 0.56% 4.78% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Wed Nov 11 10:17:00 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 11 Nov 2015 15:17:00 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-11 Message-ID: <79472352-9bd7-4e41-aea2-adade9ef6bfd@irsmsx102.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-11 04:52:01 +0000 commit: bdd257d60da278614cc221993c1529191a42bceb revision date: 2015-11-10 17:53:37 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% -1.89% 2.18% 10.09% :-) pybench 0.45% -0.20% 6.54% 6.76% :-| regex_v8 0.53% 0.02% -1.61% 7.34% :-) nbody 0.21% 0.03% 8.69% 4.88% :-) json_dump_v2 0.25% -0.01% 2.54% 14.39% :-| normal_startup 1.86% -0.37% -1.59% 2.69% :-| ssbench 0.65% -0.32% -0.65% 3.38% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Wed Nov 11 10:33:40 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 11 Nov 2015 15:33:40 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzc3NTk6?= =?utf-8?q?_Fixed_the_mhlib_module_on_filesystems_that_doesn=27t_support?= Message-ID: <20151111153340.27685.63408@psf.io> https://hg.python.org/cpython/rev/37431d9abbcd changeset: 99056:37431d9abbcd branch: 2.7 parent: 99053:bdd257d60da2 user: Serhiy Storchaka date: Wed Nov 11 17:33:12 2015 +0200 summary: Issue #7759: Fixed the mhlib module on filesystems that doesn't support link counting for directories. files: Lib/mhlib.py | 8 ++++---- Misc/NEWS | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Lib/mhlib.py b/Lib/mhlib.py --- a/Lib/mhlib.py +++ b/Lib/mhlib.py @@ -159,7 +159,7 @@ # Get the link count so we can avoid listing folders # that have no subfolders. nlinks = os.stat(fullname).st_nlink - if nlinks <= 2: + if nlinks == 2: return [] subfolders = [] subnames = os.listdir(fullname) @@ -171,7 +171,7 @@ # Stop looking for subfolders when # we've seen them all nlinks = nlinks - 1 - if nlinks <= 2: + if nlinks == 2: break subfolders.sort() return subfolders @@ -186,7 +186,7 @@ # Get the link count so we can avoid listing folders # that have no subfolders. nlinks = os.stat(fullname).st_nlink - if nlinks <= 2: + if nlinks == 2: return [] subfolders = [] subnames = os.listdir(fullname) @@ -203,7 +203,7 @@ # Stop looking for subfolders when # we've seen them all nlinks = nlinks - 1 - if nlinks <= 2: + if nlinks == 2: break subfolders.sort() return subfolders diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Library ------- +- Issue #7759: Fixed the mhlib module on filesystems that doesn't support + link counting for directories. + - Issue #892902: Fixed pickling recursive objects. - Issue #18010: Fix the pydoc GUI's search function to handle exceptions -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:00:14 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:00:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151112050014.92472.87787@psf.io> https://hg.python.org/cpython/rev/fd273cac682a changeset: 99059:fd273cac682a parent: 99057:fb4e1ec45167 parent: 99058:353d389def60 user: Zachary Ware date: Wed Nov 11 22:54:28 2015 -0600 summary: Merge with 3.5 files: Doc/whatsnew/3.5.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2098,7 +2098,7 @@ improvement in some benchmarks. (Contributed by Antoine Pitrou in :issue:`22847`.) -Objects from :mod:`random` module now use two times less memory on 64-bit +Objects from :mod:`random` module now use 50% less memory on 64-bit builds. (Contributed by Serhiy Storchaka in :issue:`23488`.) The :func:`property` getter calls are up to 25% faster. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:00:17 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:00:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NjAz?= =?utf-8?q?=3A_Add_missing_parenthesis=2E?= Message-ID: <20151112050014.29419.52506@psf.io> https://hg.python.org/cpython/rev/81cc0cea2323 changeset: 99060:81cc0cea2323 branch: 3.5 parent: 99058:353d389def60 user: Zachary Ware date: Wed Nov 11 22:59:44 2015 -0600 summary: Issue #25603: Add missing parenthesis. files: Doc/library/typing.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -478,7 +478,7 @@ Usage:: - Employee = typing.NamedTuple('Employee', [('name', str), 'id', int)]) + Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)]) This is equivalent to:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:00:16 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:00:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Fix_typos_in_whatsnew=2E?= Message-ID: <20151112050014.103676.2283@psf.io> https://hg.python.org/cpython/rev/fb4e1ec45167 changeset: 99057:fb4e1ec45167 parent: 99055:3f392050d519 user: Zachary Ware date: Wed Nov 11 22:41:43 2015 -0600 summary: Fix typos in whatsnew. Reported on docs@ by Igor Zhun. files: Doc/whatsnew/3.6.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -98,8 +98,8 @@ datetime -------- -:meth:`datetime.stftime ` and -:meth:`date.stftime ` methods now support ISO 8601 date +:meth:`datetime.strftime ` and +:meth:`date.strftime ` methods now support ISO 8601 date directives ``%G``, ``%u`` and ``%V``. (Contributed by Ashley Anderson in :issue:`12006`.) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:00:16 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:00:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Closes_=2325603=3A_Merge_with_3=2E5?= Message-ID: <20151112050014.21708.47452@psf.io> https://hg.python.org/cpython/rev/1af59662f6d5 changeset: 99061:1af59662f6d5 parent: 99059:fd273cac682a parent: 99060:81cc0cea2323 user: Zachary Ware date: Wed Nov 11 23:00:01 2015 -0600 summary: Closes #25603: Merge with 3.5 files: Doc/library/typing.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -478,7 +478,7 @@ Usage:: - Employee = typing.NamedTuple('Employee', [('name', str), 'id', int)]) + Employee = typing.NamedTuple('Employee', [('name', str), ('id', int)]) This is equivalent to:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:00:17 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:00:17 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fix_awkward_gr?= =?utf-8?q?ammar_in_whatsnew=2E?= Message-ID: <20151112050014.27687.54258@psf.io> https://hg.python.org/cpython/rev/353d389def60 changeset: 99058:353d389def60 branch: 3.5 parent: 99054:d4dc36586f24 user: Zachary Ware date: Wed Nov 11 22:53:47 2015 -0600 summary: Fix awkward grammar in whatsnew. Reported on docs@ by Keith Briggs. files: Doc/whatsnew/3.5.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -2098,7 +2098,7 @@ improvement in some benchmarks. (Contributed by Antoine Pitrou in :issue:`22847`.) -Objects from :mod:`random` module now use two times less memory on 64-bit +Objects from :mod:`random` module now use 50% less memory on 64-bit builds. (Contributed by Serhiy Storchaka in :issue:`23488`.) The :func:`property` getter calls are up to 25% faster. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:34:17 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:34:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogUmV3cml0ZSByZS5W?= =?utf-8?q?ERBOSE_section=2E?= Message-ID: <20151112053417.17061.1954@psf.io> https://hg.python.org/cpython/rev/b337fc4195cb changeset: 99062:b337fc4195cb branch: 2.7 parent: 99056:37431d9abbcd user: Zachary Ware date: Wed Nov 11 23:32:14 2015 -0600 summary: Rewrite re.VERBOSE section. It now has slightly better rationale and a less awkward wording in the explanation. Inspired by a report of a neither/or conflict by 'animalize' on docs at . files: Doc/library/re.rst | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -514,13 +514,15 @@ .. data:: X VERBOSE - This flag allows you to write regular expressions that look nicer. Whitespace - within the pattern is ignored, except when in a character class or preceded by - an unescaped backslash, and, when a line contains a ``'#'`` neither in a - character class or preceded by an unescaped backslash, all characters from the - leftmost such ``'#'`` through the end of the line are ignored. + This flag allows you to write regular expressions that look nicer and are + more readable by allowing you to visually separate logical sections of the + pattern and add comments. Whitespace within the pattern is ignored, except + when in a character class or when preceded by an unescaped backslash. + When a line contains a ``#`` that is not in a character class and is not + preceded by an unescaped backslash, all characters from the leftmost such + ``#`` through the end of the line are ignored. - That means that the two following regular expression objects that match a + This means that the two following regular expression objects that match a decimal number are functionally equal:: a = re.compile(r"""\d + # the integral part -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:34:17 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:34:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogUmV3cml0ZSByZS5W?= =?utf-8?q?ERBOSE_section=2E?= Message-ID: <20151112053417.58409.30745@psf.io> https://hg.python.org/cpython/rev/b13960fc5fd4 changeset: 99063:b13960fc5fd4 branch: 3.4 parent: 99050:3c0a817ab616 user: Zachary Ware date: Wed Nov 11 23:32:14 2015 -0600 summary: Rewrite re.VERBOSE section. It now has slightly better rationale and a less awkward wording in the explanation. Inspired by a report of a neither/or conflict by 'animalize' on docs at . files: Doc/library/re.rst | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -548,13 +548,15 @@ .. data:: X VERBOSE - This flag allows you to write regular expressions that look nicer. Whitespace - within the pattern is ignored, except when in a character class or preceded by - an unescaped backslash, and, when a line contains a ``'#'`` neither in a - character class or preceded by an unescaped backslash, all characters from the - leftmost such ``'#'`` through the end of the line are ignored. + This flag allows you to write regular expressions that look nicer and are + more readable by allowing you to visually separate logical sections of the + pattern and add comments. Whitespace within the pattern is ignored, except + when in a character class or when preceded by an unescaped backslash. + When a line contains a ``#`` that is not in a character class and is not + preceded by an unescaped backslash, all characters from the leftmost such + ``#`` through the end of the line are ignored. - That means that the two following regular expression objects that match a + This means that the two following regular expression objects that match a decimal number are functionally equal:: a = re.compile(r"""\d + # the integral part -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:34:17 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:34:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151112053417.33554.82773@psf.io> https://hg.python.org/cpython/rev/15b0ea7134da changeset: 99064:15b0ea7134da branch: 3.5 parent: 99060:81cc0cea2323 parent: 99063:b13960fc5fd4 user: Zachary Ware date: Wed Nov 11 23:33:50 2015 -0600 summary: Merge with 3.4 files: Doc/library/re.rst | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -556,13 +556,15 @@ .. data:: X VERBOSE - This flag allows you to write regular expressions that look nicer. Whitespace - within the pattern is ignored, except when in a character class or preceded by - an unescaped backslash, and, when a line contains a ``'#'`` neither in a - character class or preceded by an unescaped backslash, all characters from the - leftmost such ``'#'`` through the end of the line are ignored. + This flag allows you to write regular expressions that look nicer and are + more readable by allowing you to visually separate logical sections of the + pattern and add comments. Whitespace within the pattern is ignored, except + when in a character class or when preceded by an unescaped backslash. + When a line contains a ``#`` that is not in a character class and is not + preceded by an unescaped backslash, all characters from the leftmost such + ``#`` through the end of the line are ignored. - That means that the two following regular expression objects that match a + This means that the two following regular expression objects that match a decimal number are functionally equal:: a = re.compile(r"""\d + # the integral part -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 00:34:18 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 05:34:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151112053417.33528.75883@psf.io> https://hg.python.org/cpython/rev/c7fbef40b62b changeset: 99065:c7fbef40b62b parent: 99061:1af59662f6d5 parent: 99064:15b0ea7134da user: Zachary Ware date: Wed Nov 11 23:34:00 2015 -0600 summary: Merge with 3.5 files: Doc/library/re.rst | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Doc/library/re.rst b/Doc/library/re.rst --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -556,13 +556,15 @@ .. data:: X VERBOSE - This flag allows you to write regular expressions that look nicer. Whitespace - within the pattern is ignored, except when in a character class or preceded by - an unescaped backslash, and, when a line contains a ``'#'`` neither in a - character class or preceded by an unescaped backslash, all characters from the - leftmost such ``'#'`` through the end of the line are ignored. + This flag allows you to write regular expressions that look nicer and are + more readable by allowing you to visually separate logical sections of the + pattern and add comments. Whitespace within the pattern is ignored, except + when in a character class or when preceded by an unescaped backslash. + When a line contains a ``#`` that is not in a character class and is not + preceded by an unescaped backslash, all characters from the leftmost such + ``#`` through the end of the line are ignored. - That means that the two following regular expression objects that match a + This means that the two following regular expression objects that match a decimal number are functionally equal:: a = re.compile(r"""\d + # the integral part -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:14:45 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:14:45 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_fix_memory_lea?= =?utf-8?q?k_in_=5Fget=5Fcrl=5Fdp_=28closes_=2325569=29?= Message-ID: <20151112061445.115886.33562@psf.io> https://hg.python.org/cpython/rev/10c3646b2d59 changeset: 99066:10c3646b2d59 branch: 2.7 parent: 99062:b337fc4195cb user: Benjamin Peterson date: Wed Nov 11 22:07:38 2015 -0800 summary: fix memory leak in _get_crl_dp (closes #25569) Patch started by St?phane Wirtel. files: Misc/NEWS | 2 + Modules/_ssl.c | 54 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Library ------- +- Issue #25569: Fix memory leak in SSLSocket.getpeercert(). + - Issue #7759: Fixed the mhlib module on filesystems that doesn't support link counting for directories. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1015,25 +1015,23 @@ static PyObject * _get_crl_dp(X509 *certificate) { STACK_OF(DIST_POINT) *dps; - int i, j, result; - PyObject *lst; + int i, j; + PyObject *lst, *res = NULL; #if OPENSSL_VERSION_NUMBER < 0x10001000L - dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, - NULL, NULL); + dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); #else /* Calls x509v3_cache_extensions and sets up crldp */ X509_check_ca(certificate); dps = certificate->crldp; #endif - if (dps == NULL) { + if (dps == NULL) return Py_None; - } - - if ((lst = PyList_New(0)) == NULL) { - return NULL; - } + + lst = PyList_New(0); + if (lst == NULL) + goto done; for (i=0; i < sk_DIST_POINT_num(dps); i++) { DIST_POINT *dp; @@ -1046,6 +1044,7 @@ GENERAL_NAME *gn; ASN1_IA5STRING *uri; PyObject *ouri; + int err; gn = sk_GENERAL_NAME_value(gns, j); if (gn->type != GEN_URI) { @@ -1054,28 +1053,25 @@ uri = gn->d.uniformResourceIdentifier; ouri = PyUnicode_FromStringAndSize((char *)uri->data, uri->length); - if (ouri == NULL) { - Py_DECREF(lst); - return NULL; - } - result = PyList_Append(lst, ouri); + if (ouri == NULL) + goto done; + + err = PyList_Append(lst, ouri); Py_DECREF(ouri); - if (result < 0) { - Py_DECREF(lst); - return NULL; - } + if (err < 0) + goto done; } } - /* convert to tuple or None */ - if (PyList_Size(lst) == 0) { - Py_DECREF(lst); - return Py_None; - } else { - PyObject *tup; - tup = PyList_AsTuple(lst); - Py_DECREF(lst); - return tup; - } + + /* Convert to tuple. */ + res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; + + done: + Py_XDECREF(lst); +#if OPENSSL_VERSION_NUMBER < 0x10001000L + sk_DIST_POINT_free(dsp); +#endif + return res; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:14:46 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:14:46 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E5_=28=2325569=29?= Message-ID: <20151112061446.17051.93489@psf.io> https://hg.python.org/cpython/rev/07a298572d93 changeset: 99068:07a298572d93 branch: 3.5 parent: 99064:15b0ea7134da parent: 99067:aabe273b20ab user: Benjamin Peterson date: Wed Nov 11 22:14:08 2015 -0800 summary: merge 3.5 (#25569) files: Misc/NEWS | 2 + Modules/_ssl.c | 54 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -229,6 +229,8 @@ - Issue #24881: Fixed setting binary mode in Python implementation of FileIO on Windows and Cygwin. Patch from Akira Li. +- Issue #25569: Fix memory leak in SSLSocket.getpeercert(). + - Issue #25471: Sockets returned from accept() shouldn't appear to be nonblocking. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1067,25 +1067,23 @@ static PyObject * _get_crl_dp(X509 *certificate) { STACK_OF(DIST_POINT) *dps; - int i, j, result; - PyObject *lst; + int i, j; + PyObject *lst, *res = NULL; #if OPENSSL_VERSION_NUMBER < 0x10001000L - dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, - NULL, NULL); + dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); #else /* Calls x509v3_cache_extensions and sets up crldp */ X509_check_ca(certificate); dps = certificate->crldp; #endif - if (dps == NULL) { + if (dps == NULL) return Py_None; - } - - if ((lst = PyList_New(0)) == NULL) { - return NULL; - } + + lst = PyList_New(0); + if (lst == NULL) + goto done; for (i=0; i < sk_DIST_POINT_num(dps); i++) { DIST_POINT *dp; @@ -1098,6 +1096,7 @@ GENERAL_NAME *gn; ASN1_IA5STRING *uri; PyObject *ouri; + int err; gn = sk_GENERAL_NAME_value(gns, j); if (gn->type != GEN_URI) { @@ -1106,28 +1105,25 @@ uri = gn->d.uniformResourceIdentifier; ouri = PyUnicode_FromStringAndSize((char *)uri->data, uri->length); - if (ouri == NULL) { - Py_DECREF(lst); - return NULL; - } - result = PyList_Append(lst, ouri); + if (ouri == NULL) + goto done; + + err = PyList_Append(lst, ouri); Py_DECREF(ouri); - if (result < 0) { - Py_DECREF(lst); - return NULL; - } + if (err < 0) + goto done; } } - /* convert to tuple or None */ - if (PyList_Size(lst) == 0) { - Py_DECREF(lst); - return Py_None; - } else { - PyObject *tup; - tup = PyList_AsTuple(lst); - Py_DECREF(lst); - return tup; - } + + /* Convert to tuple. */ + res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; + + done: + Py_XDECREF(lst); +#if OPENSSL_VERSION_NUMBER < 0x10001000L + sk_DIST_POINT_free(dsp); +#endif + return res; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:14:46 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:14:46 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41ICgjMjU1Njkp?= Message-ID: <20151112061446.17069.11688@psf.io> https://hg.python.org/cpython/rev/fb55b1ab43fc changeset: 99069:fb55b1ab43fc parent: 99065:c7fbef40b62b parent: 99068:07a298572d93 user: Benjamin Peterson date: Wed Nov 11 22:14:31 2015 -0800 summary: merge 3.5 (#25569) files: Misc/NEWS | 2 + Modules/_ssl.c | 54 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -233,6 +233,8 @@ - Issue #13248: Remove deprecated inspect.getargspec and inspect.getmoduleinfo functions. +- Issue #25569: Fix memory leak in SSLSocket.getpeercert(). + - Issue #25471: Sockets returned from accept() shouldn't appear to be nonblocking. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1067,25 +1067,23 @@ static PyObject * _get_crl_dp(X509 *certificate) { STACK_OF(DIST_POINT) *dps; - int i, j, result; - PyObject *lst; + int i, j; + PyObject *lst, *res = NULL; #if OPENSSL_VERSION_NUMBER < 0x10001000L - dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, - NULL, NULL); + dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); #else /* Calls x509v3_cache_extensions and sets up crldp */ X509_check_ca(certificate); dps = certificate->crldp; #endif - if (dps == NULL) { + if (dps == NULL) return Py_None; - } - - if ((lst = PyList_New(0)) == NULL) { - return NULL; - } + + lst = PyList_New(0); + if (lst == NULL) + goto done; for (i=0; i < sk_DIST_POINT_num(dps); i++) { DIST_POINT *dp; @@ -1098,6 +1096,7 @@ GENERAL_NAME *gn; ASN1_IA5STRING *uri; PyObject *ouri; + int err; gn = sk_GENERAL_NAME_value(gns, j); if (gn->type != GEN_URI) { @@ -1106,28 +1105,25 @@ uri = gn->d.uniformResourceIdentifier; ouri = PyUnicode_FromStringAndSize((char *)uri->data, uri->length); - if (ouri == NULL) { - Py_DECREF(lst); - return NULL; - } - result = PyList_Append(lst, ouri); + if (ouri == NULL) + goto done; + + err = PyList_Append(lst, ouri); Py_DECREF(ouri); - if (result < 0) { - Py_DECREF(lst); - return NULL; - } + if (err < 0) + goto done; } } - /* convert to tuple or None */ - if (PyList_Size(lst) == 0) { - Py_DECREF(lst); - return Py_None; - } else { - PyObject *tup; - tup = PyList_AsTuple(lst); - Py_DECREF(lst); - return tup; - } + + /* Convert to tuple. */ + res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; + + done: + Py_XDECREF(lst); +#if OPENSSL_VERSION_NUMBER < 0x10001000L + sk_DIST_POINT_free(dsp); +#endif + return res; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:14:46 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:14:46 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_fix_memory_lea?= =?utf-8?q?k_in_=5Fget=5Fcrl=5Fdp_=28closes_=2325569=29?= Message-ID: <20151112061446.103686.7096@psf.io> https://hg.python.org/cpython/rev/aabe273b20ab changeset: 99067:aabe273b20ab branch: 3.4 parent: 99063:b13960fc5fd4 user: Benjamin Peterson date: Wed Nov 11 22:07:38 2015 -0800 summary: fix memory leak in _get_crl_dp (closes #25569) Patch started by St?phane Wirtel. files: Misc/NEWS | 2 + Modules/_ssl.c | 54 +++++++++++++++++-------------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -107,6 +107,8 @@ at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. +- Issue #25569: Fix memory leak in SSLSocket.getpeercert(). + - Issue #21827: Fixed textwrap.dedent() for the case when largest common whitespace is a substring of smallest leading whitespace. Based on patch by Robert Li. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1027,25 +1027,23 @@ static PyObject * _get_crl_dp(X509 *certificate) { STACK_OF(DIST_POINT) *dps; - int i, j, result; - PyObject *lst; + int i, j; + PyObject *lst, *res = NULL; #if OPENSSL_VERSION_NUMBER < 0x10001000L - dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, - NULL, NULL); + dps = X509_get_ext_d2i(certificate, NID_crl_distribution_points, NULL, NULL); #else /* Calls x509v3_cache_extensions and sets up crldp */ X509_check_ca(certificate); dps = certificate->crldp; #endif - if (dps == NULL) { + if (dps == NULL) return Py_None; - } - - if ((lst = PyList_New(0)) == NULL) { - return NULL; - } + + lst = PyList_New(0); + if (lst == NULL) + goto done; for (i=0; i < sk_DIST_POINT_num(dps); i++) { DIST_POINT *dp; @@ -1058,6 +1056,7 @@ GENERAL_NAME *gn; ASN1_IA5STRING *uri; PyObject *ouri; + int err; gn = sk_GENERAL_NAME_value(gns, j); if (gn->type != GEN_URI) { @@ -1066,28 +1065,25 @@ uri = gn->d.uniformResourceIdentifier; ouri = PyUnicode_FromStringAndSize((char *)uri->data, uri->length); - if (ouri == NULL) { - Py_DECREF(lst); - return NULL; - } - result = PyList_Append(lst, ouri); + if (ouri == NULL) + goto done; + + err = PyList_Append(lst, ouri); Py_DECREF(ouri); - if (result < 0) { - Py_DECREF(lst); - return NULL; - } + if (err < 0) + goto done; } } - /* convert to tuple or None */ - if (PyList_Size(lst) == 0) { - Py_DECREF(lst); - return Py_None; - } else { - PyObject *tup; - tup = PyList_AsTuple(lst); - Py_DECREF(lst); - return tup; - } + + /* Convert to tuple. */ + res = (PyList_GET_SIZE(lst) > 0) ? PyList_AsTuple(lst) : Py_None; + + done: + Py_XDECREF(lst); +#if OPENSSL_VERSION_NUMBER < 0x10001000L + sk_DIST_POINT_free(dsp); +#endif + return res; } static PyObject * -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:45:47 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:45:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_always_set_OP?= =?utf-8?q?=5FNO=5FSSLv3_by_default_=28closes_=2325530=29?= Message-ID: <20151112064547.29429.66631@psf.io> https://hg.python.org/cpython/rev/56f64ec9259f changeset: 99071:56f64ec9259f branch: 3.4 parent: 99067:aabe273b20ab user: Benjamin Peterson date: Wed Nov 11 22:38:41 2015 -0800 summary: always set OP_NO_SSLv3 by default (closes #25530) files: Lib/test/test_ssl.py | 18 +++++++++--------- Misc/NEWS | 3 +++ Modules/_ssl.c | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -674,11 +674,11 @@ @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - # OP_ALL | OP_NO_SSLv2 is the default value - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, + # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, ctx.options) - ctx.options |= ssl.OP_NO_SSLv3 - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1, ctx.options) if can_clear_options(): ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 @@ -2172,17 +2172,17 @@ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED) @@ -2214,8 +2214,8 @@ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True, - client_options=ssl.OP_NO_SSLv2) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, + False, client_options=ssl.OP_NO_SSLv2) @skip_if_broken_ubuntu_ssl def test_protocol_tlsv1(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -107,6 +107,9 @@ at the end if the FileInput was opened with binary mode. Patch by Ryosuke Ito. +- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating + ssl.SSLContext. + - Issue #25569: Fix memory leak in SSLSocket.getpeercert(). - Issue #21827: Fixed textwrap.dedent() for the case when largest common diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2037,6 +2037,8 @@ options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (proto_version != PY_SSL_VERSION_SSL2) options |= SSL_OP_NO_SSLv2; + if (proto_version != PY_SSL_VERSION_SSL3) + options |= SSL_OP_NO_SSLv3; SSL_CTX_set_options(self->ctx, options); #ifndef OPENSSL_NO_ECDH -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:45:47 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:45:47 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E4_=28=2325530=29?= Message-ID: <20151112064547.21724.55825@psf.io> https://hg.python.org/cpython/rev/d1737db0f1b2 changeset: 99072:d1737db0f1b2 branch: 3.5 parent: 99068:07a298572d93 parent: 99071:56f64ec9259f user: Benjamin Peterson date: Wed Nov 11 22:45:22 2015 -0800 summary: merge 3.4 (#25530) files: Lib/test/test_ssl.py | 18 +++++++++--------- Misc/NEWS | 3 +++ Modules/_ssl.c | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -784,11 +784,11 @@ @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - # OP_ALL | OP_NO_SSLv2 is the default value - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, + # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, ctx.options) - ctx.options |= ssl.OP_NO_SSLv3 - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1, ctx.options) if can_clear_options(): ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 @@ -2451,17 +2451,17 @@ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3') + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1') if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) @@ -2493,8 +2493,8 @@ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3', - client_options=ssl.OP_NO_SSLv2) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, + False, client_options=ssl.OP_NO_SSLv2) @skip_if_broken_ubuntu_ssl def test_protocol_tlsv1(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -229,6 +229,9 @@ - Issue #24881: Fixed setting binary mode in Python implementation of FileIO on Windows and Cygwin. Patch from Akira Li. +- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating + ssl.SSLContext. + - Issue #25569: Fix memory leak in SSLSocket.getpeercert(). - Issue #25471: Sockets returned from accept() shouldn't appear to be diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2276,6 +2276,8 @@ options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (proto_version != PY_SSL_VERSION_SSL2) options |= SSL_OP_NO_SSLv2; + if (proto_version != PY_SSL_VERSION_SSL3) + options |= SSL_OP_NO_SSLv3; SSL_CTX_set_options(self->ctx, options); #ifndef OPENSSL_NO_ECDH -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:45:47 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:45:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41ICgjMjU1MzAp?= Message-ID: <20151112064547.27695.59721@psf.io> https://hg.python.org/cpython/rev/2899acbd2b46 changeset: 99073:2899acbd2b46 parent: 99069:fb55b1ab43fc parent: 99072:d1737db0f1b2 user: Benjamin Peterson date: Wed Nov 11 22:45:36 2015 -0800 summary: merge 3.5 (#25530) files: Lib/test/test_ssl.py | 18 +++++++++--------- Misc/NEWS | 3 +++ Modules/_ssl.c | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -784,11 +784,11 @@ @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - # OP_ALL | OP_NO_SSLv2 is the default value - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, + # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, ctx.options) - ctx.options |= ssl.OP_NO_SSLv3 - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1, ctx.options) if can_clear_options(): ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 @@ -2451,17 +2451,17 @@ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3') + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1') if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) @@ -2493,8 +2493,8 @@ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3', - client_options=ssl.OP_NO_SSLv2) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, + False, client_options=ssl.OP_NO_SSLv2) @skip_if_broken_ubuntu_ssl def test_protocol_tlsv1(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -233,6 +233,9 @@ - Issue #13248: Remove deprecated inspect.getargspec and inspect.getmoduleinfo functions. +- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating + ssl.SSLContext. + - Issue #25569: Fix memory leak in SSLSocket.getpeercert(). - Issue #25471: Sockets returned from accept() shouldn't appear to be diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2276,6 +2276,8 @@ options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (proto_version != PY_SSL_VERSION_SSL2) options |= SSL_OP_NO_SSLv2; + if (proto_version != PY_SSL_VERSION_SSL3) + options |= SSL_OP_NO_SSLv3; SSL_CTX_set_options(self->ctx, options); #ifndef OPENSSL_NO_ECDH -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 01:45:47 2015 From: python-checkins at python.org (benjamin.peterson) Date: Thu, 12 Nov 2015 06:45:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_always_set_OP?= =?utf-8?q?=5FNO=5FSSLv3_by_default_=28closes_=2325530=29?= Message-ID: <20151112064547.58411.74477@psf.io> https://hg.python.org/cpython/rev/d80954d941c7 changeset: 99070:d80954d941c7 branch: 2.7 parent: 99066:10c3646b2d59 user: Benjamin Peterson date: Wed Nov 11 22:38:41 2015 -0800 summary: always set OP_NO_SSLv3 by default (closes #25530) files: Lib/test/test_ssl.py | 18 +++++++++--------- Misc/NEWS | 3 +++ Modules/_ssl.c | 2 ++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -714,11 +714,11 @@ @skip_if_broken_ubuntu_ssl def test_options(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) - # OP_ALL | OP_NO_SSLv2 is the default value - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, + # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, ctx.options) - ctx.options |= ssl.OP_NO_SSLv3 - self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, + ctx.options |= ssl.OP_NO_TLSv1 + self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1, ctx.options) if can_clear_options(): ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 @@ -2230,17 +2230,17 @@ " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n" % str(x)) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3') + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1') if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL) if hasattr(ssl, 'PROTOCOL_SSLv3'): - try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED) + try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED) try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED) @@ -2272,8 +2272,8 @@ try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False) if no_sslv2_implies_sslv3_hello(): # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs - try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3', - client_options=ssl.OP_NO_SSLv2) + try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, + False, client_options=ssl.OP_NO_SSLv2) @skip_if_broken_ubuntu_ssl def test_protocol_tlsv1(self): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,9 @@ Library ------- +- Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating + ssl.SSLContext. + - Issue #25569: Fix memory leak in SSLSocket.getpeercert(). - Issue #7759: Fixed the mhlib module on filesystems that doesn't support diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -2046,6 +2046,8 @@ options = SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; if (proto_version != PY_SSL_VERSION_SSL2) options |= SSL_OP_NO_SSLv2; + if (proto_version != PY_SSL_VERSION_SSL3) + options |= SSL_OP_NO_SSLv3; SSL_CTX_set_options(self->ctx, options); #ifndef OPENSSL_NO_ECDH -- Repository URL: https://hg.python.org/cpython From benjamin at python.org Thu Nov 12 01:50:05 2015 From: benjamin at python.org (Benjamin Peterson) Date: Wed, 11 Nov 2015 22:50:05 -0800 Subject: [Python-checkins] cpython (2.7): Backport early-out 91259f061cfb to reduce the cost of bb1a2944bcb6 In-Reply-To: <20151007031207.18390.20414@psf.io> References: <20151007031207.18390.20414@psf.io> Message-ID: <1447311005.2650788.436807905.05A186FE@webmail.messagingengine.com> On Tue, Oct 6, 2015, at 19:12, raymond.hettinger wrote: > https://hg.python.org/cpython/rev/37aee118e1a3 > changeset: 98578:37aee118e1a3 > branch: 2.7 > parent: 98572:60c44a09c5fc > user: Raymond Hettinger > date: Tue Oct 06 23:12:02 2015 -0400 > summary: > Backport early-out 91259f061cfb to reduce the cost of bb1a2944bcb6 > > files: > Modules/_collectionsmodule.c | 6 +++++- > 1 files changed, 5 insertions(+), 1 deletions(-) > > > diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c > --- a/Modules/_collectionsmodule.c > +++ b/Modules/_collectionsmodule.c > @@ -651,6 +651,9 @@ > Py_ssize_t n; > PyObject *item; > > + if (Py_SIZE(deque) == 0) > + return; > + dequeue is not varsized in Python 2.7, so using Py_SIZE() is incorrect. From solipsis at pitrou.net Thu Nov 12 03:42:03 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 12 Nov 2015 08:42:03 +0000 Subject: [Python-checkins] Daily reference leaks (c7fbef40b62b): sum=7 Message-ID: <20151112084203.27705.3117@psf.io> results for c7fbef40b62b on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflog2f4jdB', '--timeout', '7200'] From python-checkins at python.org Thu Nov 12 04:35:16 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 09:35:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIyOTk1?= =?utf-8?q?=3A_Default_implementation_of_=5F=5Freduce=5F=5F_and_=5F=5Fredu?= =?utf-8?b?Y2VfZXhfXyBub3c=?= Message-ID: <20151112093516.29421.16265@psf.io> https://hg.python.org/cpython/rev/c8841db9433d changeset: 99074:c8841db9433d branch: 3.4 parent: 99071:56f64ec9259f user: Serhiy Storchaka date: Thu Nov 12 11:23:04 2015 +0200 summary: Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. Added tests for non-pickleable types. files: Lib/test/test_dictviews.py | 18 ++++++++++++++++++ Lib/test/test_generators.py | 20 ++++++++++++++++++++ Lib/test/test_xml_etree.py | 14 ++++++++++++++ Lib/test/test_zlib.py | 11 +++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 12 ++++++++++++ 6 files changed, 78 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,3 +1,5 @@ +import copy +import pickle import unittest from test import support @@ -198,6 +200,22 @@ d[42] = d.values() self.assertRaises(RuntimeError, repr, d) + def test_copy(self): + d = {1: 10, "a": "ABC"} + self.assertRaises(TypeError, copy.copy, d.keys()) + self.assertRaises(TypeError, copy.copy, d.values()) + self.assertRaises(TypeError, copy.copy, d.items()) + + def test_pickle(self): + d = {1: 10, "a": "ABC"} + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.keys(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.values(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.items(), proto) + def test_main(): support.run_unittest(DictSetTest) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1,4 +1,6 @@ +import copy import gc +import pickle import sys import unittest import weakref @@ -70,6 +72,24 @@ self.assertEqual(cm.exception.value, 2) +class GeneratorTest(unittest.TestCase): + + def test_copy(self): + def f(): + yield 1 + g = f() + with self.assertRaises(TypeError): + copy.copy(g) + + def test_pickle(self): + def f(): + yield 1 + g = f() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(g, proto) + + class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception # is correctly saved/restored in PyEval_EvalFrameEx(). diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -5,6 +5,7 @@ # For this purpose, the module-level "ET" symbol is temporarily # monkey-patched when running the "test_xml_etree_c" test suite. +import copy import html import io import operator @@ -2082,6 +2083,19 @@ self.assertEqual(self._ilist(doc), all_tags) self.assertEqual(self._ilist(doc, '*'), all_tags) + def test_copy(self): + a = ET.Element('a') + it = a.iter() + with self.assertRaises(TypeError): + copy.copy(it) + + def test_pickle(self): + a = ET.Element('a') + it = a.iter() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(it, proto) + class TreeBuilderTest(unittest.TestCase): sample1 = ('tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + Py_TYPE(obj)->tp_name); + return NULL; + } if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { return NULL; } @@ -4046,6 +4052,12 @@ Py_ssize_t i, n; _Py_IDENTIFIER(__newobj__); + if (Py_TYPE(obj)->tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + Py_TYPE(obj)->tp_name); + return NULL; + } if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) { return NULL; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 04:35:16 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 09:35:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2322995=3A_Default_implementation_of_=5F=5Freduce=5F=5F?= =?utf-8?q?_and_=5F=5Freduce=5Fex=5F=5F_now?= Message-ID: <20151112093516.29415.23388@psf.io> https://hg.python.org/cpython/rev/4c05e7c195ac changeset: 99075:4c05e7c195ac branch: 3.5 parent: 99072:d1737db0f1b2 parent: 99074:c8841db9433d user: Serhiy Storchaka date: Thu Nov 12 11:31:51 2015 +0200 summary: Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. Added tests for non-pickleable types. files: Lib/test/test_coroutines.py | 30 +++++++++++++++++++++++++ Lib/test/test_dictviews.py | 18 +++++++++++++++ Lib/test/test_generators.py | 17 ++++++++++++++ Lib/test/test_xml_etree.py | 14 +++++++++++ Lib/test/test_zlib.py | 11 +++++++++ Misc/NEWS | 3 ++ Objects/typeobject.c | 6 +++++ 7 files changed, 99 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1,5 +1,7 @@ import contextlib +import copy import inspect +import pickle import sys import types import unittest @@ -1318,6 +1320,34 @@ run_async(foo()) self.assertEqual(CNT, 0) + def test_copy(self): + async def func(): pass + coro = func() + with self.assertRaises(TypeError): + copy.copy(coro) + + aw = coro.__await__() + try: + with self.assertRaises(TypeError): + copy.copy(aw) + finally: + aw.close() + + def test_pickle(self): + async def func(): pass + coro = func() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(coro, proto) + + aw = coro.__await__() + try: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(aw, proto) + finally: + aw.close() + class CoroAsyncIOCompatTest(unittest.TestCase): diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,3 +1,5 @@ +import copy +import pickle import unittest class DictSetTest(unittest.TestCase): @@ -197,6 +199,22 @@ d[42] = d.values() self.assertRaises(RecursionError, repr, d) + def test_copy(self): + d = {1: 10, "a": "ABC"} + self.assertRaises(TypeError, copy.copy, d.keys()) + self.assertRaises(TypeError, copy.copy, d.values()) + self.assertRaises(TypeError, copy.copy, d.items()) + + def test_pickle(self): + d = {1: 10, "a": "ABC"} + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.keys(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.values(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.items(), proto) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1,4 +1,6 @@ +import copy import gc +import pickle import sys import unittest import warnings @@ -111,6 +113,21 @@ self.assertEqual(gen.__qualname__, "GeneratorTest.test_name..") + def test_copy(self): + def f(): + yield 1 + g = f() + with self.assertRaises(TypeError): + copy.copy(g) + + def test_pickle(self): + def f(): + yield 1 + g = f() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(g, proto) + class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -5,6 +5,7 @@ # For this purpose, the module-level "ET" symbol is temporarily # monkey-patched when running the "test_xml_etree_c" test suite. +import copy import html import io import operator @@ -2082,6 +2083,19 @@ self.assertEqual(self._ilist(doc), all_tags) self.assertEqual(self._ilist(doc, '*'), all_tags) + def test_copy(self): + a = ET.Element('a') + it = a.iter() + with self.assertRaises(TypeError): + copy.copy(it) + + def test_pickle(self): + a = ET.Element('a') + it = a.iter() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(it, proto) + class TreeBuilderTest(unittest.TestCase): sample1 = ('tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + Py_TYPE(obj)->tp_name); + return NULL; + } if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 04:35:16 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 09:35:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2322995=3A_Default_implementation_of_=5F=5Freduce?= =?utf-8?b?X18gYW5kIF9fcmVkdWNlX2V4X18gbm93?= Message-ID: <20151112093516.103698.40037@psf.io> https://hg.python.org/cpython/rev/a2f574896f49 changeset: 99076:a2f574896f49 parent: 99073:2899acbd2b46 parent: 99075:4c05e7c195ac user: Serhiy Storchaka date: Thu Nov 12 11:34:39 2015 +0200 summary: Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. Added tests for non-pickleable types. files: Lib/test/test_coroutines.py | 30 +++++++++++++++++++++++++ Lib/test/test_dictviews.py | 18 +++++++++++++++ Lib/test/test_generators.py | 17 ++++++++++++++ Lib/test/test_xml_etree.py | 14 +++++++++++ Lib/test/test_zlib.py | 11 +++++++++ Misc/NEWS | 3 ++ Objects/typeobject.c | 6 +++++ 7 files changed, 99 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -1,5 +1,7 @@ import contextlib +import copy import inspect +import pickle import sys import types import unittest @@ -1318,6 +1320,34 @@ run_async(foo()) self.assertEqual(CNT, 0) + def test_copy(self): + async def func(): pass + coro = func() + with self.assertRaises(TypeError): + copy.copy(coro) + + aw = coro.__await__() + try: + with self.assertRaises(TypeError): + copy.copy(aw) + finally: + aw.close() + + def test_pickle(self): + async def func(): pass + coro = func() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(coro, proto) + + aw = coro.__await__() + try: + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(aw, proto) + finally: + aw.close() + class CoroAsyncIOCompatTest(unittest.TestCase): diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,4 +1,6 @@ import collections +import copy +import pickle import unittest class DictSetTest(unittest.TestCase): @@ -198,6 +200,22 @@ d[42] = d.values() self.assertRaises(RecursionError, repr, d) + def test_copy(self): + d = {1: 10, "a": "ABC"} + self.assertRaises(TypeError, copy.copy, d.keys()) + self.assertRaises(TypeError, copy.copy, d.values()) + self.assertRaises(TypeError, copy.copy, d.items()) + + def test_pickle(self): + d = {1: 10, "a": "ABC"} + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.keys(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.values(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.items(), proto) + def test_abc_registry(self): d = dict(a=1) diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -1,4 +1,6 @@ +import copy import gc +import pickle import sys import unittest import warnings @@ -111,6 +113,21 @@ self.assertEqual(gen.__qualname__, "GeneratorTest.test_name..") + def test_copy(self): + def f(): + yield 1 + g = f() + with self.assertRaises(TypeError): + copy.copy(g) + + def test_pickle(self): + def f(): + yield 1 + g = f() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(g, proto) + class ExceptionTest(unittest.TestCase): # Tests for the issue #23353: check that the currently handled exception diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -5,6 +5,7 @@ # For this purpose, the module-level "ET" symbol is temporarily # monkey-patched when running the "test_xml_etree_c" test suite. +import copy import html import io import operator @@ -2082,6 +2083,19 @@ self.assertEqual(self._ilist(doc), all_tags) self.assertEqual(self._ilist(doc, '*'), all_tags) + def test_copy(self): + a = ET.Element('a') + it = a.iter() + with self.assertRaises(TypeError): + copy.copy(it) + + def test_pickle(self): + a = ET.Element('a') + it = a.iter() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(it, proto) + class TreeBuilderTest(unittest.TestCase): sample1 = ('tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + Py_TYPE(obj)->tp_name); + return NULL; + } if (_PyObject_GetNewArguments(obj, &args, &kwargs) < 0) return NULL; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 04:37:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 09:37:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIyOTk1?= =?utf-8?q?=3A_Backported_additional_tests_for_non-pickleable_types=2E?= Message-ID: <20151112093709.21734.64523@psf.io> https://hg.python.org/cpython/rev/94664fb4354e changeset: 99077:94664fb4354e branch: 2.7 parent: 99070:d80954d941c7 user: Serhiy Storchaka date: Thu Nov 12 11:36:42 2015 +0200 summary: Issue #22995: Backported additional tests for non-pickleable types. files: Lib/test/test_dictviews.py | 18 ++++++++++++++++++ Lib/test/test_zlib.py | 11 +++++++++++ 2 files changed, 29 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py --- a/Lib/test/test_dictviews.py +++ b/Lib/test/test_dictviews.py @@ -1,3 +1,5 @@ +import copy +import pickle import unittest import collections from test import test_support @@ -186,6 +188,22 @@ self.assertIsInstance(d.viewitems(), collections.Iterable) self.assertIsInstance(d.viewitems(), collections.Container) + def test_copy(self): + d = {1: 10, "a": "ABC"} + self.assertRaises(TypeError, copy.copy, d.viewkeys()) + self.assertRaises(TypeError, copy.copy, d.viewvalues()) + self.assertRaises(TypeError, copy.copy, d.viewitems()) + + def test_pickle(self): + d = {1: 10, "a": "ABC"} + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.viewkeys(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.viewvalues(), proto) + self.assertRaises((TypeError, pickle.PicklingError), + pickle.dumps, d.viewitems(), proto) + def test_main(): test_support.run_unittest(DictSetTest) diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -1,6 +1,7 @@ import unittest from test.test_support import TESTFN, run_unittest, import_module, unlink, requires import binascii +import pickle import random from test.test_support import precisionbigmemtest, _1G, _4G import sys @@ -502,6 +503,16 @@ d.flush() self.assertRaises(ValueError, d.copy) + def test_compresspickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto) + + def test_decompresspickle(self): + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.assertRaises((TypeError, pickle.PicklingError)): + pickle.dumps(zlib.decompressobj(), proto) + # Memory use of the following functions takes into account overallocation @precisionbigmemtest(size=_1G + 1024 * 1024, memuse=3) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 05:01:06 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 10:01:06 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIyOTk1?= =?utf-8?q?=3A_Default_implementation_of_=5F=5Freduce=5F=5F_and_=5F=5Fredu?= =?utf-8?b?Y2VfZXhfXyBub3c=?= Message-ID: <20151112100105.115900.95154@psf.io> https://hg.python.org/cpython/rev/2b950eba9792 changeset: 99078:2b950eba9792 branch: 2.7 user: Serhiy Storchaka date: Thu Nov 12 11:59:03 2015 +0200 summary: Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. files: Misc/NEWS | 3 +++ Objects/typeobject.c | 7 +++++++ 2 files changed, 10 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now + rejects builtin types with not defined __new__. + - Issue #7267: format(int, 'c') now raises OverflowError when the argument is not in range(0, 256). diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3214,6 +3214,13 @@ if (cls == NULL) return NULL; + if (PyType_Check(cls) && ((PyTypeObject *)cls)->tp_new == NULL) { + PyErr_Format(PyExc_TypeError, + "can't pickle %s objects", + ((PyTypeObject *)cls)->tp_name); + return NULL; + } + getnewargs = PyObject_GetAttrString(obj, "__getnewargs__"); if (getnewargs != NULL) { args = PyObject_CallObject(getnewargs, NULL); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 06:28:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 11:28:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Restore_old_distutils_logging_threshold_after_running_te?= =?utf-8?q?st=5Flog=2E?= Message-ID: <20151112112847.29441.18775@psf.io> https://hg.python.org/cpython/rev/42bfb4b48101 changeset: 99081:42bfb4b48101 parent: 99076:a2f574896f49 parent: 99080:2c9b5c5b54ae user: Serhiy Storchaka date: Thu Nov 12 13:28:07 2015 +0200 summary: Restore old distutils logging threshold after running test_log. files: Lib/distutils/tests/test_log.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_log.py b/Lib/distutils/tests/test_log.py --- a/Lib/distutils/tests/test_log.py +++ b/Lib/distutils/tests/test_log.py @@ -14,8 +14,8 @@ # error handler) old_stdout = sys.stdout old_stderr = sys.stderr + old_threshold = log.set_threshold(log.DEBUG) try: - log.set_threshold(log.DEBUG) with NamedTemporaryFile(mode="w+", encoding='ascii') as stdout, \ NamedTemporaryFile(mode="w+", encoding='ascii') as stderr: sys.stdout = stdout @@ -27,6 +27,7 @@ stderr.seek(0) self.assertEqual(stderr.read().rstrip(), "fatal:\\xe9") finally: + log.set_threshold(old_threshold) sys.stdout = old_stdout sys.stderr = old_stderr -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 06:28:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 11:28:47 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Restore_old_distutils_logging_threshold_after_running_test=5Fl?= =?utf-8?b?b2cu?= Message-ID: <20151112112847.115900.69866@psf.io> https://hg.python.org/cpython/rev/2c9b5c5b54ae changeset: 99080:2c9b5c5b54ae branch: 3.5 parent: 99075:4c05e7c195ac parent: 99079:515ebfbb4e67 user: Serhiy Storchaka date: Thu Nov 12 13:15:56 2015 +0200 summary: Restore old distutils logging threshold after running test_log. files: Lib/distutils/tests/test_log.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_log.py b/Lib/distutils/tests/test_log.py --- a/Lib/distutils/tests/test_log.py +++ b/Lib/distutils/tests/test_log.py @@ -14,8 +14,8 @@ # error handler) old_stdout = sys.stdout old_stderr = sys.stderr + old_threshold = log.set_threshold(log.DEBUG) try: - log.set_threshold(log.DEBUG) with NamedTemporaryFile(mode="w+", encoding='ascii') as stdout, \ NamedTemporaryFile(mode="w+", encoding='ascii') as stderr: sys.stdout = stdout @@ -27,6 +27,7 @@ stderr.seek(0) self.assertEqual(stderr.read().rstrip(), "fatal:\\xe9") finally: + log.set_threshold(old_threshold) sys.stdout = old_stdout sys.stderr = old_stderr -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 06:28:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 11:28:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Restore_old_di?= =?utf-8?q?stutils_logging_threshold_after_running_test=5Flog=2E?= Message-ID: <20151112112846.115896.59605@psf.io> https://hg.python.org/cpython/rev/515ebfbb4e67 changeset: 99079:515ebfbb4e67 branch: 3.4 parent: 99074:c8841db9433d user: Serhiy Storchaka date: Thu Nov 12 13:15:41 2015 +0200 summary: Restore old distutils logging threshold after running test_log. files: Lib/distutils/tests/test_log.py | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_log.py b/Lib/distutils/tests/test_log.py --- a/Lib/distutils/tests/test_log.py +++ b/Lib/distutils/tests/test_log.py @@ -14,8 +14,8 @@ # error handler) old_stdout = sys.stdout old_stderr = sys.stderr + old_threshold = log.set_threshold(log.DEBUG) try: - log.set_threshold(log.DEBUG) with NamedTemporaryFile(mode="w+", encoding='ascii') as stdout, \ NamedTemporaryFile(mode="w+", encoding='ascii') as stderr: sys.stdout = stdout @@ -27,6 +27,7 @@ stderr.seek(0) self.assertEqual(stderr.read().rstrip(), "fatal:\\xe9") finally: + log.set_threshold(old_threshold) sys.stdout = old_stdout sys.stderr = old_stderr -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 10:18:51 2015 From: python-checkins at python.org (raymond.hettinger) Date: Thu, 12 Nov 2015 15:18:51 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogRGVxdWUgdXNlcyAi?= =?utf-8?q?len=22_instead_of_varhead_in_Py2=2E7?= Message-ID: <20151112151850.103694.10138@psf.io> https://hg.python.org/cpython/rev/a2a518b6ded4 changeset: 99082:a2a518b6ded4 branch: 2.7 parent: 99078:2b950eba9792 user: Raymond Hettinger date: Thu Nov 12 07:18:45 2015 -0800 summary: Deque uses "len" instead of varhead in Py2.7 files: Modules/_collectionsmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -651,7 +651,7 @@ Py_ssize_t n; PyObject *item; - if (Py_SIZE(deque) == 0) + if (deque->len == 0) return; /* During the process of clearing a deque, decrefs can cause the -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 11:03:59 2015 From: python-checkins at python.org (zach.ware) Date: Thu, 12 Nov 2015 16:03:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Document_the_B?= =?utf-8?q?UILD=5FSET_opcode=2E?= Message-ID: <20151112160357.115896.98934@psf.io> https://hg.python.org/cpython/rev/2fb9f769603a changeset: 99083:2fb9f769603a branch: 2.7 user: Zachary Ware date: Thu Nov 12 10:02:06 2015 -0600 summary: Document the BUILD_SET opcode. Reported by Hrvoje Abraham on docs at . files: Doc/library/dis.rst | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -647,6 +647,13 @@ Works as ``BUILD_TUPLE``, but creates a list. +.. opcode:: BUILD_SET (count) + + Works as ``BUILD_TUPLE``, but creates a set. + + .. versionadded:: 2.7 + + .. opcode:: BUILD_MAP (count) Pushes a new dictionary object onto the stack. The dictionary is pre-sized -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Thu Nov 12 11:54:11 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 12 Nov 2015 16:54:11 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-12 Message-ID: Results for project Python default, build date 2015-11-12 04:02:27 +0000 commit: 3f392050d51934c685d3528d5204dd004f91a648 revision date: 2015-11-11 06:27:13 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.51% 0.31% 8.17% 18.67% :-| pybench 0.10% -0.11% -1.58% 9.17% :-( regex_v8 2.74% 0.02% -4.69% 5.99% :-( nbody 0.07% -0.03% -3.34% 11.62% :-| json_dump_v2 0.36% -0.05% 0.08% 9.66% :-| normal_startup 0.75% -0.14% 0.40% 4.96% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Thu Nov 12 11:56:50 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 12 Nov 2015 16:56:50 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-12 Message-ID: Results for project Python 2.7, build date 2015-11-12 04:51:18 +0000 commit: 37431d9abbcd429f2a52996ba574aaf8fa63e880 revision date: 2015-11-11 15:33:12 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.36% 0.64% 2.80% 9.71% :-) pybench 0.17% 0.10% 6.64% 6.55% :-| regex_v8 0.65% -0.18% -1.80% 6.55% :-) nbody 0.17% -0.00% 8.68% 3.05% :-) json_dump_v2 0.38% -0.24% 2.31% 14.58% :-| normal_startup 1.70% 0.30% -1.29% 2.43% :-| ssbench 0.29% 1.26% 0.60% 1.70% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Thu Nov 12 12:48:28 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 17:48:28 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjA3?= =?utf-8?q?=3A_Restore_old_distutils_logging_threshold_after_running_tests?= =?utf-8?q?_that?= Message-ID: <20151112174827.27699.96040@psf.io> https://hg.python.org/cpython/rev/d7741afd8347 changeset: 99085:d7741afd8347 branch: 2.7 parent: 99083:2fb9f769603a user: Serhiy Storchaka date: Thu Nov 12 19:46:23 2015 +0200 summary: Issue #25607: Restore old distutils logging threshold after running tests that parse command line arguments. files: Lib/distutils/tests/test_core.py | 2 ++ Lib/distutils/tests/test_dist.py | 2 ++ Lib/test/test_shutil.py | 2 +- 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py --- a/Lib/distutils/tests/test_core.py +++ b/Lib/distutils/tests/test_core.py @@ -9,6 +9,7 @@ from test.test_support import captured_stdout, run_unittest import unittest from distutils.tests import support +from distutils import log # setup script that uses __file__ setup_using___file__ = """\ @@ -36,6 +37,7 @@ self.old_stdout = sys.stdout self.cleanup_testfn() self.old_argv = sys.argv, sys.argv[:] + self.addCleanup(log.set_threshold, log._global_log.threshold) def tearDown(self): sys.stdout = self.old_stdout diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py --- a/Lib/distutils/tests/test_dist.py +++ b/Lib/distutils/tests/test_dist.py @@ -13,6 +13,7 @@ import distutils.dist from test.test_support import TESTFN, captured_stdout, run_unittest, unlink from distutils.tests import support +from distutils import log class test_dist(Command): @@ -397,6 +398,7 @@ def test_show_help(self): # smoke test, just makes sure some help is displayed + self.addCleanup(log.set_threshold, log._global_log.threshold) dist = Distribution() sys.argv = [] dist.help = 1 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -443,7 +443,7 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir), captured_stdout(): + with support.change_cwd(root_dir): spawn(tar_cmd) self.assertTrue(os.path.isfile(tarball2)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 12:48:28 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 17:48:28 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325607=3A_Restore_old_distutils_logging_threshold_afte?= =?utf-8?q?r_running_tests_that?= Message-ID: <20151112174827.27695.66359@psf.io> https://hg.python.org/cpython/rev/7411830c7b24 changeset: 99086:7411830c7b24 branch: 3.5 parent: 99080:2c9b5c5b54ae parent: 99084:4461613ffe78 user: Serhiy Storchaka date: Thu Nov 12 19:47:14 2015 +0200 summary: Issue #25607: Restore old distutils logging threshold after running tests that parse command line arguments. files: Lib/distutils/tests/test_core.py | 2 ++ Lib/distutils/tests/test_dist.py | 2 ++ Lib/test/test_shutil.py | 2 +- 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py --- a/Lib/distutils/tests/test_core.py +++ b/Lib/distutils/tests/test_core.py @@ -9,6 +9,7 @@ from test.support import captured_stdout, run_unittest import unittest from distutils.tests import support +from distutils import log # setup script that uses __file__ setup_using___file__ = """\ @@ -36,6 +37,7 @@ self.old_stdout = sys.stdout self.cleanup_testfn() self.old_argv = sys.argv, sys.argv[:] + self.addCleanup(log.set_threshold, log._global_log.threshold) def tearDown(self): sys.stdout = self.old_stdout diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py --- a/Lib/distutils/tests/test_dist.py +++ b/Lib/distutils/tests/test_dist.py @@ -13,6 +13,7 @@ from test.support import TESTFN, captured_stdout, run_unittest from distutils.tests import support +from distutils import log class test_dist(Command): @@ -405,6 +406,7 @@ def test_show_help(self): # smoke test, just makes sure some help is displayed + self.addCleanup(log.set_threshold, log._global_log.threshold) dist = Distribution() sys.argv = [] dist.help = 1 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1037,7 +1037,7 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir), captured_stdout(): + with support.change_cwd(root_dir): spawn(tar_cmd) self.assertTrue(os.path.isfile(tarball2)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 12:48:28 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 17:48:28 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325607=3A_Restore_old_distutils_logging_threshol?= =?utf-8?q?d_after_running_tests_that?= Message-ID: <20151112174827.19475.77314@psf.io> https://hg.python.org/cpython/rev/9f6e43a6b3e0 changeset: 99087:9f6e43a6b3e0 parent: 99081:42bfb4b48101 parent: 99086:7411830c7b24 user: Serhiy Storchaka date: Thu Nov 12 19:47:38 2015 +0200 summary: Issue #25607: Restore old distutils logging threshold after running tests that parse command line arguments. files: Lib/distutils/tests/test_core.py | 2 ++ Lib/distutils/tests/test_dist.py | 2 ++ Lib/test/test_shutil.py | 2 +- 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py --- a/Lib/distutils/tests/test_core.py +++ b/Lib/distutils/tests/test_core.py @@ -9,6 +9,7 @@ from test.support import captured_stdout, run_unittest import unittest from distutils.tests import support +from distutils import log # setup script that uses __file__ setup_using___file__ = """\ @@ -51,6 +52,7 @@ self.old_stdout = sys.stdout self.cleanup_testfn() self.old_argv = sys.argv, sys.argv[:] + self.addCleanup(log.set_threshold, log._global_log.threshold) def tearDown(self): sys.stdout = self.old_stdout diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py --- a/Lib/distutils/tests/test_dist.py +++ b/Lib/distutils/tests/test_dist.py @@ -13,6 +13,7 @@ from test.support import TESTFN, captured_stdout, run_unittest from distutils.tests import support +from distutils import log class test_dist(Command): @@ -405,6 +406,7 @@ def test_show_help(self): # smoke test, just makes sure some help is displayed + self.addCleanup(log.set_threshold, log._global_log.threshold) dist = Distribution() sys.argv = [] dist.help = 1 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1037,7 +1037,7 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir), captured_stdout(): + with support.change_cwd(root_dir): spawn(tar_cmd) self.assertTrue(os.path.isfile(tarball2)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 12:48:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 12 Nov 2015 17:48:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjA3?= =?utf-8?q?=3A_Restore_old_distutils_logging_threshold_after_running_tests?= =?utf-8?q?_that?= Message-ID: <20151112174827.33542.28037@psf.io> https://hg.python.org/cpython/rev/4461613ffe78 changeset: 99084:4461613ffe78 branch: 3.4 parent: 99079:515ebfbb4e67 user: Serhiy Storchaka date: Thu Nov 12 19:46:23 2015 +0200 summary: Issue #25607: Restore old distutils logging threshold after running tests that parse command line arguments. files: Lib/distutils/tests/test_core.py | 2 ++ Lib/distutils/tests/test_dist.py | 2 ++ Lib/test/test_shutil.py | 2 +- 3 files changed, 5 insertions(+), 1 deletions(-) diff --git a/Lib/distutils/tests/test_core.py b/Lib/distutils/tests/test_core.py --- a/Lib/distutils/tests/test_core.py +++ b/Lib/distutils/tests/test_core.py @@ -9,6 +9,7 @@ from test.support import captured_stdout, run_unittest import unittest from distutils.tests import support +from distutils import log # setup script that uses __file__ setup_using___file__ = """\ @@ -36,6 +37,7 @@ self.old_stdout = sys.stdout self.cleanup_testfn() self.old_argv = sys.argv, sys.argv[:] + self.addCleanup(log.set_threshold, log._global_log.threshold) def tearDown(self): sys.stdout = self.old_stdout diff --git a/Lib/distutils/tests/test_dist.py b/Lib/distutils/tests/test_dist.py --- a/Lib/distutils/tests/test_dist.py +++ b/Lib/distutils/tests/test_dist.py @@ -13,6 +13,7 @@ from test.support import TESTFN, captured_stdout, run_unittest from distutils.tests import support +from distutils import log class test_dist(Command): @@ -405,6 +406,7 @@ def test_show_help(self): # smoke test, just makes sure some help is displayed + self.addCleanup(log.set_threshold, log._global_log.threshold) dist = Distribution() sys.argv = [] dist.help = 1 diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1031,7 +1031,7 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir), captured_stdout(): + with support.change_cwd(root_dir): spawn(tar_cmd) self.assertTrue(os.path.isfile(tarball2)) -- Repository URL: https://hg.python.org/cpython From benjamin at python.org Thu Nov 12 15:13:10 2015 From: benjamin at python.org (Benjamin Peterson) Date: Thu, 12 Nov 2015 12:13:10 -0800 Subject: [Python-checkins] cpython (2.7): Backport early-out 91259f061cfb to reduce the cost of bb1a2944bcb6 In-Reply-To: <305A353F-82F7-4A6C-A9E5-235808CBA966@rcn.com> References: <20151007031207.18390.20414@psf.io> <1447311005.2650788.436807905.05A186FE@webmail.messagingengine.com> <305A353F-82F7-4A6C-A9E5-235808CBA966@rcn.com> Message-ID: <1447359190.2841964.438218129.0466D7F0@webmail.messagingengine.com> There's two instances in that file. On Thu, Nov 12, 2015, at 07:20, Raymond Hettinger wrote: > > > On Nov 11, 2015, at 10:50 PM, Benjamin Peterson wrote: > > > >> + if (Py_SIZE(deque) == 0) > >> + return; > >> + > > > > dequeue is not varsized in Python 2.7, so using Py_SIZE() is incorrect. > > Fixed in a2a518b6ded4. > > - if (Py_SIZE(deque) == 0) > + if (deque->len == 0) > > > Raymond From python-checkins at python.org Thu Nov 12 15:25:29 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1MzEz?= =?utf-8?q?=3A_Change_the_handling_of_new_built-in_text_color_themes_to_be?= =?utf-8?q?tter?= Message-ID: <20151112202529.17069.45074@psf.io> https://hg.python.org/cpython/rev/b95c10cb457d changeset: 99088:b95c10cb457d branch: 2.7 parent: 99085:d7741afd8347 user: Terry Jan Reedy date: Thu Nov 12 15:02:50 2015 -0500 summary: Issue #25313: Change the handling of new built-in text color themes to better address the compatibility problem introduced by the addition of IDLE Dark. Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. files: Lib/idlelib/ClassBrowser.py | 2 +- Lib/idlelib/ColorDelegator.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/PyShell.py | 6 ++-- Lib/idlelib/TreeWidget.py | 2 +- Lib/idlelib/config-main.def | 2 + Lib/idlelib/configDialog.py | 29 ++++++++++------------ Lib/idlelib/configHandler.py | 28 ++++++++++++++++++++- 8 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -56,7 +56,7 @@ self.settitle() top.focus_set() # create scrolled canvas - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -62,7 +62,7 @@ self.tag_raise('sel') def LoadTagDefs(self): - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -754,7 +754,7 @@ # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() normal_colors = idleConf.GetHighlight(theme, 'normal') cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') select_colors = idleConf.GetHighlight(theme, 'hilite') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -158,7 +158,7 @@ # possible due to update in restore_file_breaks return if color: - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() cfg = idleConf.GetHighlight(theme, "break") else: cfg = {'foreground': '', 'background': ''} @@ -343,7 +343,7 @@ def LoadTagDefs(self): ColorDelegator.LoadTagDefs(self) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs.update({ "stdin": {'background':None,'foreground':None}, "stdout": idleConf.GetHighlight(theme, "stdout"), @@ -631,7 +631,7 @@ item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) from idlelib.TreeWidget import ScrolledCanvas, TreeNode top = Toplevel(self.tkconsole.root) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -250,7 +250,7 @@ except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -65,6 +65,8 @@ [Theme] default= 1 name= IDLE Classic +name2= +# name2 set in user config-main.cfg for themes added after 2015 Oct 1 [Keys] default= 1 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -261,6 +261,7 @@ self.buttonDeleteCustomTheme=Button( frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + self.new_custom_theme = Label(frameTheme, bd=2) ##widget packing #body @@ -284,6 +285,7 @@ self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) + self.new_custom_theme.pack(side=TOP, fill=X, pady=5) return frame def CreatePageKeys(self): @@ -520,20 +522,15 @@ def VarChanged_builtinTheme(self, *params): value = self.builtinTheme.get() if value == 'IDLE Dark': - tkMessageBox.showwarning( - title="The 'IDLE Dark' Text Color Theme", - message="IDLE Dark is new in October, 2015. Trying to " - "run earlier versions of IDLE with it selected " - "will disable colorizing, or worse.\n\n" - "If you might ever run an earlier release of IDLE, " - "then before exiting this version, " - "either switch to another theme or " - "hit the 'Save as New Custom Theme' button. " - "The latter requires a new name, such as " - "'Custom Dark', but the custom theme will work " - "with any IDLE release, and can be modified.", - parent=self) - self.AddChangedItem('main', 'Theme', 'name', value) + if idleConf.GetOption('main', 'Theme', 'name') != 'IDLE New': + self.AddChangedItem('main', 'Theme', 'name', 'IDLE Classic') + self.AddChangedItem('main', 'Theme', 'name2', value) + self.new_custom_theme.config(text='New theme, see Help', + fg='#500000') + else: + self.AddChangedItem('main', 'Theme', 'name', value) + self.AddChangedItem('main', 'Theme', 'name2', '') + self.new_custom_theme.config(text='', fg='black') self.PaintThemeSample() def VarChanged_customTheme(self, *params): @@ -1367,14 +1364,14 @@ When you click either the Apply or Ok buttons, settings in this dialog that are different from IDLE's default are saved in a .idlerc directory in your home directory. Except as noted, -hese changes apply to all versions of IDLE installed on this +these changes apply to all versions of IDLE installed on this machine. Some do not take affect until IDLE is restarted. [Cancel] only cancels changes made since the last save. ''' help_pages = { 'Highlighting':''' Highlighting: -The IDLE Dark color theme is new in Octover 2015. It can only +The IDLE Dark color theme is new in October 2015. It can only be used with older IDLE releases if it is saved as a custom theme, with a different name. ''' diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -373,8 +373,32 @@ return theme def CurrentTheme(self): - "Return the name of the currently active theme." - return self.GetOption('main', 'Theme', 'name', default='') + """Return the name of the currently active text color theme. + + idlelib.config-main.def includes this section + [Theme] + default= 1 + name= IDLE Classic + name2= + # name2 set in user config-main.cfg for themes added after 2015 Oct 1 + + Item name2 is needed because setting name to a new builtin + causes older IDLEs to display multiple error messages or quit. + See https://bugs.python.org/issue25313. + When default = True, name2 takes precedence over name, + while older IDLEs will just use name. + """ + default = self.GetOption('main', 'Theme', 'default', + type='bool', default=True) + if default: + theme = self.GetOption('main', 'Theme', 'name2', default='') + if default and not theme or not default: + theme = self.GetOption('main', 'Theme', 'name', default='') + source = self.defaultCfg if default else self.userCfg + if source['highlight'].has_section(theme): + return theme + else: + return "IDLE Classic" def CurrentKeys(self): "Return the name of the currently active key set." -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:29 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1MzEz?= =?utf-8?q?=3A_Change_the_handling_of_new_built-in_text_color_themes_to_be?= =?utf-8?q?tter?= Message-ID: <20151112202529.103678.864@psf.io> https://hg.python.org/cpython/rev/6185c5603eed changeset: 99089:6185c5603eed branch: 3.4 parent: 99084:4461613ffe78 user: Terry Jan Reedy date: Thu Nov 12 15:02:57 2015 -0500 summary: Issue #25313: Change the handling of new built-in text color themes to better address the compatibility problem introduced by the addition of IDLE Dark. Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. files: Lib/idlelib/ClassBrowser.py | 2 +- Lib/idlelib/ColorDelegator.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/PyShell.py | 6 ++-- Lib/idlelib/TreeWidget.py | 2 +- Lib/idlelib/config-main.def | 2 + Lib/idlelib/configDialog.py | 29 ++++++++++------------ Lib/idlelib/configHandler.py | 28 ++++++++++++++++++++- 8 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -56,7 +56,7 @@ self.settitle() top.focus_set() # create scrolled canvas - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -60,7 +60,7 @@ self.tag_raise('sel') def LoadTagDefs(self): - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -739,7 +739,7 @@ # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() normal_colors = idleConf.GetHighlight(theme, 'normal') cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') select_colors = idleConf.GetHighlight(theme, 'hilite') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -152,7 +152,7 @@ # possible due to update in restore_file_breaks return if color: - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() cfg = idleConf.GetHighlight(theme, "break") else: cfg = {'foreground': '', 'background': ''} @@ -338,7 +338,7 @@ def LoadTagDefs(self): ColorDelegator.LoadTagDefs(self) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs.update({ "stdin": {'background':None,'foreground':None}, "stdout": idleConf.GetHighlight(theme, "stdout"), @@ -621,7 +621,7 @@ item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) from idlelib.TreeWidget import ScrolledCanvas, TreeNode top = Toplevel(self.tkconsole.root) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -249,7 +249,7 @@ except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -65,6 +65,8 @@ [Theme] default= 1 name= IDLE Classic +name2= +# name2 set in user config-main.cfg for themes added after 2015 Oct 1 [Keys] default= 1 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -263,6 +263,7 @@ self.buttonDeleteCustomTheme=Button( frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + self.new_custom_theme = Label(frameTheme, bd=2) ##widget packing #body @@ -286,6 +287,7 @@ self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) + self.new_custom_theme.pack(side=TOP, fill=X, pady=5) return frame def CreatePageKeys(self): @@ -503,20 +505,15 @@ def VarChanged_builtinTheme(self, *params): value = self.builtinTheme.get() if value == 'IDLE Dark': - tkMessageBox.showwarning( - title="The 'IDLE Dark' Text Color Theme", - message="IDLE Dark is new in October, 2015. Trying to " - "run earlier versions of IDLE with it selected " - "will disable colorizing, or worse.\n\n" - "If you might ever run an earlier release of IDLE, " - "then before exiting this version, " - "either switch to another theme or " - "hit the 'Save as New Custom Theme' button. " - "The latter requires a new name, such as " - "'Custom Dark', but the custom theme will work " - "with any IDLE release, and can be modified.", - parent=self) - self.AddChangedItem('main', 'Theme', 'name', value) + if idleConf.GetOption('main', 'Theme', 'name') != 'IDLE New': + self.AddChangedItem('main', 'Theme', 'name', 'IDLE Classic') + self.AddChangedItem('main', 'Theme', 'name2', value) + self.new_custom_theme.config(text='New theme, see Help', + fg='#500000') + else: + self.AddChangedItem('main', 'Theme', 'name', value) + self.AddChangedItem('main', 'Theme', 'name2', '') + self.new_custom_theme.config(text='', fg='black') self.PaintThemeSample() def VarChanged_customTheme(self, *params): @@ -1350,14 +1347,14 @@ When you click either the Apply or Ok buttons, settings in this dialog that are different from IDLE's default are saved in a .idlerc directory in your home directory. Except as noted, -hese changes apply to all versions of IDLE installed on this +these changes apply to all versions of IDLE installed on this machine. Some do not take affect until IDLE is restarted. [Cancel] only cancels changes made since the last save. ''' help_pages = { 'Highlighting':''' Highlighting: -The IDLE Dark color theme is new in Octover 2015. It can only +The IDLE Dark color theme is new in October 2015. It can only be used with older IDLE releases if it is saved as a custom theme, with a different name. ''' diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -372,8 +372,32 @@ return theme def CurrentTheme(self): - "Return the name of the currently active theme." - return self.GetOption('main', 'Theme', 'name', default='') + """Return the name of the currently active text color theme. + + idlelib.config-main.def includes this section + [Theme] + default= 1 + name= IDLE Classic + name2= + # name2 set in user config-main.cfg for themes added after 2015 Oct 1 + + Item name2 is needed because setting name to a new builtin + causes older IDLEs to display multiple error messages or quit. + See https://bugs.python.org/issue25313. + When default = True, name2 takes precedence over name, + while older IDLEs will just use name. + """ + default = self.GetOption('main', 'Theme', 'default', + type='bool', default=True) + if default: + theme = self.GetOption('main', 'Theme', 'name2', default='') + if default and not theme or not default: + theme = self.GetOption('main', 'Theme', 'name', default='') + source = self.defaultCfg if default else self.userCfg + if source['highlight'].has_section(theme): + return theme + else: + return "IDLE Classic" def CurrentKeys(self): "Return the name of the currently active key set." -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Whitespace?= Message-ID: <20151112202530.21730.76874@psf.io> https://hg.python.org/cpython/rev/c030b05c8daf changeset: 99093:c030b05c8daf branch: 3.4 parent: 99089:6185c5603eed user: Terry Jan Reedy date: Thu Nov 12 15:06:07 2015 -0500 summary: Whitespace files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -396,7 +396,7 @@ source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): return theme - else: + else: return "IDLE Classic" def CurrentKeys(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151112202529.29427.41406@psf.io> https://hg.python.org/cpython/rev/1fa383dc5f83 changeset: 99090:1fa383dc5f83 branch: 3.5 parent: 99086:7411830c7b24 parent: 99089:6185c5603eed user: Terry Jan Reedy date: Thu Nov 12 15:03:17 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/ClassBrowser.py | 2 +- Lib/idlelib/ColorDelegator.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/PyShell.py | 6 ++-- Lib/idlelib/TreeWidget.py | 2 +- Lib/idlelib/config-main.def | 2 + Lib/idlelib/configDialog.py | 29 ++++++++++------------ Lib/idlelib/configHandler.py | 28 ++++++++++++++++++++- 8 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -56,7 +56,7 @@ self.settitle() top.focus_set() # create scrolled canvas - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -60,7 +60,7 @@ self.tag_raise('sel') def LoadTagDefs(self): - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -739,7 +739,7 @@ # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() normal_colors = idleConf.GetHighlight(theme, 'normal') cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') select_colors = idleConf.GetHighlight(theme, 'hilite') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -152,7 +152,7 @@ # possible due to update in restore_file_breaks return if color: - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() cfg = idleConf.GetHighlight(theme, "break") else: cfg = {'foreground': '', 'background': ''} @@ -338,7 +338,7 @@ def LoadTagDefs(self): ColorDelegator.LoadTagDefs(self) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs.update({ "stdin": {'background':None,'foreground':None}, "stdout": idleConf.GetHighlight(theme, "stdout"), @@ -621,7 +621,7 @@ item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) from idlelib.TreeWidget import ScrolledCanvas, TreeNode top = Toplevel(self.tkconsole.root) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -249,7 +249,7 @@ except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -65,6 +65,8 @@ [Theme] default= 1 name= IDLE Classic +name2= +# name2 set in user config-main.cfg for themes added after 2015 Oct 1 [Keys] default= 1 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -263,6 +263,7 @@ self.buttonDeleteCustomTheme=Button( frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + self.new_custom_theme = Label(frameTheme, bd=2) ##widget packing #body @@ -286,6 +287,7 @@ self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) + self.new_custom_theme.pack(side=TOP, fill=X, pady=5) return frame def CreatePageKeys(self): @@ -503,20 +505,15 @@ def VarChanged_builtinTheme(self, *params): value = self.builtinTheme.get() if value == 'IDLE Dark': - tkMessageBox.showwarning( - title="The 'IDLE Dark' Text Color Theme", - message="IDLE Dark is new in October, 2015. Trying to " - "run earlier versions of IDLE with it selected " - "will disable colorizing, or worse.\n\n" - "If you might ever run an earlier release of IDLE, " - "then before exiting this version, " - "either switch to another theme or " - "hit the 'Save as New Custom Theme' button. " - "The latter requires a new name, such as " - "'Custom Dark', but the custom theme will work " - "with any IDLE release, and can be modified.", - parent=self) - self.AddChangedItem('main', 'Theme', 'name', value) + if idleConf.GetOption('main', 'Theme', 'name') != 'IDLE New': + self.AddChangedItem('main', 'Theme', 'name', 'IDLE Classic') + self.AddChangedItem('main', 'Theme', 'name2', value) + self.new_custom_theme.config(text='New theme, see Help', + fg='#500000') + else: + self.AddChangedItem('main', 'Theme', 'name', value) + self.AddChangedItem('main', 'Theme', 'name2', '') + self.new_custom_theme.config(text='', fg='black') self.PaintThemeSample() def VarChanged_customTheme(self, *params): @@ -1350,14 +1347,14 @@ When you click either the Apply or Ok buttons, settings in this dialog that are different from IDLE's default are saved in a .idlerc directory in your home directory. Except as noted, -hese changes apply to all versions of IDLE installed on this +these changes apply to all versions of IDLE installed on this machine. Some do not take affect until IDLE is restarted. [Cancel] only cancels changes made since the last save. ''' help_pages = { 'Highlighting':''' Highlighting: -The IDLE Dark color theme is new in Octover 2015. It can only +The IDLE Dark color theme is new in October 2015. It can only be used with older IDLE releases if it is saved as a custom theme, with a different name. ''' diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -372,8 +372,32 @@ return theme def CurrentTheme(self): - "Return the name of the currently active theme." - return self.GetOption('main', 'Theme', 'name', default='') + """Return the name of the currently active text color theme. + + idlelib.config-main.def includes this section + [Theme] + default= 1 + name= IDLE Classic + name2= + # name2 set in user config-main.cfg for themes added after 2015 Oct 1 + + Item name2 is needed because setting name to a new builtin + causes older IDLEs to display multiple error messages or quit. + See https://bugs.python.org/issue25313. + When default = True, name2 takes precedence over name, + while older IDLEs will just use name. + """ + default = self.GetOption('main', 'Theme', 'default', + type='bool', default=True) + if default: + theme = self.GetOption('main', 'Theme', 'name2', default='') + if default and not theme or not default: + theme = self.GetOption('main', 'Theme', 'name', default='') + source = self.defaultCfg if default else self.userCfg + if source['highlight'].has_section(theme): + return theme + else: + return "IDLE Classic" def CurrentKeys(self): "Return the name of the currently active key set." -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151112202529.29441.73790@psf.io> https://hg.python.org/cpython/rev/d4a149e22d17 changeset: 99091:d4a149e22d17 parent: 99087:9f6e43a6b3e0 parent: 99090:1fa383dc5f83 user: Terry Jan Reedy date: Thu Nov 12 15:03:30 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/ClassBrowser.py | 2 +- Lib/idlelib/ColorDelegator.py | 2 +- Lib/idlelib/EditorWindow.py | 2 +- Lib/idlelib/PyShell.py | 6 ++-- Lib/idlelib/TreeWidget.py | 2 +- Lib/idlelib/config-main.def | 2 + Lib/idlelib/configDialog.py | 29 ++++++++++------------ Lib/idlelib/configHandler.py | 28 ++++++++++++++++++++- 8 files changed, 48 insertions(+), 25 deletions(-) diff --git a/Lib/idlelib/ClassBrowser.py b/Lib/idlelib/ClassBrowser.py --- a/Lib/idlelib/ClassBrowser.py +++ b/Lib/idlelib/ClassBrowser.py @@ -56,7 +56,7 @@ self.settitle() top.focus_set() # create scrolled canvas - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/ColorDelegator.py b/Lib/idlelib/ColorDelegator.py --- a/Lib/idlelib/ColorDelegator.py +++ b/Lib/idlelib/ColorDelegator.py @@ -60,7 +60,7 @@ self.tag_raise('sel') def LoadTagDefs(self): - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs = { "COMMENT": idleConf.GetHighlight(theme, "comment"), "KEYWORD": idleConf.GetHighlight(theme, "keyword"), diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -739,7 +739,7 @@ # Called from self.filename_change_hook and from configDialog.py self._rmcolorizer() self._addcolorizer() - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() normal_colors = idleConf.GetHighlight(theme, 'normal') cursor_color = idleConf.GetHighlight(theme, 'cursor', fgBg='fg') select_colors = idleConf.GetHighlight(theme, 'hilite') diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -152,7 +152,7 @@ # possible due to update in restore_file_breaks return if color: - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() cfg = idleConf.GetHighlight(theme, "break") else: cfg = {'foreground': '', 'background': ''} @@ -338,7 +338,7 @@ def LoadTagDefs(self): ColorDelegator.LoadTagDefs(self) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() self.tagdefs.update({ "stdin": {'background':None,'foreground':None}, "stdout": idleConf.GetHighlight(theme, "stdout"), @@ -621,7 +621,7 @@ item = RemoteObjectBrowser.StubObjectTreeItem(self.rpcclt, oid) from idlelib.TreeWidget import ScrolledCanvas, TreeNode top = Toplevel(self.tkconsole.root) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() background = idleConf.GetHighlight(theme, 'normal')['background'] sc = ScrolledCanvas(top, bg=background, highlightthickness=0) sc.frame.pack(expand=1, fill="both") diff --git a/Lib/idlelib/TreeWidget.py b/Lib/idlelib/TreeWidget.py --- a/Lib/idlelib/TreeWidget.py +++ b/Lib/idlelib/TreeWidget.py @@ -249,7 +249,7 @@ except AttributeError: # padding carefully selected (on Windows) to match Entry widget: self.label = Label(self.canvas, text=text, bd=0, padx=2, pady=2) - theme = idleConf.GetOption('main','Theme','name') + theme = idleConf.CurrentTheme() if self.selected: self.label.configure(idleConf.GetHighlight(theme, 'hilite')) else: diff --git a/Lib/idlelib/config-main.def b/Lib/idlelib/config-main.def --- a/Lib/idlelib/config-main.def +++ b/Lib/idlelib/config-main.def @@ -65,6 +65,8 @@ [Theme] default= 1 name= IDLE Classic +name2= +# name2 set in user config-main.cfg for themes added after 2015 Oct 1 [Keys] default= 1 diff --git a/Lib/idlelib/configDialog.py b/Lib/idlelib/configDialog.py --- a/Lib/idlelib/configDialog.py +++ b/Lib/idlelib/configDialog.py @@ -263,6 +263,7 @@ self.buttonDeleteCustomTheme=Button( frameTheme, text='Delete Custom Theme', command=self.DeleteCustomTheme) + self.new_custom_theme = Label(frameTheme, bd=2) ##widget packing #body @@ -286,6 +287,7 @@ self.optMenuThemeBuiltin.pack(side=TOP, fill=X, padx=5, pady=5) self.optMenuThemeCustom.pack(side=TOP, fill=X, anchor=W, padx=5, pady=5) self.buttonDeleteCustomTheme.pack(side=TOP, fill=X, padx=5, pady=5) + self.new_custom_theme.pack(side=TOP, fill=X, pady=5) return frame def CreatePageKeys(self): @@ -503,20 +505,15 @@ def VarChanged_builtinTheme(self, *params): value = self.builtinTheme.get() if value == 'IDLE Dark': - tkMessageBox.showwarning( - title="The 'IDLE Dark' Text Color Theme", - message="IDLE Dark is new in October, 2015. Trying to " - "run earlier versions of IDLE with it selected " - "will disable colorizing, or worse.\n\n" - "If you might ever run an earlier release of IDLE, " - "then before exiting this version, " - "either switch to another theme or " - "hit the 'Save as New Custom Theme' button. " - "The latter requires a new name, such as " - "'Custom Dark', but the custom theme will work " - "with any IDLE release, and can be modified.", - parent=self) - self.AddChangedItem('main', 'Theme', 'name', value) + if idleConf.GetOption('main', 'Theme', 'name') != 'IDLE New': + self.AddChangedItem('main', 'Theme', 'name', 'IDLE Classic') + self.AddChangedItem('main', 'Theme', 'name2', value) + self.new_custom_theme.config(text='New theme, see Help', + fg='#500000') + else: + self.AddChangedItem('main', 'Theme', 'name', value) + self.AddChangedItem('main', 'Theme', 'name2', '') + self.new_custom_theme.config(text='', fg='black') self.PaintThemeSample() def VarChanged_customTheme(self, *params): @@ -1350,14 +1347,14 @@ When you click either the Apply or Ok buttons, settings in this dialog that are different from IDLE's default are saved in a .idlerc directory in your home directory. Except as noted, -hese changes apply to all versions of IDLE installed on this +these changes apply to all versions of IDLE installed on this machine. Some do not take affect until IDLE is restarted. [Cancel] only cancels changes made since the last save. ''' help_pages = { 'Highlighting':''' Highlighting: -The IDLE Dark color theme is new in Octover 2015. It can only +The IDLE Dark color theme is new in October 2015. It can only be used with older IDLE releases if it is saved as a custom theme, with a different name. ''' diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -372,8 +372,32 @@ return theme def CurrentTheme(self): - "Return the name of the currently active theme." - return self.GetOption('main', 'Theme', 'name', default='') + """Return the name of the currently active text color theme. + + idlelib.config-main.def includes this section + [Theme] + default= 1 + name= IDLE Classic + name2= + # name2 set in user config-main.cfg for themes added after 2015 Oct 1 + + Item name2 is needed because setting name to a new builtin + causes older IDLEs to display multiple error messages or quit. + See https://bugs.python.org/issue25313. + When default = True, name2 takes precedence over name, + while older IDLEs will just use name. + """ + default = self.GetOption('main', 'Theme', 'default', + type='bool', default=True) + if default: + theme = self.GetOption('main', 'Theme', 'name2', default='') + if default and not theme or not default: + theme = self.GetOption('main', 'Theme', 'name', default='') + source = self.defaultCfg if default else self.userCfg + if source['highlight'].has_section(theme): + return theme + else: + return "IDLE Classic" def CurrentKeys(self): "Return the name of the currently active key set." -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Whitespace?= Message-ID: <20151112202530.33548.86477@psf.io> https://hg.python.org/cpython/rev/b735889192f7 changeset: 99092:b735889192f7 branch: 2.7 parent: 99088:b95c10cb457d user: Terry Jan Reedy date: Thu Nov 12 15:06:02 2015 -0500 summary: Whitespace files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -397,7 +397,7 @@ source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): return theme - else: + else: return "IDLE Classic" def CurrentKeys(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151112202530.115888.1491@psf.io> https://hg.python.org/cpython/rev/1ca862377dfd changeset: 99094:1ca862377dfd branch: 3.5 parent: 99090:1fa383dc5f83 parent: 99093:c030b05c8daf user: Terry Jan Reedy date: Thu Nov 12 15:06:20 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -396,7 +396,7 @@ source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): return theme - else: + else: return "IDLE Classic" def CurrentKeys(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSW5kZW50?= Message-ID: <20151112202530.21724.17196@psf.io> https://hg.python.org/cpython/rev/7249cde9709a changeset: 99096:7249cde9709a branch: 2.7 parent: 99092:b735889192f7 user: Terry Jan Reedy date: Thu Nov 12 15:24:22 2015 -0500 summary: Indent files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -396,7 +396,7 @@ theme = self.GetOption('main', 'Theme', 'name', default='') source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): - return theme + return theme else: return "IDLE Classic" -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:30 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151112202530.115884.78037@psf.io> https://hg.python.org/cpython/rev/07222a8bcadf changeset: 99095:07222a8bcadf parent: 99091:d4a149e22d17 parent: 99094:1ca862377dfd user: Terry Jan Reedy date: Thu Nov 12 15:06:34 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -396,7 +396,7 @@ source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): return theme - else: + else: return "IDLE Classic" def CurrentKeys(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:36 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:36 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSW5kZW50?= Message-ID: <20151112202535.19457.75160@psf.io> https://hg.python.org/cpython/rev/fcd453e89c4e changeset: 99097:fcd453e89c4e branch: 3.4 parent: 99093:c030b05c8daf user: Terry Jan Reedy date: Thu Nov 12 15:24:33 2015 -0500 summary: Indent files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -395,7 +395,7 @@ theme = self.GetOption('main', 'Theme', 'name', default='') source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): - return theme + return theme else: return "IDLE Classic" -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:36 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:36 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151112202536.33548.91480@psf.io> https://hg.python.org/cpython/rev/9cf274b2248e changeset: 99098:9cf274b2248e branch: 3.5 parent: 99094:1ca862377dfd parent: 99097:fcd453e89c4e user: Terry Jan Reedy date: Thu Nov 12 15:24:50 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -395,7 +395,7 @@ theme = self.GetOption('main', 'Theme', 'name', default='') source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): - return theme + return theme else: return "IDLE Classic" -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 15:25:36 2015 From: python-checkins at python.org (terry.reedy) Date: Thu, 12 Nov 2015 20:25:36 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151112202536.103686.69790@psf.io> https://hg.python.org/cpython/rev/e25a73751f81 changeset: 99099:e25a73751f81 parent: 99095:07222a8bcadf parent: 99098:9cf274b2248e user: Terry Jan Reedy date: Thu Nov 12 15:25:07 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/configHandler.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/configHandler.py b/Lib/idlelib/configHandler.py --- a/Lib/idlelib/configHandler.py +++ b/Lib/idlelib/configHandler.py @@ -395,7 +395,7 @@ theme = self.GetOption('main', 'Theme', 'name', default='') source = self.defaultCfg if default else self.userCfg if source['highlight'].has_section(theme): - return theme + return theme else: return "IDLE Classic" -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 12 21:20:34 2015 From: python-checkins at python.org (raymond.hettinger) Date: Fri, 13 Nov 2015 02:20:34 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Second_instanc?= =?utf-8?q?e_of_deque_needing_=22len=22_instead_of_=22Py=5FSIZE=22_in_Py2?= =?utf-8?q?=2E7?= Message-ID: <20151113022033.14369.91374@psf.io> https://hg.python.org/cpython/rev/d920b09d22ce changeset: 99100:d920b09d22ce branch: 2.7 parent: 99096:7249cde9709a user: Raymond Hettinger date: Thu Nov 12 18:20:21 2015 -0800 summary: Second instance of deque needing "len" instead of "Py_SIZE" in Py2.7 files: Modules/_collectionsmodule.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c --- a/Modules/_collectionsmodule.c +++ b/Modules/_collectionsmodule.c @@ -1086,7 +1086,7 @@ } } deque->maxlen = maxlen; - if (Py_SIZE(deque) > 0) + if (deque->len > 0) deque_clear(deque); if (iterable != NULL) { PyObject *rv = deque_extend(deque, iterable); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 03:14:43 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 13 Nov 2015 08:14:43 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjA1?= =?utf-8?q?=3A_Document_exceptions_raised_by_fcntl=2Eioctl=28=29_and_fcntl?= =?utf-8?b?LmZsb2NrKCk=?= Message-ID: <20151113081443.88492.91544@psf.io> https://hg.python.org/cpython/rev/f82cd1ed659e changeset: 99102:f82cd1ed659e branch: 3.4 parent: 99097:fcd453e89c4e user: Victor Stinner date: Fri Nov 13 09:13:48 2015 +0100 summary: Issue #25605: Document exceptions raised by fcntl.ioctl() and fcntl.flock() files: Doc/library/fcntl.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -83,6 +83,8 @@ buffer 1024 bytes long which is then passed to :func:`ioctl` and copied back into the supplied buffer. + If the :c:func:`ioctl` fails, an :exc:`IOError` exception is raised. + An example:: >>> import array, fcntl, struct, termios, os @@ -104,6 +106,8 @@ :manpage:`flock(2)` for details. (On some systems, this function is emulated using :c:func:`fcntl`.) + If the :c:func:`flock` fails, an :exc:`IOError` exception is raised. + .. function:: lockf(fd, operation, [length, [start, [whence]]]) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 03:14:43 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 13 Nov 2015 08:14:43 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjA1?= =?utf-8?q?=3A_Document_exceptions_raised_by_fcntl=2Eioctl=28=29_and_fcntl?= =?utf-8?b?LmZsb2NrKCk=?= Message-ID: <20151113081443.4683.14861@psf.io> https://hg.python.org/cpython/rev/d3d974e92e6f changeset: 99101:d3d974e92e6f branch: 2.7 user: Victor Stinner date: Fri Nov 13 09:13:16 2015 +0100 summary: Issue #25605: Document exceptions raised by fcntl.ioctl() and fcntl.flock() files: Doc/library/fcntl.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -82,6 +82,8 @@ which is a change from versions 2.3 and 2.4. Supply the argument explicitly if version portability is a priority. + If the :c:func:`ioctl` fails, an :exc:`IOError` exception is raised. + An example:: >>> import array, fcntl, struct, termios, os @@ -103,6 +105,8 @@ :manpage:`flock(2)` for details. (On some systems, this function is emulated using :c:func:`fcntl`.) + If the :c:func:`flock` fails, an :exc:`IOError` exception is raised. + .. function:: lockf(fd, operation, [length, [start, [whence]]]) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 03:14:49 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 13 Nov 2015 08:14:49 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41IChpc3N1ZSAjMjU2MDUp?= Message-ID: <20151113081448.37458.34703@psf.io> https://hg.python.org/cpython/rev/0eddeb57c3d6 changeset: 99104:0eddeb57c3d6 parent: 99099:e25a73751f81 parent: 99103:cf69fe41f873 user: Victor Stinner date: Fri Nov 13 09:14:26 2015 +0100 summary: Merge 3.5 (issue #25605) files: Doc/library/fcntl.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -83,6 +83,8 @@ buffer 1024 bytes long which is then passed to :func:`ioctl` and copied back into the supplied buffer. + If the :c:func:`ioctl` fails, an :exc:`IOError` exception is raised. + An example:: >>> import array, fcntl, struct, termios, os @@ -104,6 +106,8 @@ :manpage:`flock(2)` for details. (On some systems, this function is emulated using :c:func:`fcntl`.) + If the :c:func:`flock` fails, an :exc:`IOError` exception is raised. + .. function:: lockf(fd, cmd, len=0, start=0, whence=0) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 03:14:43 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 13 Nov 2015 08:14:43 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4_=28issue_=2325605=29?= Message-ID: <20151113081443.37466.97202@psf.io> https://hg.python.org/cpython/rev/cf69fe41f873 changeset: 99103:cf69fe41f873 branch: 3.5 parent: 99098:9cf274b2248e parent: 99102:f82cd1ed659e user: Victor Stinner date: Fri Nov 13 09:14:05 2015 +0100 summary: Merge 3.4 (issue #25605) files: Doc/library/fcntl.rst | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Doc/library/fcntl.rst b/Doc/library/fcntl.rst --- a/Doc/library/fcntl.rst +++ b/Doc/library/fcntl.rst @@ -83,6 +83,8 @@ buffer 1024 bytes long which is then passed to :func:`ioctl` and copied back into the supplied buffer. + If the :c:func:`ioctl` fails, an :exc:`IOError` exception is raised. + An example:: >>> import array, fcntl, struct, termios, os @@ -104,6 +106,8 @@ :manpage:`flock(2)` for details. (On some systems, this function is emulated using :c:func:`fcntl`.) + If the :c:func:`flock` fails, an :exc:`IOError` exception is raised. + .. function:: lockf(fd, cmd, len=0, start=0, whence=0) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Fri Nov 13 03:44:31 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 13 Nov 2015 08:44:31 +0000 Subject: [Python-checkins] Daily reference leaks (e25a73751f81): sum=-1 Message-ID: <20151113084431.4657.30160@psf.io> results for e25a73751f81 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_collections leaked [0, -6, 0] references, sum=-6 test_collections leaked [0, -3, 1] memory blocks, sum=-2 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogLJibKq', '--timeout', '7200'] From python at rcn.com Thu Nov 12 10:20:29 2015 From: python at rcn.com (Raymond Hettinger) Date: Thu, 12 Nov 2015 07:20:29 -0800 Subject: [Python-checkins] cpython (2.7): Backport early-out 91259f061cfb to reduce the cost of bb1a2944bcb6 In-Reply-To: <1447311005.2650788.436807905.05A186FE@webmail.messagingengine.com> References: <20151007031207.18390.20414@psf.io> <1447311005.2650788.436807905.05A186FE@webmail.messagingengine.com> Message-ID: <305A353F-82F7-4A6C-A9E5-235808CBA966@rcn.com> > On Nov 11, 2015, at 10:50 PM, Benjamin Peterson wrote: > >> + if (Py_SIZE(deque) == 0) >> + return; >> + > > dequeue is not varsized in Python 2.7, so using Py_SIZE() is incorrect. Fixed in a2a518b6ded4. - if (Py_SIZE(deque) == 0) + if (deque->len == 0) Raymond From python-checkins at python.org Fri Nov 13 08:19:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 13 Nov 2015 13:19:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDYy?= =?utf-8?q?=3A_The_hash_of_the_key_now_is_calculated_only_once_in_most?= Message-ID: <20151113131910.31755.77047@psf.io> https://hg.python.org/cpython/rev/52ff0c00a404 changeset: 99105:52ff0c00a404 branch: 3.5 parent: 99103:cf69fe41f873 user: Serhiy Storchaka date: Fri Nov 13 14:48:36 2015 +0200 summary: Issue #25462: The hash of the key now is calculated only once in most operations in C implementation of OrderedDict. files: Misc/NEWS | 3 + Objects/odictobject.c | 120 +++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 36 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25462: The hash of the key now is calculated only once in most + operations in C implementation of OrderedDict. + - Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -88,15 +88,16 @@ * _odict_add_head(od, node) * _odict_add_tail(od, node) -* _odict_add_new_node(od, key) +* _odict_add_new_node(od, key, hash) For removing nodes: -* _odict_clear_node(od, node) +* _odict_clear_node(od, node, key, hash) * _odict_clear_nodes(od, clear_each) Others: +* _odict_find_node_hash(od, key, hash) * _odict_find_node(od, key) * _odict_keys_equal(od1, od2) @@ -532,7 +533,7 @@ /* Return the index into the hash table, regardless of a valid node. */ static Py_ssize_t -_odict_get_index_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) +_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash) { PyObject **value_addr = NULL; PyDictKeyEntry *ep; @@ -563,7 +564,7 @@ /* Copy the current nodes into the table. */ _odict_FOREACH(od, node) { - i = _odict_get_index_hash(od, _odictnode_KEY(node), + i = _odict_get_index_raw(od, _odictnode_KEY(node), _odictnode_HASH(node)); if (i < 0) { PyMem_FREE(fast_nodes); @@ -582,15 +583,11 @@ /* Return the index into the hash table, regardless of a valid node. */ static Py_ssize_t -_odict_get_index(PyODictObject *od, PyObject *key) +_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash) { - Py_hash_t hash; PyDictKeysObject *keys; assert(key != NULL); - hash = PyObject_Hash(key); - if (hash == -1) - return -1; keys = ((PyDictObject *)od)->ma_keys; /* Ensure od_fast_nodes and dk_entries are in sync. */ @@ -601,18 +598,35 @@ return -1; } - return _odict_get_index_hash(od, key, hash); + return _odict_get_index_raw(od, key, hash); } /* Returns NULL if there was some error or the key was not found. */ static _ODictNode * -_odict_find_node(PyODictObject *od, PyObject *key) +_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) { Py_ssize_t index; if (_odict_EMPTY(od)) return NULL; - index = _odict_get_index(od, key); + index = _odict_get_index(od, key, hash); + if (index < 0) + return NULL; + return od->od_fast_nodes[index]; +} + +static _ODictNode * +_odict_find_node(PyODictObject *od, PyObject *key) +{ + Py_ssize_t index; + Py_hash_t hash; + + if (_odict_EMPTY(od)) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + index = _odict_get_index(od, key, hash); if (index < 0) return NULL; return od->od_fast_nodes[index]; @@ -646,18 +660,13 @@ /* adds the node to the end of the list */ static int -_odict_add_new_node(PyODictObject *od, PyObject *key) +_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash) { - Py_hash_t hash; Py_ssize_t i; _ODictNode *node; - hash = PyObject_Hash(key); - if (hash == -1) - return -1; - Py_INCREF(key); - i = _odict_get_index(od, key); + i = _odict_get_index(od, key, hash); if (i < 0) { if (!PyErr_Occurred()) PyErr_SetObject(PyExc_KeyError, key); @@ -728,7 +737,8 @@ we modify od_fast_nodes. */ static int -_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key) +_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key, + Py_hash_t hash) { Py_ssize_t i; @@ -738,7 +748,7 @@ return 0; } - i = _odict_get_index(od, key); + i = _odict_get_index(od, key, hash); if (i < 0) return PyErr_Occurred() ? -1 : 0; @@ -1091,7 +1101,8 @@ } static PyObject * -_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj) +_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, + Py_hash_t hash) { _ODictNode *node; PyObject *value = NULL; @@ -1099,13 +1110,13 @@ /* Pop the node first to avoid a possible dict resize (due to eval loop reentrancy) and complications due to hash collision resolution. */ - node = _odict_find_node((PyODictObject *)od, key); + node = _odict_find_node_hash((PyODictObject *)od, key, hash); if (node == NULL) { if (PyErr_Occurred()) return NULL; } else { - int res = _odict_clear_node((PyODictObject *)od, node, key); + int res = _odict_clear_node((PyODictObject *)od, node, key, hash); if (res < 0) { return NULL; } @@ -1114,8 +1125,14 @@ /* Now delete the value from the dict. */ if (PyODict_CheckExact(od)) { if (node != NULL) { - /* We could do PyDict_GetItem() and PyDict_DelItem() directly... */ - value = _PyDict_Pop((PyDictObject *)od, key, failobj); + value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */ + if (value != NULL) { + Py_INCREF(value); + if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) { + Py_DECREF(value); + return NULL; + } + } } } else { @@ -1146,6 +1163,16 @@ return value; } +static PyObject * +_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + + return _odict_popkey_hash(od, key, failobj, hash); +} + /* popitem() */ PyDoc_STRVAR(odict_popitem__doc__, @@ -1178,7 +1205,7 @@ node = last ? _odict_LAST(od) : _odict_FIRST(od); key = _odictnode_KEY(node); Py_INCREF(key); - value = _odict_popkey(od, key, NULL); + value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; item = PyTuple_Pack(2, key, value); @@ -1237,6 +1264,10 @@ /* copy() */ +/* forward */ +static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *, + Py_hash_t); + PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od"); static PyObject * @@ -1261,7 +1292,8 @@ PyErr_SetObject(PyExc_KeyError, key); goto fail; } - if (PyODict_SetItem((PyObject *)od_copy, key, value) != 0) + if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value, + _odictnode_HASH(node)) != 0) goto fail; } } @@ -1720,16 +1752,18 @@ return odict_new(&PyODict_Type, NULL, NULL); }; -int -PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) { - int res = PyDict_SetItem(od, key, value); +static int +_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value, + Py_hash_t hash) +{ + int res = _PyDict_SetItem_KnownHash(od, key, value, hash); if (res == 0) { - res = _odict_add_new_node((PyODictObject *)od, key); + res = _odict_add_new_node((PyODictObject *)od, key, hash); if (res < 0) { /* Revert setting the value on the dict */ PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); - (void) PyDict_DelItem(od, key); + (void) _PyDict_DelItem_KnownHash(od, key, hash); _PyErr_ChainExceptions(exc, val, tb); } } @@ -1737,11 +1771,25 @@ }; int -PyODict_DelItem(PyObject *od, PyObject *key) { - int res = _odict_clear_node((PyODictObject *)od, NULL, key); +PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + return _PyODict_SetItem_KnownHash(od, key, value, hash); +}; + +int +PyODict_DelItem(PyObject *od, PyObject *key) +{ + int res; + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + res = _odict_clear_node((PyODictObject *)od, NULL, key, hash); if (res < 0) return -1; - return PyDict_DelItem(od, key); + return _PyDict_DelItem_KnownHash(od, key, hash); }; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 08:19:11 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 13 Nov 2015 13:19:11 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325462=3A_The_hash_of_the_key_now_is_calculated_?= =?utf-8?q?only_once_in_most?= Message-ID: <20151113131910.34163.65702@psf.io> https://hg.python.org/cpython/rev/828c9b920532 changeset: 99106:828c9b920532 parent: 99104:0eddeb57c3d6 parent: 99105:52ff0c00a404 user: Serhiy Storchaka date: Fri Nov 13 15:18:26 2015 +0200 summary: Issue #25462: The hash of the key now is calculated only once in most operations in C implementation of OrderedDict. files: Misc/NEWS | 3 + Objects/odictobject.c | 120 +++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 36 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25462: The hash of the key now is calculated only once in most + operations in C implementation of OrderedDict. + - Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. diff --git a/Objects/odictobject.c b/Objects/odictobject.c --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -88,15 +88,16 @@ * _odict_add_head(od, node) * _odict_add_tail(od, node) -* _odict_add_new_node(od, key) +* _odict_add_new_node(od, key, hash) For removing nodes: -* _odict_clear_node(od, node) +* _odict_clear_node(od, node, key, hash) * _odict_clear_nodes(od, clear_each) Others: +* _odict_find_node_hash(od, key, hash) * _odict_find_node(od, key) * _odict_keys_equal(od1, od2) @@ -532,7 +533,7 @@ /* Return the index into the hash table, regardless of a valid node. */ static Py_ssize_t -_odict_get_index_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) +_odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash) { PyObject **value_addr = NULL; PyDictKeyEntry *ep; @@ -563,7 +564,7 @@ /* Copy the current nodes into the table. */ _odict_FOREACH(od, node) { - i = _odict_get_index_hash(od, _odictnode_KEY(node), + i = _odict_get_index_raw(od, _odictnode_KEY(node), _odictnode_HASH(node)); if (i < 0) { PyMem_FREE(fast_nodes); @@ -582,15 +583,11 @@ /* Return the index into the hash table, regardless of a valid node. */ static Py_ssize_t -_odict_get_index(PyODictObject *od, PyObject *key) +_odict_get_index(PyODictObject *od, PyObject *key, Py_hash_t hash) { - Py_hash_t hash; PyDictKeysObject *keys; assert(key != NULL); - hash = PyObject_Hash(key); - if (hash == -1) - return -1; keys = ((PyDictObject *)od)->ma_keys; /* Ensure od_fast_nodes and dk_entries are in sync. */ @@ -601,18 +598,35 @@ return -1; } - return _odict_get_index_hash(od, key, hash); + return _odict_get_index_raw(od, key, hash); } /* Returns NULL if there was some error or the key was not found. */ static _ODictNode * -_odict_find_node(PyODictObject *od, PyObject *key) +_odict_find_node_hash(PyODictObject *od, PyObject *key, Py_hash_t hash) { Py_ssize_t index; if (_odict_EMPTY(od)) return NULL; - index = _odict_get_index(od, key); + index = _odict_get_index(od, key, hash); + if (index < 0) + return NULL; + return od->od_fast_nodes[index]; +} + +static _ODictNode * +_odict_find_node(PyODictObject *od, PyObject *key) +{ + Py_ssize_t index; + Py_hash_t hash; + + if (_odict_EMPTY(od)) + return NULL; + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + index = _odict_get_index(od, key, hash); if (index < 0) return NULL; return od->od_fast_nodes[index]; @@ -646,18 +660,13 @@ /* adds the node to the end of the list */ static int -_odict_add_new_node(PyODictObject *od, PyObject *key) +_odict_add_new_node(PyODictObject *od, PyObject *key, Py_hash_t hash) { - Py_hash_t hash; Py_ssize_t i; _ODictNode *node; - hash = PyObject_Hash(key); - if (hash == -1) - return -1; - Py_INCREF(key); - i = _odict_get_index(od, key); + i = _odict_get_index(od, key, hash); if (i < 0) { if (!PyErr_Occurred()) PyErr_SetObject(PyExc_KeyError, key); @@ -728,7 +737,8 @@ we modify od_fast_nodes. */ static int -_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key) +_odict_clear_node(PyODictObject *od, _ODictNode *node, PyObject *key, + Py_hash_t hash) { Py_ssize_t i; @@ -738,7 +748,7 @@ return 0; } - i = _odict_get_index(od, key); + i = _odict_get_index(od, key, hash); if (i < 0) return PyErr_Occurred() ? -1 : 0; @@ -1091,7 +1101,8 @@ } static PyObject * -_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj) +_odict_popkey_hash(PyObject *od, PyObject *key, PyObject *failobj, + Py_hash_t hash) { _ODictNode *node; PyObject *value = NULL; @@ -1099,13 +1110,13 @@ /* Pop the node first to avoid a possible dict resize (due to eval loop reentrancy) and complications due to hash collision resolution. */ - node = _odict_find_node((PyODictObject *)od, key); + node = _odict_find_node_hash((PyODictObject *)od, key, hash); if (node == NULL) { if (PyErr_Occurred()) return NULL; } else { - int res = _odict_clear_node((PyODictObject *)od, node, key); + int res = _odict_clear_node((PyODictObject *)od, node, key, hash); if (res < 0) { return NULL; } @@ -1114,8 +1125,14 @@ /* Now delete the value from the dict. */ if (PyODict_CheckExact(od)) { if (node != NULL) { - /* We could do PyDict_GetItem() and PyDict_DelItem() directly... */ - value = _PyDict_Pop((PyDictObject *)od, key, failobj); + value = _PyDict_GetItem_KnownHash(od, key, hash); /* borrowed */ + if (value != NULL) { + Py_INCREF(value); + if (_PyDict_DelItem_KnownHash(od, key, hash) < 0) { + Py_DECREF(value); + return NULL; + } + } } } else { @@ -1146,6 +1163,16 @@ return value; } +static PyObject * +_odict_popkey(PyObject *od, PyObject *key, PyObject *failobj) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return NULL; + + return _odict_popkey_hash(od, key, failobj, hash); +} + /* popitem() */ PyDoc_STRVAR(odict_popitem__doc__, @@ -1178,7 +1205,7 @@ node = last ? _odict_LAST(od) : _odict_FIRST(od); key = _odictnode_KEY(node); Py_INCREF(key); - value = _odict_popkey(od, key, NULL); + value = _odict_popkey_hash(od, key, NULL, _odictnode_HASH(node)); if (value == NULL) return NULL; item = PyTuple_Pack(2, key, value); @@ -1237,6 +1264,10 @@ /* copy() */ +/* forward */ +static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *, + Py_hash_t); + PyDoc_STRVAR(odict_copy__doc__, "od.copy() -> a shallow copy of od"); static PyObject * @@ -1261,7 +1292,8 @@ PyErr_SetObject(PyExc_KeyError, key); goto fail; } - if (PyODict_SetItem((PyObject *)od_copy, key, value) != 0) + if (_PyODict_SetItem_KnownHash((PyObject *)od_copy, key, value, + _odictnode_HASH(node)) != 0) goto fail; } } @@ -1720,16 +1752,18 @@ return odict_new(&PyODict_Type, NULL, NULL); }; -int -PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) { - int res = PyDict_SetItem(od, key, value); +static int +_PyODict_SetItem_KnownHash(PyObject *od, PyObject *key, PyObject *value, + Py_hash_t hash) +{ + int res = _PyDict_SetItem_KnownHash(od, key, value, hash); if (res == 0) { - res = _odict_add_new_node((PyODictObject *)od, key); + res = _odict_add_new_node((PyODictObject *)od, key, hash); if (res < 0) { /* Revert setting the value on the dict */ PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); - (void) PyDict_DelItem(od, key); + (void) _PyDict_DelItem_KnownHash(od, key, hash); _PyErr_ChainExceptions(exc, val, tb); } } @@ -1737,11 +1771,25 @@ }; int -PyODict_DelItem(PyObject *od, PyObject *key) { - int res = _odict_clear_node((PyODictObject *)od, NULL, key); +PyODict_SetItem(PyObject *od, PyObject *key, PyObject *value) +{ + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + return _PyODict_SetItem_KnownHash(od, key, value, hash); +}; + +int +PyODict_DelItem(PyObject *od, PyObject *key) +{ + int res; + Py_hash_t hash = PyObject_Hash(key); + if (hash == -1) + return -1; + res = _odict_clear_node((PyODictObject *)od, NULL, key, hash); if (res < 0) return -1; - return PyDict_DelItem(od, key); + return _PyDict_DelItem_KnownHash(od, key, hash); }; -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Fri Nov 13 11:22:44 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 13 Nov 2015 16:22:44 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-13 Message-ID: Results for project Python default, build date 2015-11-13 04:02:16 +0000 commit: e25a73751f8157a776dcf9b1ba1e12daa4402b9e revision date: 2015-11-12 20:25:07 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% 0.06% 8.23% 17.29% :-| pybench 0.12% -0.21% -1.80% 8.91% :-( regex_v8 2.69% 0.02% -4.67% 6.32% :-| nbody 0.07% 1.73% -1.55% 11.62% :-| json_dump_v2 0.28% 0.56% 0.64% 9.78% :-| normal_startup 0.97% 0.16% 0.43% 5.01% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Fri Nov 13 11:23:54 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 13 Nov 2015 16:23:54 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-13 Message-ID: Results for project Python 2.7, build date 2015-11-13 13:07:14 +0000 commit: d3d974e92e6f7de017df272664a19972e566cdeb revision date: 2015-11-13 08:13:16 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.26% -0.36% 2.81% 8.46% :-) pybench 0.18% 0.04% 6.14% 7.50% :-( regex_v8 0.59% -0.46% -2.69% 8.22% :-) nbody 0.24% -0.01% 6.42% 7.44% :-| json_dump_v2 0.27% 0.20% 1.60% 14.66% :-| normal_startup 1.87% 0.75% -0.75% 2.56% :-| ssbench 0.42% -0.71% 0.23% 2.39% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Fri Nov 13 12:29:27 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 13 Nov 2015 17:29:27 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151113172927.34151.18151@psf.io> https://hg.python.org/cpython/rev/0eb7958cea3a changeset: 99109:0eb7958cea3a parent: 99106:828c9b920532 parent: 99108:d3074dfe3d39 user: Yury Selivanov date: Fri Nov 13 12:29:14 2015 -0500 summary: Merge 3.5 files: Lib/test/test_asyncio/test_tasks.py | 32 +++++++++------- 1 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2101,20 +2101,16 @@ class RunCoroutineThreadsafeTests(test_utils.TestCase): - """Test case for futures.submit_to_loop.""" + """Test case for asyncio.run_coroutine_threadsafe.""" def setUp(self): - self.loop = self.new_test_loop(self.time_gen) - - def time_gen(self): - """Handle the timer.""" - yield 0 # second - yield 1 # second + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) # Will cleanup properly @asyncio.coroutine def add(self, a, b, fail=False, cancel=False): - """Wait 1 second and return a + b.""" - yield from asyncio.sleep(1, loop=self.loop) + """Wait 0.05 second and return a + b.""" + yield from asyncio.sleep(0.05, loop=self.loop) if fail: raise RuntimeError("Fail!") if cancel: @@ -2122,10 +2118,20 @@ yield return a + b - def target(self, fail=False, cancel=False, timeout=None): + def target(self, fail=False, cancel=False, timeout=None, + advance_coro=False): """Run add coroutine in the event loop.""" coro = self.add(1, 2, fail=fail, cancel=cancel) future = asyncio.run_coroutine_threadsafe(coro, self.loop) + if advance_coro: + # this is for test_run_coroutine_threadsafe_task_factory_exception; + # otherwise it spills errors and breaks **other** unittests, since + # 'target' is interacting with threads. + + # With this call, `coro` will be advanced, so that + # CoroWrapper.__del__ won't do anything when asyncio tests run + # in debug mode. + self.loop.call_soon_threadsafe(coro.send, None) try: return future.result(timeout) finally: @@ -2152,7 +2158,6 @@ future = self.loop.run_in_executor(None, callback) with self.assertRaises(asyncio.TimeoutError): self.loop.run_until_complete(future) - # Clear the time generator and tasks test_utils.run_briefly(self.loop) # Check that there's no pending task (add has been cancelled) for task in asyncio.Task.all_tasks(self.loop): @@ -2169,10 +2174,9 @@ def test_run_coroutine_threadsafe_task_factory_exception(self): """Test coroutine submission from a tread to an event loop when the task factory raise an exception.""" - # Clear the time generator - asyncio.ensure_future(self.add(1, 2), loop=self.loop) # Schedule the target - future = self.loop.run_in_executor(None, self.target) + future = self.loop.run_in_executor( + None, lambda: self.target(advance_coro=True)) # Set corrupted task factory self.loop.set_task_factory(lambda loop, coro: wrong_name) # Set exception handler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 12:29:27 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 13 Nov 2015 17:29:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogRml4?= =?utf-8?q?_sporadic_failing_unittests_in_debug_mode?= Message-ID: <20151113172927.120336.71575@psf.io> https://hg.python.org/cpython/rev/4569663e6e17 changeset: 99107:4569663e6e17 branch: 3.4 parent: 99102:f82cd1ed659e user: Yury Selivanov date: Fri Nov 13 12:28:48 2015 -0500 summary: asyncio: Fix sporadic failing unittests in debug mode files: Lib/test/test_asyncio/test_tasks.py | 32 +++++++++------- 1 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2101,20 +2101,16 @@ class RunCoroutineThreadsafeTests(test_utils.TestCase): - """Test case for futures.submit_to_loop.""" + """Test case for asyncio.run_coroutine_threadsafe.""" def setUp(self): - self.loop = self.new_test_loop(self.time_gen) - - def time_gen(self): - """Handle the timer.""" - yield 0 # second - yield 1 # second + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) # Will cleanup properly @asyncio.coroutine def add(self, a, b, fail=False, cancel=False): - """Wait 1 second and return a + b.""" - yield from asyncio.sleep(1, loop=self.loop) + """Wait 0.05 second and return a + b.""" + yield from asyncio.sleep(0.05, loop=self.loop) if fail: raise RuntimeError("Fail!") if cancel: @@ -2122,10 +2118,20 @@ yield return a + b - def target(self, fail=False, cancel=False, timeout=None): + def target(self, fail=False, cancel=False, timeout=None, + advance_coro=False): """Run add coroutine in the event loop.""" coro = self.add(1, 2, fail=fail, cancel=cancel) future = asyncio.run_coroutine_threadsafe(coro, self.loop) + if advance_coro: + # this is for test_run_coroutine_threadsafe_task_factory_exception; + # otherwise it spills errors and breaks **other** unittests, since + # 'target' is interacting with threads. + + # With this call, `coro` will be advanced, so that + # CoroWrapper.__del__ won't do anything when asyncio tests run + # in debug mode. + self.loop.call_soon_threadsafe(coro.send, None) try: return future.result(timeout) finally: @@ -2152,7 +2158,6 @@ future = self.loop.run_in_executor(None, callback) with self.assertRaises(asyncio.TimeoutError): self.loop.run_until_complete(future) - # Clear the time generator and tasks test_utils.run_briefly(self.loop) # Check that there's no pending task (add has been cancelled) for task in asyncio.Task.all_tasks(self.loop): @@ -2169,10 +2174,9 @@ def test_run_coroutine_threadsafe_task_factory_exception(self): """Test coroutine submission from a tread to an event loop when the task factory raise an exception.""" - # Clear the time generator - asyncio.ensure_future(self.add(1, 2), loop=self.loop) # Schedule the target - future = self.loop.run_in_executor(None, self.target) + future = self.loop.run_in_executor( + None, lambda: self.target(advance_coro=True)) # Set corrupted task factory self.loop.set_task_factory(lambda loop, coro: wrong_name) # Set exception handler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 12:29:27 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 13 Nov 2015 17:29:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151113172927.14379.87313@psf.io> https://hg.python.org/cpython/rev/d3074dfe3d39 changeset: 99108:d3074dfe3d39 branch: 3.5 parent: 99105:52ff0c00a404 parent: 99107:4569663e6e17 user: Yury Selivanov date: Fri Nov 13 12:29:03 2015 -0500 summary: Merge 3.4 files: Lib/test/test_asyncio/test_tasks.py | 32 +++++++++------- 1 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2101,20 +2101,16 @@ class RunCoroutineThreadsafeTests(test_utils.TestCase): - """Test case for futures.submit_to_loop.""" + """Test case for asyncio.run_coroutine_threadsafe.""" def setUp(self): - self.loop = self.new_test_loop(self.time_gen) - - def time_gen(self): - """Handle the timer.""" - yield 0 # second - yield 1 # second + self.loop = asyncio.new_event_loop() + self.set_event_loop(self.loop) # Will cleanup properly @asyncio.coroutine def add(self, a, b, fail=False, cancel=False): - """Wait 1 second and return a + b.""" - yield from asyncio.sleep(1, loop=self.loop) + """Wait 0.05 second and return a + b.""" + yield from asyncio.sleep(0.05, loop=self.loop) if fail: raise RuntimeError("Fail!") if cancel: @@ -2122,10 +2118,20 @@ yield return a + b - def target(self, fail=False, cancel=False, timeout=None): + def target(self, fail=False, cancel=False, timeout=None, + advance_coro=False): """Run add coroutine in the event loop.""" coro = self.add(1, 2, fail=fail, cancel=cancel) future = asyncio.run_coroutine_threadsafe(coro, self.loop) + if advance_coro: + # this is for test_run_coroutine_threadsafe_task_factory_exception; + # otherwise it spills errors and breaks **other** unittests, since + # 'target' is interacting with threads. + + # With this call, `coro` will be advanced, so that + # CoroWrapper.__del__ won't do anything when asyncio tests run + # in debug mode. + self.loop.call_soon_threadsafe(coro.send, None) try: return future.result(timeout) finally: @@ -2152,7 +2158,6 @@ future = self.loop.run_in_executor(None, callback) with self.assertRaises(asyncio.TimeoutError): self.loop.run_until_complete(future) - # Clear the time generator and tasks test_utils.run_briefly(self.loop) # Check that there's no pending task (add has been cancelled) for task in asyncio.Task.all_tasks(self.loop): @@ -2169,10 +2174,9 @@ def test_run_coroutine_threadsafe_task_factory_exception(self): """Test coroutine submission from a tread to an event loop when the task factory raise an exception.""" - # Clear the time generator - asyncio.ensure_future(self.add(1, 2), loop=self.loop) # Schedule the target - future = self.loop.run_in_executor(None, self.target) + future = self.loop.run_in_executor( + None, lambda: self.target(advance_coro=True)) # Set corrupted task factory self.loop.set_task_factory(lambda loop, coro: wrong_name) # Set exception handler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 17:20:11 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 22:20:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDk4?= =?utf-8?q?=3A_Update_error_message_for_3=2E5?= Message-ID: <20151113222011.31743.90412@psf.io> https://hg.python.org/cpython/rev/deb0fb601191 changeset: 99112:deb0fb601191 branch: 3.5 user: Martin Panter date: Fri Nov 13 22:12:58 2015 +0000 summary: Issue #25498: Update error message for 3.5 files: Lib/ctypes/test/test_frombuffer.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -44,7 +44,7 @@ (c_char * 16).from_buffer(memoryview(b"a" * 16)) with self.assertRaisesRegex(TypeError, "not C contiguous"): (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1]) - msg = "does not have the buffer interface" + msg = "bytes-like object is required" with self.assertRaisesRegex(TypeError, msg): (c_char * 16).from_buffer("a" * 16) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 17:20:11 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 22:20:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NDk4?= =?utf-8?q?=3A_Fix_GC_crash_due_to_ctypes_objects_wrapping_a_memoryview?= Message-ID: <20151113222011.18192.53869@psf.io> https://hg.python.org/cpython/rev/9b23f7a94ba9 changeset: 99110:9b23f7a94ba9 branch: 3.4 parent: 99107:4569663e6e17 user: Martin Panter date: Fri Nov 13 21:43:39 2015 +0000 summary: Issue #25498: Fix GC crash due to ctypes objects wrapping a memoryview This was a regression caused by revision 1da9630e9b7f. Based on patch by Eryksun. files: Lib/ctypes/test/test_frombuffer.py | 31 +++++++++- Misc/ACKS | 1 + Misc/NEWS | 4 + Modules/_ctypes/_ctypes.c | 56 ++++++++++++----- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -38,11 +38,32 @@ del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): (c_char * 16).from_buffer(b"a" * 16) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): + (c_char * 16).from_buffer(memoryview(b"a" * 16)) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1]) + msg = "does not have the buffer interface" + with self.assertRaisesRegex(TypeError, msg): (c_char * 16).from_buffer("a" * 16) + def test_fortran_contiguous(self): + try: + import _testbuffer + except ImportError as err: + self.skipTest(str(err)) + flags = _testbuffer.ND_WRITABLE | _testbuffer.ND_FORTRAN + array = _testbuffer.ndarray( + [97] * 16, format="B", shape=[4, 4], flags=flags) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + array = memoryview(array) + self.assertTrue(array.f_contiguous) + self.assertFalse(array.c_contiguous) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) @@ -55,6 +76,12 @@ with self.assertRaises(ValueError): (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) + def test_from_buffer_memoryview(self): + a = [c_char.from_buffer(memoryview(bytearray(b'a')))] + a.append(a) + del a + gc.collect() # Should not crash + def test_from_buffer_copy(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer_copy(a) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -391,6 +391,7 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst +Eryksun Ben Escoto Andy Eskilsson Andr? Espaze diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -103,6 +103,10 @@ Library ------- +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.4.3. Based + on patch by Eryksun. + - Issue #18010: Fix the pydoc web server's module search function to handle exceptions from importing packages. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -463,45 +463,65 @@ static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) { - Py_buffer buffer; + PyObject *obj; + PyObject *mv; + PyObject *result; + Py_buffer *buffer; Py_ssize_t offset = 0; - PyObject *result, *mv; + StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset)) + if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) return NULL; + mv = PyMemoryView_FromObject(obj); + if (mv == NULL) + return NULL; + + buffer = PyMemoryView_GET_BUFFER(mv); + + if (buffer->readonly) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not writable"); + Py_DECREF(mv); + return NULL; + } + + if (!PyBuffer_IsContiguous(buffer, 'C')) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not C contiguous"); + Py_DECREF(mv); + return NULL; + } + if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative"); - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - if (dict->size > buffer.len - offset) { + + if (dict->size > buffer->len - offset) { PyErr_Format(PyExc_ValueError, - "Buffer size too small (%zd instead of at least %zd bytes)", - buffer.len, dict->size + offset); - PyBuffer_Release(&buffer); + "Buffer size too small " + "(%zd instead of at least %zd bytes)", + buffer->len, dict->size + offset); + Py_DECREF(mv); return NULL; } - result = PyCData_AtAddress(type, (char *)buffer.buf + offset); + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); if (result == NULL) { - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - mv = PyMemoryView_FromBuffer(&buffer); - if (mv == NULL) { - PyBuffer_Release(&buffer); + if (-1 == KeepRef((CDataObject *)result, -1, mv)) { + Py_DECREF(result); return NULL; } - /* Hack the memoryview so that it will release the buffer. */ - ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj; - ((PyMemoryViewObject *)mv)->view.obj = buffer.obj; - if (-1 == KeepRef((CDataObject *)result, -1, mv)) - result = NULL; + return result; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 17:20:12 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 22:20:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325498=3A_Merge_ctypes_crash_fix_from_3=2E5?= Message-ID: <20151113222011.120360.6321@psf.io> https://hg.python.org/cpython/rev/f3dba13c22e5 changeset: 99113:f3dba13c22e5 parent: 99109:0eb7958cea3a parent: 99112:deb0fb601191 user: Martin Panter date: Fri Nov 13 22:14:53 2015 +0000 summary: Issue #25498: Merge ctypes crash fix from 3.5 files: Lib/ctypes/test/test_frombuffer.py | 31 +++++++++- Misc/ACKS | 1 + Misc/NEWS | 4 + Modules/_ctypes/_ctypes.c | 56 ++++++++++++----- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -38,11 +38,32 @@ del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): (c_char * 16).from_buffer(b"a" * 16) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): + (c_char * 16).from_buffer(memoryview(b"a" * 16)) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1]) + msg = "bytes-like object is required" + with self.assertRaisesRegex(TypeError, msg): (c_char * 16).from_buffer("a" * 16) + def test_fortran_contiguous(self): + try: + import _testbuffer + except ImportError as err: + self.skipTest(str(err)) + flags = _testbuffer.ND_WRITABLE | _testbuffer.ND_FORTRAN + array = _testbuffer.ndarray( + [97] * 16, format="B", shape=[4, 4], flags=flags) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + array = memoryview(array) + self.assertTrue(array.f_contiguous) + self.assertFalse(array.c_contiguous) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) @@ -55,6 +76,12 @@ with self.assertRaises(ValueError): (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) + def test_from_buffer_memoryview(self): + a = [c_char.from_buffer(memoryview(bytearray(b'a')))] + a.append(a) + del a + gc.collect() # Should not crash + def test_from_buffer_copy(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer_copy(a) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -399,6 +399,7 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst +Eryksun Ben Escoto Andy Eskilsson Andr? Espaze diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -398,6 +398,10 @@ Library ------- +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.5a1. Based + on patch by Eryksun. + - Issue #25232: Fix CGIRequestHandler to split the query from the URL at the first question mark (?) rather than the last. Patch from Xiang Zhang. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -463,45 +463,65 @@ static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) { - Py_buffer buffer; + PyObject *obj; + PyObject *mv; + PyObject *result; + Py_buffer *buffer; Py_ssize_t offset = 0; - PyObject *result, *mv; + StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset)) + if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) return NULL; + mv = PyMemoryView_FromObject(obj); + if (mv == NULL) + return NULL; + + buffer = PyMemoryView_GET_BUFFER(mv); + + if (buffer->readonly) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not writable"); + Py_DECREF(mv); + return NULL; + } + + if (!PyBuffer_IsContiguous(buffer, 'C')) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not C contiguous"); + Py_DECREF(mv); + return NULL; + } + if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative"); - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - if (dict->size > buffer.len - offset) { + + if (dict->size > buffer->len - offset) { PyErr_Format(PyExc_ValueError, - "Buffer size too small (%zd instead of at least %zd bytes)", - buffer.len, dict->size + offset); - PyBuffer_Release(&buffer); + "Buffer size too small " + "(%zd instead of at least %zd bytes)", + buffer->len, dict->size + offset); + Py_DECREF(mv); return NULL; } - result = PyCData_AtAddress(type, (char *)buffer.buf + offset); + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); if (result == NULL) { - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - mv = PyMemoryView_FromBuffer(&buffer); - if (mv == NULL) { - PyBuffer_Release(&buffer); + if (-1 == KeepRef((CDataObject *)result, -1, mv)) { + Py_DECREF(result); return NULL; } - /* Hack the memoryview so that it will release the buffer. */ - ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj; - ((PyMemoryViewObject *)mv)->view.obj = buffer.obj; - if (-1 == KeepRef((CDataObject *)result, -1, mv)) - result = NULL; + return result; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 17:20:13 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 22:20:13 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325498=3A_Add_NEWS?= =?utf-8?q?_entry_for_3=2E6?= Message-ID: <20151113222012.37460.29269@psf.io> https://hg.python.org/cpython/rev/08c56962c24c changeset: 99114:08c56962c24c user: Martin Panter date: Fri Nov 13 22:17:08 2015 +0000 summary: Issue #25498: Add NEWS entry for 3.6 files: Misc/NEWS | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -85,6 +85,10 @@ Library ------- +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.5a1. Based + on patch by Eryksun. + - Issue #25584: Added "escape" to the __all__ list in the glob module. - Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 17:20:13 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 22:20:13 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325498=3A_Merge_ctypes_crash_fix_from_3=2E4_into_3=2E5?= Message-ID: <20151113222011.120360.25488@psf.io> https://hg.python.org/cpython/rev/7445de785670 changeset: 99111:7445de785670 branch: 3.5 parent: 99108:d3074dfe3d39 parent: 99110:9b23f7a94ba9 user: Martin Panter date: Fri Nov 13 22:12:12 2015 +0000 summary: Issue #25498: Merge ctypes crash fix from 3.4 into 3.5 files: Lib/ctypes/test/test_frombuffer.py | 31 +++++++++- Misc/ACKS | 1 + Misc/NEWS | 4 + Modules/_ctypes/_ctypes.c | 56 ++++++++++++----- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/Lib/ctypes/test/test_frombuffer.py b/Lib/ctypes/test/test_frombuffer.py --- a/Lib/ctypes/test/test_frombuffer.py +++ b/Lib/ctypes/test/test_frombuffer.py @@ -38,11 +38,32 @@ del a; gc.collect(); gc.collect(); gc.collect() self.assertEqual(x[:], expected) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): (c_char * 16).from_buffer(b"a" * 16) - with self.assertRaises(TypeError): + with self.assertRaisesRegex(TypeError, "not writable"): + (c_char * 16).from_buffer(memoryview(b"a" * 16)) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(memoryview(bytearray(b"a" * 16))[::-1]) + msg = "does not have the buffer interface" + with self.assertRaisesRegex(TypeError, msg): (c_char * 16).from_buffer("a" * 16) + def test_fortran_contiguous(self): + try: + import _testbuffer + except ImportError as err: + self.skipTest(str(err)) + flags = _testbuffer.ND_WRITABLE | _testbuffer.ND_FORTRAN + array = _testbuffer.ndarray( + [97] * 16, format="B", shape=[4, 4], flags=flags) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + array = memoryview(array) + self.assertTrue(array.f_contiguous) + self.assertFalse(array.c_contiguous) + with self.assertRaisesRegex(TypeError, "not C contiguous"): + (c_char * 16).from_buffer(array) + def test_from_buffer_with_offset(self): a = array.array("i", range(16)) x = (c_int * 15).from_buffer(a, sizeof(c_int)) @@ -55,6 +76,12 @@ with self.assertRaises(ValueError): (c_int * 1).from_buffer(a, 16 * sizeof(c_int)) + def test_from_buffer_memoryview(self): + a = [c_char.from_buffer(memoryview(bytearray(b'a')))] + a.append(a) + del a + gc.collect() # Should not crash + def test_from_buffer_copy(self): a = array.array("i", range(16)) x = (c_int * 16).from_buffer_copy(a) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -398,6 +398,7 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst +Eryksun Ben Escoto Andy Eskilsson Andr? Espaze diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -67,6 +67,10 @@ Library ------- +- Issue #25498: Fix a crash when garbage-collecting ctypes objects created + by wrapping a memoryview. This was a regression made in 3.5a1. Based + on patch by Eryksun. + - Issue #25584: Added "escape" to the __all__ list in the glob module. - Issue #25584: Fixed recursive glob() with patterns starting with '\*\*'. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -463,45 +463,65 @@ static PyObject * CDataType_from_buffer(PyObject *type, PyObject *args) { - Py_buffer buffer; + PyObject *obj; + PyObject *mv; + PyObject *result; + Py_buffer *buffer; Py_ssize_t offset = 0; - PyObject *result, *mv; + StgDictObject *dict = PyType_stgdict(type); assert (dict); - if (!PyArg_ParseTuple(args, "w*|n:from_buffer", &buffer, &offset)) + if (!PyArg_ParseTuple(args, "O|n:from_buffer", &obj, &offset)) return NULL; + mv = PyMemoryView_FromObject(obj); + if (mv == NULL) + return NULL; + + buffer = PyMemoryView_GET_BUFFER(mv); + + if (buffer->readonly) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not writable"); + Py_DECREF(mv); + return NULL; + } + + if (!PyBuffer_IsContiguous(buffer, 'C')) { + PyErr_SetString(PyExc_TypeError, + "underlying buffer is not C contiguous"); + Py_DECREF(mv); + return NULL; + } + if (offset < 0) { PyErr_SetString(PyExc_ValueError, "offset cannot be negative"); - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - if (dict->size > buffer.len - offset) { + + if (dict->size > buffer->len - offset) { PyErr_Format(PyExc_ValueError, - "Buffer size too small (%zd instead of at least %zd bytes)", - buffer.len, dict->size + offset); - PyBuffer_Release(&buffer); + "Buffer size too small " + "(%zd instead of at least %zd bytes)", + buffer->len, dict->size + offset); + Py_DECREF(mv); return NULL; } - result = PyCData_AtAddress(type, (char *)buffer.buf + offset); + result = PyCData_AtAddress(type, (char *)buffer->buf + offset); if (result == NULL) { - PyBuffer_Release(&buffer); + Py_DECREF(mv); return NULL; } - mv = PyMemoryView_FromBuffer(&buffer); - if (mv == NULL) { - PyBuffer_Release(&buffer); + if (-1 == KeepRef((CDataObject *)result, -1, mv)) { + Py_DECREF(result); return NULL; } - /* Hack the memoryview so that it will release the buffer. */ - ((PyMemoryViewObject *)mv)->mbuf->master.obj = buffer.obj; - ((PyMemoryViewObject *)mv)->view.obj = buffer.obj; - if (-1 == KeepRef((CDataObject *)result, -1, mv)) - result = NULL; + return result; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 18:57:39 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 23:57:39 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325590=3A_Merge_rlcompleter_getattr_change_from_?= =?utf-8?b?My41?= Message-ID: <20151113235739.120344.65617@psf.io> https://hg.python.org/cpython/rev/ff68304356fe changeset: 99117:ff68304356fe parent: 99114:08c56962c24c parent: 99116:808279e14700 user: Martin Panter date: Fri Nov 13 23:48:17 2015 +0000 summary: Issue #25590: Merge rlcompleter getattr change from 3.5 files: Lib/rlcompleter.py | 8 +++++--- Lib/test/test_rlcompleter.py | 13 +++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -159,9 +159,11 @@ while True: for word in words: if (word[:n] == attr and - not (noprefix and word[:n+1] == noprefix) and - hasattr(thisobject, word)): - val = getattr(thisobject, word) + not (noprefix and word[:n+1] == noprefix)): + try: + val = getattr(thisobject, word) + except Exception: + continue # Exclude properties that are not set word = self._callable_postfix(val, "%s.%s" % (expr, word)) matches.append(word) if matches or not noprefix: diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -79,6 +79,19 @@ ['egg.{}('.format(x) for x in dir(str) if x.startswith('s')]) + def test_excessive_getattr(self): + # Ensure getattr() is invoked no more than once per attribute + class Foo: + calls = 0 + @property + def bar(self): + self.calls += 1 + return None + f = Foo() + completer = rlcompleter.Completer(dict(f=f)) + self.assertEqual(completer.complete('f.b', 0), 'f.bar') + self.assertEqual(f.calls, 1) + def test_complete(self): completer = rlcompleter.Completer() self.assertEqual(completer.complete('', 0), '\t') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -402,6 +402,9 @@ Library ------- +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + - Issue #25498: Fix a crash when garbage-collecting ctypes objects created by wrapping a memoryview. This was a regression made in 3.5a1. Based on patch by Eryksun. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 18:57:39 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 23:57:39 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTkw?= =?utf-8?q?=3A_Make_rlcompleter_only_call_getattr=28=29_once_per_attribute?= Message-ID: <20151113235738.120348.23341@psf.io> https://hg.python.org/cpython/rev/92f989bfeca2 changeset: 99115:92f989bfeca2 branch: 3.4 parent: 99110:9b23f7a94ba9 user: Martin Panter date: Fri Nov 13 22:47:00 2015 +0000 summary: Issue #25590: Make rlcompleter only call getattr() once per attribute Previously it was called another time via hasattr(), and both calls were made once for dir(f) and again for dir(f.__class__). This includes a backport of changing from a list to a set from revision 4dbb315fe667. files: Lib/rlcompleter.py | 17 ++++++++++------- Lib/test/test_rlcompleter.py | 13 +++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -136,20 +136,23 @@ return [] # get the content of the object, except __builtins__ - words = dir(thisobject) - if "__builtins__" in words: - words.remove("__builtins__") + words = set(dir(thisobject)) + words.discard("__builtins__") if hasattr(thisobject, '__class__'): - words.append('__class__') - words.extend(get_class_members(thisobject.__class__)) + words.add('__class__') + words.update(get_class_members(thisobject.__class__)) matches = [] n = len(attr) for word in words: - if word[:n] == attr and hasattr(thisobject, word): - val = getattr(thisobject, word) + if word[:n] == attr: + try: + val = getattr(thisobject, word) + except Exception: + continue # Exclude properties that are not set word = self._callable_postfix(val, "%s.%s" % (expr, word)) matches.append(word) + matches.sort() return matches def get_class_members(klass): diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -64,6 +64,19 @@ ['egg.{}('.format(x) for x in dir(str) if x.startswith('s')]) + def test_excessive_getattr(self): + # Ensure getattr() is invoked no more than once per attribute + class Foo: + calls = 0 + @property + def bar(self): + self.calls += 1 + return None + f = Foo() + completer = rlcompleter.Completer(dict(f=f)) + self.assertEqual(completer.complete('f.b', 0), 'f.bar') + self.assertEqual(f.calls, 1) + def test_complete(self): completer = rlcompleter.Completer() self.assertEqual(completer.complete('', 0), '\t') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -103,6 +103,9 @@ Library ------- +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + - Issue #25498: Fix a crash when garbage-collecting ctypes objects created by wrapping a memoryview. This was a regression made in 3.4.3. Based on patch by Eryksun. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 18:57:39 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 23:57:39 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325590=3A_Merge_rlcompleter_change_from_3=2E4_into_3?= =?utf-8?q?=2E5?= Message-ID: <20151113235738.88500.14972@psf.io> https://hg.python.org/cpython/rev/808279e14700 changeset: 99116:808279e14700 branch: 3.5 parent: 99112:deb0fb601191 parent: 99115:92f989bfeca2 user: Martin Panter date: Fri Nov 13 23:10:39 2015 +0000 summary: Issue #25590: Merge rlcompleter change from 3.4 into 3.5 files: Lib/rlcompleter.py | 17 ++++++++++------- Lib/test/test_rlcompleter.py | 13 +++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -136,20 +136,23 @@ return [] # get the content of the object, except __builtins__ - words = dir(thisobject) - if "__builtins__" in words: - words.remove("__builtins__") + words = set(dir(thisobject)) + words.discard("__builtins__") if hasattr(thisobject, '__class__'): - words.append('__class__') - words.extend(get_class_members(thisobject.__class__)) + words.add('__class__') + words.update(get_class_members(thisobject.__class__)) matches = [] n = len(attr) for word in words: - if word[:n] == attr and hasattr(thisobject, word): - val = getattr(thisobject, word) + if word[:n] == attr: + try: + val = getattr(thisobject, word) + except Exception: + continue # Exclude properties that are not set word = self._callable_postfix(val, "%s.%s" % (expr, word)) matches.append(word) + matches.sort() return matches def get_class_members(klass): diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -64,6 +64,19 @@ ['egg.{}('.format(x) for x in dir(str) if x.startswith('s')]) + def test_excessive_getattr(self): + # Ensure getattr() is invoked no more than once per attribute + class Foo: + calls = 0 + @property + def bar(self): + self.calls += 1 + return None + f = Foo() + completer = rlcompleter.Completer(dict(f=f)) + self.assertEqual(completer.complete('f.b', 0), 'f.bar') + self.assertEqual(f.calls, 1) + def test_complete(self): completer = rlcompleter.Completer() self.assertEqual(completer.complete('', 0), '\t') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -67,6 +67,9 @@ Library ------- +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + - Issue #25498: Fix a crash when garbage-collecting ctypes objects created by wrapping a memoryview. This was a regression made in 3.5a1. Based on patch by Eryksun. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 18:57:39 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 13 Nov 2015 23:57:39 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325590=3A_Complete?= =?utf-8?q?_attribute_names_even_if_they_are_not_yet_created?= Message-ID: <20151113235739.14363.36471@psf.io> https://hg.python.org/cpython/rev/bbf63749a129 changeset: 99118:bbf63749a129 user: Martin Panter date: Fri Nov 13 23:54:02 2015 +0000 summary: Issue #25590: Complete attribute names even if they are not yet created files: Doc/whatsnew/3.6.rst | 4 ++++ Lib/rlcompleter.py | 8 +++++--- Lib/test/test_rlcompleter.py | 8 ++++++++ Misc/NEWS | 4 ++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -120,6 +120,10 @@ with underscores. A space or a colon can be added after completed keyword. (Contributed by Serhiy Storchaka in :issue:`25011` and :issue:`25209`.) +Names of most attributes listed by :func:`dir` are now completed. +Previously, names of properties and slots which were not yet created on +an instance were excluded. (Contributed by Martin Panter in :issue:`25590`.) + urllib.robotparser ------------------ diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -160,12 +160,14 @@ for word in words: if (word[:n] == attr and not (noprefix and word[:n+1] == noprefix)): + match = "%s.%s" % (expr, word) try: val = getattr(thisobject, word) except Exception: - continue # Exclude properties that are not set - word = self._callable_postfix(val, "%s.%s" % (expr, word)) - matches.append(word) + pass # Include even if attribute not set + else: + match = self._callable_postfix(val, match) + matches.append(match) if matches or not noprefix: break if noprefix == '_': diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -92,6 +92,14 @@ self.assertEqual(completer.complete('f.b', 0), 'f.bar') self.assertEqual(f.calls, 1) + def test_uncreated_attr(self): + # Attributes like properties and slots should be completed even when + # they haven't been created on an instance + class Foo: + __slots__ = ("bar",) + completer = rlcompleter.Completer(dict(f=Foo())) + self.assertEqual(completer.complete('f.', 0), 'f.bar') + def test_complete(self): completer = rlcompleter.Completer() self.assertEqual(completer.complete('', 0), '\t') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -85,6 +85,10 @@ Library ------- +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. Also complete names of attributes such as properties and slots + which are listed by dir() but not yet created on an instance. + - Issue #25498: Fix a crash when garbage-collecting ctypes objects created by wrapping a memoryview. This was a regression made in 3.5a1. Based on patch by Eryksun. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 19:45:11 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 00:45:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NTkw?= =?utf-8?q?=3A_Make_rlcompleter_only_call_getattr=28=29_once_per_attribute?= Message-ID: <20151114004511.37474.98313@psf.io> https://hg.python.org/cpython/rev/16d83e11675f changeset: 99119:16d83e11675f branch: 2.7 parent: 99101:d3d974e92e6f user: Martin Panter date: Fri Nov 13 22:47:00 2015 +0000 summary: Issue #25590: Make rlcompleter only call getattr() once per attribute Previously it was called another time via hasattr(), and both calls were made once for dir(f) and again for dir(f.__class__). This includes a backport of changing from a list to a set from revision 4dbb315fe667. files: Lib/rlcompleter.py | 17 ++++++++++------- Lib/test/test_rlcompleter.py | 13 +++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -135,20 +135,23 @@ return [] # get the content of the object, except __builtins__ - words = dir(thisobject) - if "__builtins__" in words: - words.remove("__builtins__") + words = set(dir(thisobject)) + words.discard("__builtins__") if hasattr(thisobject, '__class__'): - words.append('__class__') - words.extend(get_class_members(thisobject.__class__)) + words.add('__class__') + words.update(get_class_members(thisobject.__class__)) matches = [] n = len(attr) for word in words: - if word[:n] == attr and hasattr(thisobject, word): - val = getattr(thisobject, word) + if word[:n] == attr: + try: + val = getattr(thisobject, word) + except Exception: + continue # Exclude properties that are not set word = self._callable_postfix(val, "%s.%s" % (expr, word)) matches.append(word) + matches.sort() return matches def get_class_members(klass): diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -65,6 +65,19 @@ ['egg.{}('.format(x) for x in dir(str) if x.startswith('s')]) + def test_excessive_getattr(self): + # Ensure getattr() is invoked no more than once per attribute + class Foo: + calls = 0 + @property + def bar(self): + self.calls += 1 + return None + f = Foo() + completer = rlcompleter.Completer(dict(f=f)) + self.assertEqual(completer.complete('f.b', 0), 'f.bar') + self.assertEqual(f.calls, 1) + def test_main(): support.run_unittest(TestRlcompleter) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -52,6 +52,9 @@ Library ------- +- Issue #25590: In the Readline completer, only call getattr() once per + attribute. + - Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating ssl.SSLContext. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 19:45:11 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 00:45:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1MDE3?= =?utf-8?q?=3A_Document_that_htmllib_is_superseded_by_module_HTMLParser?= Message-ID: <20151114004511.34158.62693@psf.io> https://hg.python.org/cpython/rev/7bc8f56ef1f3 changeset: 99120:7bc8f56ef1f3 branch: 2.7 user: Martin Panter date: Sat Nov 14 00:30:46 2015 +0000 summary: Issue #25017: Document that htmllib is superseded by module HTMLParser files: Doc/library/htmllib.rst | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Doc/library/htmllib.rst b/Doc/library/htmllib.rst --- a/Doc/library/htmllib.rst +++ b/Doc/library/htmllib.rst @@ -7,6 +7,8 @@ .. deprecated:: 2.6 The :mod:`htmllib` module has been removed in Python 3. + Use :mod:`HTMLParser` instead in Python 2, and the equivalent, + :mod:`html.parser`, in Python 3. .. index:: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:08:58 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:08:58 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Correct_Conten?= =?utf-8?q?t-Type_syntax_in_documentation?= Message-ID: <20151114020858.37478.60856@psf.io> https://hg.python.org/cpython/rev/688bfec53c46 changeset: 99121:688bfec53c46 branch: 3.4 parent: 99115:92f989bfeca2 user: Martin Panter date: Sat Nov 14 00:58:32 2015 +0000 summary: Correct Content-Type syntax in documentation files: Doc/library/urllib.request.rst | 2 +- Lib/http/cookiejar.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1107,7 +1107,7 @@ #!/usr/bin/env python import sys data = sys.stdin.read() - print('Content-type: text-plain\n\nGot Data: "%s"' % data) + print('Content-type: text/plain\n\nGot Data: "%s"' % data) Here is an example of doing a ``PUT`` request using :class:`Request`:: diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -423,10 +423,10 @@ Takes a list of lists of (key, value) pairs and produces a single header value. Attribute values are quoted if needed. - >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) - 'text/plain; charset="iso-8859/1"' - >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]]) - 'text/plain, charset="iso-8859/1"' + >>> join_header_words([[("text/plain", None), ("charset", "iso-8859-1")]]) + 'text/plain; charset="iso-8859-1"' + >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859-1")]]) + 'text/plain, charset="iso-8859-1"' """ headers = [] -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:08:58 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:08:58 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Fix_a_few_gram?= =?utf-8?q?mar_problems_in_the_documentation_and_comments?= Message-ID: <20151114020858.88506.90550@psf.io> https://hg.python.org/cpython/rev/c3282d91055f changeset: 99122:c3282d91055f branch: 3.4 user: Martin Panter date: Sat Nov 14 01:07:43 2015 +0000 summary: Fix a few grammar problems in the documentation and comments files: Doc/library/ast.rst | 2 +- Doc/library/copy.rst | 4 ++-- Doc/library/ftplib.rst | 4 ++-- Lib/doctest.py | 2 +- Lib/test/test_argparse.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -104,7 +104,7 @@ :mod:`ast` Helpers ------------------ -Apart from the node classes, :mod:`ast` module defines these utility functions +Apart from the node classes, the :mod:`ast` module defines these utility functions and classes for traversing abstract syntax trees: .. function:: parse(source, filename='', mode='exec') diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -67,8 +67,8 @@ Classes can use the same interfaces to control copying that they use to control pickling. See the description of module :mod:`pickle` for information on these -methods. In fact, :mod:`copy` module uses the registered pickle functions from -:mod:`copyreg` module. +methods. In fact, the :mod:`copy` module uses the registered +pickle functions from the :mod:`copyreg` module. .. index:: single: __copy__() (copy protocol) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -418,8 +418,8 @@ .. method:: FTP_TLS.auth() - Set up secure control connection by using TLS or SSL, depending on what - specified in :meth:`ssl_version` attribute. + Set up a secure control connection by using TLS or SSL, depending on what + is specified in the :attr:`ssl_version` attribute. .. versionchanged:: 3.4 The method now supports hostname check with diff --git a/Lib/doctest.py b/Lib/doctest.py --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1573,7 +1573,7 @@ # If `want` contains hex-escaped character such as "\u1234", # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]). - # On the other hand, `got` could be an another sequence of + # On the other hand, `got` could be another sequence of # characters such as [\u1234], so `want` and `got` should # be folded to hex-escaped ASCII string to compare. got = self._toAscii(got) diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -3019,7 +3019,7 @@ '''Test extremely small number of columns. TestCase prevents "COLUMNS" from being too small in the tests themselves, - but we don't want any exceptions thrown in such case. Only ugly representation. + but we don't want any exceptions thrown in such cases. Only ugly representation. ''' def setUp(self): env = support.EnvironmentVarGuard() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:08:59 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:08:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_typo_and_grammar_fixes_from_3=2E5?= Message-ID: <20151114020859.14377.2062@psf.io> https://hg.python.org/cpython/rev/582175c2b24a changeset: 99125:582175c2b24a parent: 99118:bbf63749a129 parent: 99124:649f3721f648 user: Martin Panter date: Sat Nov 14 01:29:13 2015 +0000 summary: Merge typo and grammar fixes from 3.5 files: Doc/library/ast.rst | 2 +- Doc/library/copy.rst | 4 +- Doc/library/ftplib.rst | 4 +- Doc/library/linecache.rst | 2 +- Doc/library/urllib.request.rst | 2 +- Doc/whatsnew/3.5.rst | 149 ++++++++++---------- Lib/doctest.py | 2 +- Lib/http/cookiejar.py | 8 +- Lib/test/test_argparse.py | 2 +- Misc/NEWS | 2 +- 10 files changed, 89 insertions(+), 88 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -104,7 +104,7 @@ :mod:`ast` Helpers ------------------ -Apart from the node classes, :mod:`ast` module defines these utility functions +Apart from the node classes, the :mod:`ast` module defines these utility functions and classes for traversing abstract syntax trees: .. function:: parse(source, filename='', mode='exec') diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -67,8 +67,8 @@ Classes can use the same interfaces to control copying that they use to control pickling. See the description of module :mod:`pickle` for information on these -methods. In fact, :mod:`copy` module uses the registered pickle functions from -:mod:`copyreg` module. +methods. In fact, the :mod:`copy` module uses the registered +pickle functions from the :mod:`copyreg` module. .. index:: single: __copy__() (copy protocol) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -418,8 +418,8 @@ .. method:: FTP_TLS.auth() - Set up secure control connection by using TLS or SSL, depending on what - specified in :meth:`ssl_version` attribute. + Set up a secure control connection by using TLS or SSL, depending on what + is specified in the :attr:`ssl_version` attribute. .. versionchanged:: 3.4 The method now supports hostname check with diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -49,7 +49,7 @@ .. function:: lazycache(filename, module_globals) - Capture enough detail about a non-file based module to permit getting its + Capture enough detail about a non-file-based module to permit getting its lines later via :func:`getline` even if *module_globals* is None in the later call. This avoids doing I/O until a line is actually needed, without having to carry the module globals around indefinitely. diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1168,7 +1168,7 @@ #!/usr/bin/env python import sys data = sys.stdin.read() - print('Content-type: text-plain\n\nGot Data: "%s"' % data) + print('Content-type: text/plain\n\nGot Data: "%s"' % data) Here is an example of doing a ``PUT`` request using :class:`Request`:: diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -113,7 +113,7 @@ :ref:`implemented in C `, which makes it 4 to 100 times faster. -* :mod:`ssl` module gained +* The :mod:`ssl` module gained :ref:`support for Memory BIO `, which decouples SSL protocol handling from network IO. @@ -346,7 +346,7 @@ PEP 461 - % formatting support for bytes and bytearray ------------------------------------------------------ -:pep:`461` adds support for ``%`` +:pep:`461` adds support for the ``%`` :ref:`interpolation operator ` to :class:`bytes` and :class:`bytearray`. @@ -467,7 +467,7 @@ An :py:data:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would -raise :exc:`InterruptedError` in such case. This meant that, when writing a +raise :exc:`InterruptedError` in such cases. This meant that, when writing a Python application, the developer had two choices: #. Ignore the ``InterruptedError``. @@ -514,7 +514,7 @@ :func:`~os.writev`; * special cases: :func:`os.close` and :func:`os.dup2` now ignore - :py:data:`~errno.EINTR` error, the syscall is not retried (see the PEP + :py:data:`~errno.EINTR` errors; the syscall is not retried (see the PEP for the rationale); * :mod:`select` functions: :func:`devpoll.poll() `, @@ -757,7 +757,7 @@ asyncio ------- -Since :mod:`asyncio` module is :term:`provisional `, +Since the :mod:`asyncio` module is :term:`provisional `, all changes introduced in Python 3.5 have also been backported to Python 3.4.x. Notable changes in the :mod:`asyncio` module since Python 3.4.0: @@ -857,7 +857,7 @@ The :class:`~collections.deque` class now defines :meth:`~collections.deque.index`, :meth:`~collections.deque.insert`, and -:meth:`~collections.deque.copy`, as well as supports ``+`` and ``*`` operators. +:meth:`~collections.deque.copy`, and supports the ``+`` and ``*`` operators. This allows deques to be recognized as a :class:`~collections.abc.MutableSequence` and improves their substitutability for lists. (Contributed by Raymond Hettinger in :issue:`23704`.) @@ -871,7 +871,7 @@ (Contributed by Berker Peksag in :issue:`24064`.) -The :class:`~collections.UserString` class now implements +The :class:`~collections.UserString` class now implements the :meth:`__getnewargs__`, :meth:`__rmod__`, :meth:`~str.casefold`, :meth:`~str.format_map`, :meth:`~str.isprintable`, and :meth:`~str.maketrans` methods to match the corresponding methods of :class:`str`. @@ -925,8 +925,8 @@ :meth:`~concurrent.futures.ProcessPoolExecutor` is used. (Contributed by Dan O'Reilly in :issue:`11271`.) -A number of workers in :class:`~concurrent.futures.ThreadPoolExecutor` constructor is -optional now. The default value equals to 5 times the number of CPUs. +The number of workers in the :class:`~concurrent.futures.ThreadPoolExecutor` +constructor is optional now. The default value is 5 times the number of CPUs. (Contributed by Claudiu Popa in :issue:`21527`.) @@ -934,10 +934,10 @@ ------------ :mod:`configparser` now provides a way to customize the conversion -of values by specifying a dictionary of converters in +of values by specifying a dictionary of converters in the :class:`~configparser.ConfigParser` constructor, or by defining them as methods in ``ConfigParser`` subclasses. Converters defined in -parser instance are inherited by its section proxies. +a parser instance are inherited by its section proxies. Example:: @@ -989,9 +989,9 @@ curses ------ -The new :func:`~curses.update_lines_cols` function updates :envvar:`LINES` +The new :func:`~curses.update_lines_cols` function updates the :envvar:`LINES` and :envvar:`COLS` environment variables. This is useful for detecting -manual screen resize. (Contributed by Arnon Yaari in :issue:`4254`.) +manual screen resizing. (Contributed by Arnon Yaari in :issue:`4254`.) dbm @@ -1019,7 +1019,7 @@ distutils --------- -Both ``build`` and ``build_ext`` commands now accept a ``-j`` option to +Both the ``build`` and ``build_ext`` commands now accept a ``-j`` option to enable parallel building of extension modules. (Contributed by Antoine Pitrou in :issue:`5309`.) @@ -1032,7 +1032,7 @@ ------- The :func:`~doctest.DocTestSuite` function returns an empty -:class:`unittest.TestSuite` if *module* contains no docstrings instead of +:class:`unittest.TestSuite` if *module* contains no docstrings, instead of raising :exc:`ValueError`. (Contributed by Glenn Jones in :issue:`15916`.) @@ -1081,7 +1081,7 @@ faulthandler ------------ -:func:`~faulthandler.enable`, :func:`~faulthandler.register`, +The :func:`~faulthandler.enable`, :func:`~faulthandler.register`, :func:`~faulthandler.dump_traceback` and :func:`~faulthandler.dump_traceback_later` functions now accept file descriptors in addition to file-like objects. @@ -1093,7 +1093,7 @@ .. _whatsnew-lrucache: -Most of :func:`~functools.lru_cache` machinery is now implemented in C, making +Most of the :func:`~functools.lru_cache` machinery is now implemented in C, making it significantly faster. (Contributed by Matt Joiner, Alexey Kachayev, and Serhiy Storchaka in :issue:`14373`.) @@ -1101,15 +1101,15 @@ glob ---- -:func:`~glob.iglob` and :func:`~glob.glob` functions now support recursive -search in subdirectories using the ``"**"`` pattern. +The :func:`~glob.iglob` and :func:`~glob.glob` functions now support recursive +search in subdirectories, using the ``"**"`` pattern. (Contributed by Serhiy Storchaka in :issue:`13968`.) gzip ---- -The *mode* argument of :class:`~gzip.GzipFile` constructor now +The *mode* argument of the :class:`~gzip.GzipFile` constructor now accepts ``"x"`` to request exclusive creation. (Contributed by Tim Heaney in :issue:`19222`.) @@ -1176,7 +1176,7 @@ imaplib ------- -The :class:`~imaplib.IMAP4` class now supports :term:`context manager` protocol. +The :class:`~imaplib.IMAP4` class now supports the :term:`context manager` protocol. When used in a :keyword:`with` statement, the IMAP4 ``LOGOUT`` command will be called automatically at the end of the block. (Contributed by Tarek Ziad? and Serhiy Storchaka in :issue:`4972`.) @@ -1184,7 +1184,7 @@ The :mod:`imaplib` module now supports :rfc:`5161` (ENABLE Extension) and :rfc:`6855` (UTF-8 Support) via the :meth:`IMAP4.enable() ` method. A new :attr:`IMAP4.utf8_enabled ` -attribute, tracks whether or not :rfc:`6855` support is enabled. +attribute tracks whether or not :rfc:`6855` support is enabled. (Contributed by Milan Oberkirch, R. David Murray, and Maciej Szulik in :issue:`21800`.) @@ -1226,7 +1226,7 @@ inspect ------- -Both :class:`~inspect.Signature` and :class:`~inspect.Parameter` classes are +Both the :class:`~inspect.Signature` and :class:`~inspect.Parameter` classes are now picklable and hashable. (Contributed by Yury Selivanov in :issue:`20726` and :issue:`20334`.) @@ -1260,7 +1260,7 @@ and :func:`~inspect.getcoroutinestate`. (Contributed by Yury Selivanov in :issue:`24017` and :issue:`24400`.) -:func:`~inspect.stack`, :func:`~inspect.trace`, +The :func:`~inspect.stack`, :func:`~inspect.trace`, :func:`~inspect.getouterframes`, and :func:`~inspect.getinnerframes` functions now return a list of named tuples. (Contributed by Daniel Shahaf in :issue:`16808`.) @@ -1279,7 +1279,7 @@ ipaddress --------- -Both :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes +Both the :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes now accept an ``(address, netmask)`` tuple argument, so as to easily construct network objects from existing addresses:: @@ -1291,7 +1291,7 @@ (Contributed by Peter Moody and Antoine Pitrou in :issue:`16531`.) -A new :attr:`~ipaddress.IPv4Network.reverse_pointer` attribute for +A new :attr:`~ipaddress.IPv4Network.reverse_pointer` attribute for the :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes returns the name of the reverse DNS PTR record:: @@ -1323,7 +1323,7 @@ --------- A new :func:`~linecache.lazycache` function can be used to capture information -about a non-file based module to permit getting its lines later via +about a non-file-based module to permit getting its lines later via :func:`~linecache.getline`. This avoids doing I/O until a line is actually needed, without having to carry the module globals around indefinitely. (Contributed by Robert Collins in :issue:`17911`.) @@ -1436,13 +1436,13 @@ of the ``BY_HANDLE_FILE_INFORMATION`` structure returned by ``GetFileInformationByHandle()``. (Contributed by Ben Hoyt in :issue:`21719`.) -The :func:`~os.urandom` function now uses ``getrandom()`` syscall on Linux 3.17 +The :func:`~os.urandom` function now uses the ``getrandom()`` syscall on Linux 3.17 or newer, and ``getentropy()`` on OpenBSD 5.6 and newer, removing the need to use ``/dev/urandom`` and avoiding failures due to potential file descriptor exhaustion. (Contributed by Victor Stinner in :issue:`22181`.) New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow to -get and set a file descriptor blocking mode (:data:`~os.O_NONBLOCK`.) +get and set a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.) (Contributed by Victor Stinner in :issue:`22054`.) The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported @@ -1466,8 +1466,8 @@ ------- The new :meth:`Path.samefile() ` method can be used -to check whether the path points to the same file as other path, which can be -either an another :class:`~pathlib.Path` object, or a string:: +to check whether the path points to the same file as another path, which can +be either another :class:`~pathlib.Path` object, or a string:: >>> import pathlib >>> p1 = pathlib.Path('/etc/hosts') @@ -1486,7 +1486,7 @@ Claudiu Popa in :issue:`19776`.) A new :meth:`Path.home() ` class method can be used to get -an instance of :class:`~pathlib.Path` object representing the user?s home +a :class:`~pathlib.Path` instance representing the user?s home directory. (Contributed by Victor Salgado and Mayank Tripathi in :issue:`19777`.) @@ -1539,17 +1539,17 @@ (Contributed by Serhiy Storchaka in :issue:`9179`.) -The number of capturing groups in regular expression is no longer limited by +The number of capturing groups in regular expressions is no longer limited to 100. (Contributed by Serhiy Storchaka in :issue:`22437`.) The :func:`~re.sub` and :func:`~re.subn` functions now replace unmatched groups with empty strings instead of raising an exception. (Contributed by Serhiy Storchaka in :issue:`1519638`.) -The :class:`re.error` exceptions have new attributes: +The :class:`re.error` exceptions have new attributes, :attr:`~re.error.msg`, :attr:`~re.error.pattern`, :attr:`~re.error.pos`, :attr:`~re.error.lineno`, -and :attr:`~re.error.colno` that provide better context +and :attr:`~re.error.colno`, that provide better context information about the error:: >>> re.compile(""" @@ -1607,7 +1607,7 @@ smtpd ----- -Both :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now +Both the :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now accept a *decode_data* keyword argument to determine if the ``DATA`` portion of the SMTP transaction is decoded using the ``"utf-8"`` codec or is instead provided to the @@ -1649,7 +1649,7 @@ accepts an additional debuglevel (2), which enables timestamps in debug messages. (Contributed by Gavin Chappell and Maciej Szulik in :issue:`16914`.) -Both :meth:`SMTP.sendmail() ` and +Both the :meth:`SMTP.sendmail() ` and :meth:`SMTP.send_message() ` methods now support support :rfc:`6531` (SMTPUTF8). (Contributed by Milan Oberkirch and R. David Murray in :issue:`22027`.) @@ -1658,7 +1658,7 @@ sndhdr ------ -:func:`~sndhdr.what` and :func:`~sndhdr.whathdr` functions now return +The :func:`~sndhdr.what` and :func:`~sndhdr.whathdr` functions now return a :func:`~collections.namedtuple`. (Contributed by Claudiu Popa in :issue:`18615`.) @@ -1671,7 +1671,7 @@ A new :meth:`socket.sendfile() ` method allows to send a file over a socket by using the high-performance :func:`os.sendfile` -function on UNIX resulting in uploads being from 2 to 3 times faster than when +function on UNIX, resulting in uploads being from 2 to 3 times faster than when using plain :meth:`socket.send() `. (Contributed by Giampaolo Rodola' in :issue:`17552`.) @@ -1682,7 +1682,7 @@ The *backlog* argument of the :meth:`socket.listen() ` method is now optional. By default it is set to -:data:`SOMAXCONN ` or to ``128`` whichever is less. +:data:`SOMAXCONN ` or to ``128``, whichever is less. (Contributed by Charles-Fran?ois Natali in :issue:`21455`.) @@ -1698,7 +1698,7 @@ The new :class:`~ssl.SSLObject` class has been added to provide SSL protocol support for cases when the network I/O capabilities of :class:`~ssl.SSLSocket` -are not necessary or suboptimal. ``SSLObject`` represents +are not necessary or are suboptimal. ``SSLObject`` represents an SSL protocol instance, but does not implement any network I/O methods, and instead provides a memory buffer interface. The new :class:`~ssl.MemoryBIO` class can be used to pass data between Python and an SSL protocol instance. @@ -1716,8 +1716,8 @@ (Contributed by Benjamin Peterson in :issue:`20188`.) -Where OpenSSL support is present, :mod:`ssl` module now implements -*Application-Layer Protocol Negotiation* TLS extension as described +Where OpenSSL support is present, the :mod:`ssl` module now implements +the *Application-Layer Protocol Negotiation* TLS extension as described in :rfc:`7301`. The new :meth:`SSLContext.set_alpn_protocols() ` @@ -1727,7 +1727,7 @@ The new :meth:`SSLSocket.selected_alpn_protocol() ` returns the protocol that was selected during the TLS handshake. -:data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. +The :data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. Other Changes @@ -1742,7 +1742,7 @@ (Contributed by Giampaolo Rodola' in :issue:`17552`.) The :meth:`SSLSocket.send() ` method now raises either -:exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` exception on a +the :exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` exception on a non-blocking socket if the operation would block. Previously, it would return ``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) @@ -1758,7 +1758,7 @@ The :meth:`SSLSocket.do_handshake() `, :meth:`SSLSocket.read() `, :meth:`SSLSocket.shutdown() `, and -:meth:`SSLSocket.write() ` methods of :class:`~ssl.SSLSocket` +:meth:`SSLSocket.write() ` methods of the :class:`~ssl.SSLSocket` class no longer reset the socket timeout every time bytes are received or sent. The socket timeout is now the maximum total duration of the method. (Contributed by Victor Stinner in :issue:`23853`.) @@ -1770,7 +1770,7 @@ sqlite3 ------- -The :class:`~sqlite3.Row` class now fully supports sequence protocol, +The :class:`~sqlite3.Row` class now fully supports the sequence protocol, in particular :func:`reversed` iteration and slice indexing. (Contributed by Claudiu Popa in :issue:`10203`; by Lucas Sinclair, Jessica McKellar, and Serhiy Storchaka in :issue:`13583`.) @@ -1824,7 +1824,7 @@ --------- The name of the user scripts directory on Windows now includes the first -two components of Python version. (Contributed by Paul Moore +two components of the Python version. (Contributed by Paul Moore in :issue:`23437`.) @@ -1834,7 +1834,7 @@ The *mode* argument of the :func:`~tarfile.open` function now accepts ``"x"`` to request exclusive creation. (Contributed by Berker Peksag in :issue:`21717`.) -:meth:`TarFile.extractall() ` and +The :meth:`TarFile.extractall() ` and :meth:`TarFile.extract() ` methods now take a keyword argument *numeric_only*. If set to ``True``, the extracted files and directories will be owned by the numeric ``uid`` and ``gid`` from the tarfile. @@ -1851,7 +1851,7 @@ threading --------- -Both :meth:`Lock.acquire() ` and +Both the :meth:`Lock.acquire() ` and :meth:`RLock.acquire() ` methods now use a monotonic clock for timeout management. (Contributed by Victor Stinner in :issue:`22043`.) @@ -1898,7 +1898,7 @@ :class:`~traceback.StackSummary`, and :class:`~traceback.FrameSummary`. (Contributed by Robert Collins in :issue:`17911`.) -Both :func:`~traceback.print_tb` and :func:`~traceback.print_stack` functions +Both the :func:`~traceback.print_tb` and :func:`~traceback.print_stack` functions now support negative values for the *limit* argument. (Contributed by Dmitry Kazakov in :issue:`22619`.) @@ -1912,8 +1912,8 @@ :term:`awaitables `. (Contributed by Yury Selivanov in :issue:`24017`.) -A new :class:`~types.CoroutineType` is the type of :term:`coroutine` objects -created by :keyword:`async def` functions. +A new type called :class:`~types.CoroutineType`, which is used for +:term:`coroutine` objects created by :keyword:`async def` functions. (Contributed by Yury Selivanov in :issue:`24400`.) @@ -1934,7 +1934,7 @@ is impossible for a package name to match the default pattern. (Contributed by Robert Collins and Barry A. Warsaw in :issue:`16662`.) -Unittest discovery errors now are exposed in +Unittest discovery errors now are exposed in the :data:`TestLoader.errors ` attribute of the :class:`~unittest.TestLoader` instance. (Contributed by Robert Collins in :issue:`19746`.) @@ -1948,7 +1948,7 @@ The :class:`~unittest.mock.Mock` class has the following improvements: -* Class constructor has a new *unsafe* parameter, which causes mock +* The class constructor has a new *unsafe* parameter, which causes mock objects to raise :exc:`AttributeError` on attribute names starting with ``"assert"``. (Contributed by Kushal Das in :issue:`21238`.) @@ -2006,10 +2006,10 @@ ------ The :class:`client.ServerProxy ` class now supports -:term:`context manager` protocol. +the :term:`context manager` protocol. (Contributed by Claudiu Popa in :issue:`20627`.) -:class:`client.ServerProxy ` constructor now accepts +The :class:`client.ServerProxy ` constructor now accepts an optional :class:`ssl.SSLContext` instance. (Contributed by Alex Gaynor in :issue:`22960`.) @@ -2039,7 +2039,7 @@ Other module-level changes ========================== -Many functions in :mod:`mmap`, :mod:`ossaudiodev`, :mod:`socket`, +Many functions in the :mod:`mmap`, :mod:`ossaudiodev`, :mod:`socket`, :mod:`ssl`, and :mod:`codecs` modules now accept writable :term:`bytes-like objects `. (Contributed by Serhiy Storchaka in :issue:`23001`.) @@ -2098,7 +2098,7 @@ improvement in some benchmarks. (Contributed by Antoine Pitrou in :issue:`22847`.) -Objects from :mod:`random` module now use 50% less memory on 64-bit +Objects from the :mod:`random` module now use 50% less memory on 64-bit builds. (Contributed by Serhiy Storchaka in :issue:`23488`.) The :func:`property` getter calls are up to 25% faster. @@ -2108,7 +2108,7 @@ (Contributed by Stefan Behnel in :issue:`22464`.) String methods :meth:`~str.find`, :meth:`~str.rfind`, :meth:`~str.split`, -:meth:`~str.partition` and :keyword:`in` string operator are now significantly +:meth:`~str.partition` and the :keyword:`in` string operator are now significantly faster for searching 1-character substrings. (Contributed by Serhiy Storchaka in :issue:`23573`.) @@ -2154,14 +2154,14 @@ (Contributed by Benjamin Peterson in :issue:`21176`. See also :pep:`465` for details.) -The :c:member:`PyTypeObject.tp_finalize` slot is now part of stable ABI. +The :c:member:`PyTypeObject.tp_finalize` slot is now part of the stable ABI. Windows builds now require Microsoft Visual C++ 14.0, which is available as part of `Visual Studio 2015 `_. -Extension modules now include platform information tag in their filename on +Extension modules now include a platform information tag in their filename on some platforms (the tag is optional, and CPython will import extensions without -it; although if the tag is present and mismatched, the extension won't be +it, although if the tag is present and mismatched, the extension won't be loaded): * On Linux, extension module filenames end with @@ -2217,7 +2217,7 @@ Deprecated Python Behavior -------------------------- -Raising :exc:`StopIteration` exception inside a generator will now generate a silent +Raising the :exc:`StopIteration` exception inside a generator will now generate a silent :exc:`PendingDeprecationWarning`, which will become a non-silent deprecation warning in Python 3.6 and will trigger a :exc:`RuntimeError` in Python 3.7. See :ref:`PEP 479: Change StopIteration handling inside generators ` @@ -2276,7 +2276,7 @@ :func:`~inspect.getargvalues`, :func:`~inspect.getcallargs`, :func:`~inspect.getargvalues`, :func:`~inspect.formatargspec`, and :func:`~inspect.formatargvalues` functions are deprecated in favor of -:func:`inspect.signature` API. +the :func:`inspect.signature` API. (Contributed by Yury Selivanov in :issue:`20438`.) Use of :const:`re.LOCALE` flag with str patterns or :const:`re.ASCII` is now @@ -2354,7 +2354,7 @@ on a non-blocking socket if the operation would block. Previously, it would return ``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) -* The ``__name__`` attribute of generator is now set from the function name, +* The ``__name__`` attribute of generators is now set from the function name, instead of being set from the code name. Use ``gen.gi_code.co_name`` to retrieve the code name. Generators also have a new ``__qualname__`` attribute, the qualified name, which is now used for the representation @@ -2376,7 +2376,7 @@ * If the current directory is set to a directory that no longer exists then :exc:`FileNotFoundError` will no longer be raised and instead :meth:`~importlib.machinery.FileFinder.find_spec` will return ``None`` - **without** caching ``None`` in :data:`sys.path_importer_cache` which is + **without** caching ``None`` in :data:`sys.path_importer_cache`, which is different than the typical case (:issue:`22834`). * HTTP status code and messages from :mod:`http.client` and :mod:`http.server` @@ -2395,7 +2395,7 @@ * The :func:`re.split` function always ignored empty pattern matches, so the ``"x*"`` pattern worked the same as ``"x+"``, and the ``"\b"`` pattern never worked. Now :func:`re.split` raises a warning if the pattern could match - an empty string. For compatibility use patterns that never match an empty + an empty string. For compatibility, use patterns that never match an empty string (e.g. ``"x+"`` instead of ``"x*"``). Patterns that could only match an empty string (such as ``"\b"``) now raise an error. (Contributed by Serhiy Storchaka in :issue:`22818`.) @@ -2431,9 +2431,9 @@ * The ``pygettext.py`` Tool now uses the standard +NNNN format for timezones in the POT-Creation-Date header. -* The :mod:`smtplib` module now uses :data:`sys.stderr` instead of previous - module level :data:`stderr` variable for debug output. If your (test) - program depends on patching the module level variable to capture the debug +* The :mod:`smtplib` module now uses :data:`sys.stderr` instead of the previous + module-level :data:`stderr` variable for debug output. If your (test) + program depends on patching the module-level variable to capture the debug output, you will need to update it to capture sys.stderr instead. * The :meth:`str.startswith` and :meth:`str.endswith` methods no longer return @@ -2471,11 +2471,12 @@ (Contributed by Serhiy Storchaka in :issue:`22453`.) * Because the lack of the :attr:`__module__` attribute breaks pickling and - introspection, a deprecation warning now is raised for builtin type without - the :attr:`__module__` attribute. Would be an AttributeError in future. + introspection, a deprecation warning is now raised for builtin types without + the :attr:`__module__` attribute. This would be an AttributeError in + the future. (Contributed by Serhiy Storchaka in :issue:`20204`.) -* As part of :pep:`492` implementation, ``tp_reserved`` slot of +* As part of the :pep:`492` implementation, the ``tp_reserved`` slot of :c:type:`PyTypeObject` was replaced with a :c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for new types, structures and functions. diff --git a/Lib/doctest.py b/Lib/doctest.py --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1575,7 +1575,7 @@ # If `want` contains hex-escaped character such as "\u1234", # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]). - # On the other hand, `got` could be an another sequence of + # On the other hand, `got` could be another sequence of # characters such as [\u1234], so `want` and `got` should # be folded to hex-escaped ASCII string to compare. got = self._toAscii(got) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -423,10 +423,10 @@ Takes a list of lists of (key, value) pairs and produces a single header value. Attribute values are quoted if needed. - >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) - 'text/plain; charset="iso-8859/1"' - >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]]) - 'text/plain, charset="iso-8859/1"' + >>> join_header_words([[("text/plain", None), ("charset", "iso-8859-1")]]) + 'text/plain; charset="iso-8859-1"' + >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859-1")]]) + 'text/plain, charset="iso-8859-1"' """ headers = [] diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -3026,7 +3026,7 @@ '''Test extremely small number of columns. TestCase prevents "COLUMNS" from being too small in the tests themselves, - but we don't want any exceptions thrown in such case. Only ugly representation. + but we don't want any exceptions thrown in such cases. Only ugly representation. ''' def setUp(self): env = support.EnvironmentVarGuard() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1854,7 +1854,7 @@ C API ----- -- Issue #20204: Deprecation warning is now raised for builtin type without the +- Issue #20204: Deprecation warning is now raised for builtin types without the __module__ attribute. Windows -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:09:00 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:09:00 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fix_grammar_in?= =?utf-8?q?_whatsnew/3=2E5=2Erst_and_elsewhere?= Message-ID: <20151114020859.34177.89336@psf.io> https://hg.python.org/cpython/rev/649f3721f648 changeset: 99124:649f3721f648 branch: 3.5 user: Martin Panter date: Sat Nov 14 01:14:54 2015 +0000 summary: Fix grammar in whatsnew/3.5.rst and elsewhere Mainly missing grammatical articles (the, a). files: Doc/library/linecache.rst | 2 +- Doc/whatsnew/3.5.rst | 149 +++++++++++++------------ Misc/NEWS | 2 +- 3 files changed, 77 insertions(+), 76 deletions(-) diff --git a/Doc/library/linecache.rst b/Doc/library/linecache.rst --- a/Doc/library/linecache.rst +++ b/Doc/library/linecache.rst @@ -49,7 +49,7 @@ .. function:: lazycache(filename, module_globals) - Capture enough detail about a non-file based module to permit getting its + Capture enough detail about a non-file-based module to permit getting its lines later via :func:`getline` even if *module_globals* is None in the later call. This avoids doing I/O until a line is actually needed, without having to carry the module globals around indefinitely. diff --git a/Doc/whatsnew/3.5.rst b/Doc/whatsnew/3.5.rst --- a/Doc/whatsnew/3.5.rst +++ b/Doc/whatsnew/3.5.rst @@ -113,7 +113,7 @@ :ref:`implemented in C `, which makes it 4 to 100 times faster. -* :mod:`ssl` module gained +* The :mod:`ssl` module gained :ref:`support for Memory BIO `, which decouples SSL protocol handling from network IO. @@ -346,7 +346,7 @@ PEP 461 - % formatting support for bytes and bytearray ------------------------------------------------------ -:pep:`461` adds support for ``%`` +:pep:`461` adds support for the ``%`` :ref:`interpolation operator ` to :class:`bytes` and :class:`bytearray`. @@ -467,7 +467,7 @@ An :py:data:`errno.EINTR` error code is returned whenever a system call, that is waiting for I/O, is interrupted by a signal. Previously, Python would -raise :exc:`InterruptedError` in such case. This meant that, when writing a +raise :exc:`InterruptedError` in such cases. This meant that, when writing a Python application, the developer had two choices: #. Ignore the ``InterruptedError``. @@ -514,7 +514,7 @@ :func:`~os.writev`; * special cases: :func:`os.close` and :func:`os.dup2` now ignore - :py:data:`~errno.EINTR` error, the syscall is not retried (see the PEP + :py:data:`~errno.EINTR` errors; the syscall is not retried (see the PEP for the rationale); * :mod:`select` functions: :func:`devpoll.poll() `, @@ -757,7 +757,7 @@ asyncio ------- -Since :mod:`asyncio` module is :term:`provisional `, +Since the :mod:`asyncio` module is :term:`provisional `, all changes introduced in Python 3.5 have also been backported to Python 3.4.x. Notable changes in the :mod:`asyncio` module since Python 3.4.0: @@ -857,7 +857,7 @@ The :class:`~collections.deque` class now defines :meth:`~collections.deque.index`, :meth:`~collections.deque.insert`, and -:meth:`~collections.deque.copy`, as well as supports ``+`` and ``*`` operators. +:meth:`~collections.deque.copy`, and supports the ``+`` and ``*`` operators. This allows deques to be recognized as a :class:`~collections.abc.MutableSequence` and improves their substitutability for lists. (Contributed by Raymond Hettinger in :issue:`23704`.) @@ -871,7 +871,7 @@ (Contributed by Berker Peksag in :issue:`24064`.) -The :class:`~collections.UserString` class now implements +The :class:`~collections.UserString` class now implements the :meth:`__getnewargs__`, :meth:`__rmod__`, :meth:`~str.casefold`, :meth:`~str.format_map`, :meth:`~str.isprintable`, and :meth:`~str.maketrans` methods to match the corresponding methods of :class:`str`. @@ -925,8 +925,8 @@ :meth:`~concurrent.futures.ProcessPoolExecutor` is used. (Contributed by Dan O'Reilly in :issue:`11271`.) -A number of workers in :class:`~concurrent.futures.ThreadPoolExecutor` constructor is -optional now. The default value equals to 5 times the number of CPUs. +The number of workers in the :class:`~concurrent.futures.ThreadPoolExecutor` +constructor is optional now. The default value is 5 times the number of CPUs. (Contributed by Claudiu Popa in :issue:`21527`.) @@ -934,10 +934,10 @@ ------------ :mod:`configparser` now provides a way to customize the conversion -of values by specifying a dictionary of converters in +of values by specifying a dictionary of converters in the :class:`~configparser.ConfigParser` constructor, or by defining them as methods in ``ConfigParser`` subclasses. Converters defined in -parser instance are inherited by its section proxies. +a parser instance are inherited by its section proxies. Example:: @@ -989,9 +989,9 @@ curses ------ -The new :func:`~curses.update_lines_cols` function updates :envvar:`LINES` +The new :func:`~curses.update_lines_cols` function updates the :envvar:`LINES` and :envvar:`COLS` environment variables. This is useful for detecting -manual screen resize. (Contributed by Arnon Yaari in :issue:`4254`.) +manual screen resizing. (Contributed by Arnon Yaari in :issue:`4254`.) dbm @@ -1019,7 +1019,7 @@ distutils --------- -Both ``build`` and ``build_ext`` commands now accept a ``-j`` option to +Both the ``build`` and ``build_ext`` commands now accept a ``-j`` option to enable parallel building of extension modules. (Contributed by Antoine Pitrou in :issue:`5309`.) @@ -1032,7 +1032,7 @@ ------- The :func:`~doctest.DocTestSuite` function returns an empty -:class:`unittest.TestSuite` if *module* contains no docstrings instead of +:class:`unittest.TestSuite` if *module* contains no docstrings, instead of raising :exc:`ValueError`. (Contributed by Glenn Jones in :issue:`15916`.) @@ -1081,7 +1081,7 @@ faulthandler ------------ -:func:`~faulthandler.enable`, :func:`~faulthandler.register`, +The :func:`~faulthandler.enable`, :func:`~faulthandler.register`, :func:`~faulthandler.dump_traceback` and :func:`~faulthandler.dump_traceback_later` functions now accept file descriptors in addition to file-like objects. @@ -1093,7 +1093,7 @@ .. _whatsnew-lrucache: -Most of :func:`~functools.lru_cache` machinery is now implemented in C, making +Most of the :func:`~functools.lru_cache` machinery is now implemented in C, making it significantly faster. (Contributed by Matt Joiner, Alexey Kachayev, and Serhiy Storchaka in :issue:`14373`.) @@ -1101,15 +1101,15 @@ glob ---- -:func:`~glob.iglob` and :func:`~glob.glob` functions now support recursive -search in subdirectories using the ``"**"`` pattern. +The :func:`~glob.iglob` and :func:`~glob.glob` functions now support recursive +search in subdirectories, using the ``"**"`` pattern. (Contributed by Serhiy Storchaka in :issue:`13968`.) gzip ---- -The *mode* argument of :class:`~gzip.GzipFile` constructor now +The *mode* argument of the :class:`~gzip.GzipFile` constructor now accepts ``"x"`` to request exclusive creation. (Contributed by Tim Heaney in :issue:`19222`.) @@ -1176,7 +1176,7 @@ imaplib ------- -The :class:`~imaplib.IMAP4` class now supports :term:`context manager` protocol. +The :class:`~imaplib.IMAP4` class now supports the :term:`context manager` protocol. When used in a :keyword:`with` statement, the IMAP4 ``LOGOUT`` command will be called automatically at the end of the block. (Contributed by Tarek Ziad? and Serhiy Storchaka in :issue:`4972`.) @@ -1184,7 +1184,7 @@ The :mod:`imaplib` module now supports :rfc:`5161` (ENABLE Extension) and :rfc:`6855` (UTF-8 Support) via the :meth:`IMAP4.enable() ` method. A new :attr:`IMAP4.utf8_enabled ` -attribute, tracks whether or not :rfc:`6855` support is enabled. +attribute tracks whether or not :rfc:`6855` support is enabled. (Contributed by Milan Oberkirch, R. David Murray, and Maciej Szulik in :issue:`21800`.) @@ -1226,7 +1226,7 @@ inspect ------- -Both :class:`~inspect.Signature` and :class:`~inspect.Parameter` classes are +Both the :class:`~inspect.Signature` and :class:`~inspect.Parameter` classes are now picklable and hashable. (Contributed by Yury Selivanov in :issue:`20726` and :issue:`20334`.) @@ -1260,7 +1260,7 @@ and :func:`~inspect.getcoroutinestate`. (Contributed by Yury Selivanov in :issue:`24017` and :issue:`24400`.) -:func:`~inspect.stack`, :func:`~inspect.trace`, +The :func:`~inspect.stack`, :func:`~inspect.trace`, :func:`~inspect.getouterframes`, and :func:`~inspect.getinnerframes` functions now return a list of named tuples. (Contributed by Daniel Shahaf in :issue:`16808`.) @@ -1279,7 +1279,7 @@ ipaddress --------- -Both :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes +Both the :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes now accept an ``(address, netmask)`` tuple argument, so as to easily construct network objects from existing addresses:: @@ -1291,7 +1291,7 @@ (Contributed by Peter Moody and Antoine Pitrou in :issue:`16531`.) -A new :attr:`~ipaddress.IPv4Network.reverse_pointer` attribute for +A new :attr:`~ipaddress.IPv4Network.reverse_pointer` attribute for the :class:`~ipaddress.IPv4Network` and :class:`~ipaddress.IPv6Network` classes returns the name of the reverse DNS PTR record:: @@ -1323,7 +1323,7 @@ --------- A new :func:`~linecache.lazycache` function can be used to capture information -about a non-file based module to permit getting its lines later via +about a non-file-based module to permit getting its lines later via :func:`~linecache.getline`. This avoids doing I/O until a line is actually needed, without having to carry the module globals around indefinitely. (Contributed by Robert Collins in :issue:`17911`.) @@ -1436,13 +1436,13 @@ of the ``BY_HANDLE_FILE_INFORMATION`` structure returned by ``GetFileInformationByHandle()``. (Contributed by Ben Hoyt in :issue:`21719`.) -The :func:`~os.urandom` function now uses ``getrandom()`` syscall on Linux 3.17 +The :func:`~os.urandom` function now uses the ``getrandom()`` syscall on Linux 3.17 or newer, and ``getentropy()`` on OpenBSD 5.6 and newer, removing the need to use ``/dev/urandom`` and avoiding failures due to potential file descriptor exhaustion. (Contributed by Victor Stinner in :issue:`22181`.) New :func:`~os.get_blocking` and :func:`~os.set_blocking` functions allow to -get and set a file descriptor blocking mode (:data:`~os.O_NONBLOCK`.) +get and set a file descriptor's blocking mode (:data:`~os.O_NONBLOCK`.) (Contributed by Victor Stinner in :issue:`22054`.) The :func:`~os.truncate` and :func:`~os.ftruncate` functions are now supported @@ -1466,8 +1466,8 @@ ------- The new :meth:`Path.samefile() ` method can be used -to check whether the path points to the same file as other path, which can be -either an another :class:`~pathlib.Path` object, or a string:: +to check whether the path points to the same file as another path, which can +be either another :class:`~pathlib.Path` object, or a string:: >>> import pathlib >>> p1 = pathlib.Path('/etc/hosts') @@ -1486,7 +1486,7 @@ Claudiu Popa in :issue:`19776`.) A new :meth:`Path.home() ` class method can be used to get -an instance of :class:`~pathlib.Path` object representing the user?s home +a :class:`~pathlib.Path` instance representing the user?s home directory. (Contributed by Victor Salgado and Mayank Tripathi in :issue:`19777`.) @@ -1539,17 +1539,17 @@ (Contributed by Serhiy Storchaka in :issue:`9179`.) -The number of capturing groups in regular expression is no longer limited by +The number of capturing groups in regular expressions is no longer limited to 100. (Contributed by Serhiy Storchaka in :issue:`22437`.) The :func:`~re.sub` and :func:`~re.subn` functions now replace unmatched groups with empty strings instead of raising an exception. (Contributed by Serhiy Storchaka in :issue:`1519638`.) -The :class:`re.error` exceptions have new attributes: +The :class:`re.error` exceptions have new attributes, :attr:`~re.error.msg`, :attr:`~re.error.pattern`, :attr:`~re.error.pos`, :attr:`~re.error.lineno`, -and :attr:`~re.error.colno` that provide better context +and :attr:`~re.error.colno`, that provide better context information about the error:: >>> re.compile(""" @@ -1607,7 +1607,7 @@ smtpd ----- -Both :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now +Both the :class:`~smtpd.SMTPServer` and :class:`~smtpd.SMTPChannel` classes now accept a *decode_data* keyword argument to determine if the ``DATA`` portion of the SMTP transaction is decoded using the ``"utf-8"`` codec or is instead provided to the @@ -1649,7 +1649,7 @@ accepts an additional debuglevel (2), which enables timestamps in debug messages. (Contributed by Gavin Chappell and Maciej Szulik in :issue:`16914`.) -Both :meth:`SMTP.sendmail() ` and +Both the :meth:`SMTP.sendmail() ` and :meth:`SMTP.send_message() ` methods now support support :rfc:`6531` (SMTPUTF8). (Contributed by Milan Oberkirch and R. David Murray in :issue:`22027`.) @@ -1658,7 +1658,7 @@ sndhdr ------ -:func:`~sndhdr.what` and :func:`~sndhdr.whathdr` functions now return +The :func:`~sndhdr.what` and :func:`~sndhdr.whathdr` functions now return a :func:`~collections.namedtuple`. (Contributed by Claudiu Popa in :issue:`18615`.) @@ -1671,7 +1671,7 @@ A new :meth:`socket.sendfile() ` method allows to send a file over a socket by using the high-performance :func:`os.sendfile` -function on UNIX resulting in uploads being from 2 to 3 times faster than when +function on UNIX, resulting in uploads being from 2 to 3 times faster than when using plain :meth:`socket.send() `. (Contributed by Giampaolo Rodola' in :issue:`17552`.) @@ -1682,7 +1682,7 @@ The *backlog* argument of the :meth:`socket.listen() ` method is now optional. By default it is set to -:data:`SOMAXCONN ` or to ``128`` whichever is less. +:data:`SOMAXCONN ` or to ``128``, whichever is less. (Contributed by Charles-Fran?ois Natali in :issue:`21455`.) @@ -1698,7 +1698,7 @@ The new :class:`~ssl.SSLObject` class has been added to provide SSL protocol support for cases when the network I/O capabilities of :class:`~ssl.SSLSocket` -are not necessary or suboptimal. ``SSLObject`` represents +are not necessary or are suboptimal. ``SSLObject`` represents an SSL protocol instance, but does not implement any network I/O methods, and instead provides a memory buffer interface. The new :class:`~ssl.MemoryBIO` class can be used to pass data between Python and an SSL protocol instance. @@ -1716,8 +1716,8 @@ (Contributed by Benjamin Peterson in :issue:`20188`.) -Where OpenSSL support is present, :mod:`ssl` module now implements -*Application-Layer Protocol Negotiation* TLS extension as described +Where OpenSSL support is present, the :mod:`ssl` module now implements +the *Application-Layer Protocol Negotiation* TLS extension as described in :rfc:`7301`. The new :meth:`SSLContext.set_alpn_protocols() ` @@ -1727,7 +1727,7 @@ The new :meth:`SSLSocket.selected_alpn_protocol() ` returns the protocol that was selected during the TLS handshake. -:data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. +The :data:`~ssl.HAS_ALPN` flag indicates whether ALPN support is present. Other Changes @@ -1742,7 +1742,7 @@ (Contributed by Giampaolo Rodola' in :issue:`17552`.) The :meth:`SSLSocket.send() ` method now raises either -:exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` exception on a +the :exc:`ssl.SSLWantReadError` or :exc:`ssl.SSLWantWriteError` exception on a non-blocking socket if the operation would block. Previously, it would return ``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) @@ -1758,7 +1758,7 @@ The :meth:`SSLSocket.do_handshake() `, :meth:`SSLSocket.read() `, :meth:`SSLSocket.shutdown() `, and -:meth:`SSLSocket.write() ` methods of :class:`~ssl.SSLSocket` +:meth:`SSLSocket.write() ` methods of the :class:`~ssl.SSLSocket` class no longer reset the socket timeout every time bytes are received or sent. The socket timeout is now the maximum total duration of the method. (Contributed by Victor Stinner in :issue:`23853`.) @@ -1770,7 +1770,7 @@ sqlite3 ------- -The :class:`~sqlite3.Row` class now fully supports sequence protocol, +The :class:`~sqlite3.Row` class now fully supports the sequence protocol, in particular :func:`reversed` iteration and slice indexing. (Contributed by Claudiu Popa in :issue:`10203`; by Lucas Sinclair, Jessica McKellar, and Serhiy Storchaka in :issue:`13583`.) @@ -1824,7 +1824,7 @@ --------- The name of the user scripts directory on Windows now includes the first -two components of Python version. (Contributed by Paul Moore +two components of the Python version. (Contributed by Paul Moore in :issue:`23437`.) @@ -1834,7 +1834,7 @@ The *mode* argument of the :func:`~tarfile.open` function now accepts ``"x"`` to request exclusive creation. (Contributed by Berker Peksag in :issue:`21717`.) -:meth:`TarFile.extractall() ` and +The :meth:`TarFile.extractall() ` and :meth:`TarFile.extract() ` methods now take a keyword argument *numeric_only*. If set to ``True``, the extracted files and directories will be owned by the numeric ``uid`` and ``gid`` from the tarfile. @@ -1851,7 +1851,7 @@ threading --------- -Both :meth:`Lock.acquire() ` and +Both the :meth:`Lock.acquire() ` and :meth:`RLock.acquire() ` methods now use a monotonic clock for timeout management. (Contributed by Victor Stinner in :issue:`22043`.) @@ -1898,7 +1898,7 @@ :class:`~traceback.StackSummary`, and :class:`~traceback.FrameSummary`. (Contributed by Robert Collins in :issue:`17911`.) -Both :func:`~traceback.print_tb` and :func:`~traceback.print_stack` functions +Both the :func:`~traceback.print_tb` and :func:`~traceback.print_stack` functions now support negative values for the *limit* argument. (Contributed by Dmitry Kazakov in :issue:`22619`.) @@ -1912,8 +1912,8 @@ :term:`awaitables `. (Contributed by Yury Selivanov in :issue:`24017`.) -A new :class:`~types.CoroutineType` is the type of :term:`coroutine` objects -created by :keyword:`async def` functions. +A new type called :class:`~types.CoroutineType`, which is used for +:term:`coroutine` objects created by :keyword:`async def` functions. (Contributed by Yury Selivanov in :issue:`24400`.) @@ -1934,7 +1934,7 @@ is impossible for a package name to match the default pattern. (Contributed by Robert Collins and Barry A. Warsaw in :issue:`16662`.) -Unittest discovery errors now are exposed in +Unittest discovery errors now are exposed in the :data:`TestLoader.errors ` attribute of the :class:`~unittest.TestLoader` instance. (Contributed by Robert Collins in :issue:`19746`.) @@ -1948,7 +1948,7 @@ The :class:`~unittest.mock.Mock` class has the following improvements: -* Class constructor has a new *unsafe* parameter, which causes mock +* The class constructor has a new *unsafe* parameter, which causes mock objects to raise :exc:`AttributeError` on attribute names starting with ``"assert"``. (Contributed by Kushal Das in :issue:`21238`.) @@ -2006,10 +2006,10 @@ ------ The :class:`client.ServerProxy ` class now supports -:term:`context manager` protocol. +the :term:`context manager` protocol. (Contributed by Claudiu Popa in :issue:`20627`.) -:class:`client.ServerProxy ` constructor now accepts +The :class:`client.ServerProxy ` constructor now accepts an optional :class:`ssl.SSLContext` instance. (Contributed by Alex Gaynor in :issue:`22960`.) @@ -2039,7 +2039,7 @@ Other module-level changes ========================== -Many functions in :mod:`mmap`, :mod:`ossaudiodev`, :mod:`socket`, +Many functions in the :mod:`mmap`, :mod:`ossaudiodev`, :mod:`socket`, :mod:`ssl`, and :mod:`codecs` modules now accept writable :term:`bytes-like objects `. (Contributed by Serhiy Storchaka in :issue:`23001`.) @@ -2098,7 +2098,7 @@ improvement in some benchmarks. (Contributed by Antoine Pitrou in :issue:`22847`.) -Objects from :mod:`random` module now use 50% less memory on 64-bit +Objects from the :mod:`random` module now use 50% less memory on 64-bit builds. (Contributed by Serhiy Storchaka in :issue:`23488`.) The :func:`property` getter calls are up to 25% faster. @@ -2108,7 +2108,7 @@ (Contributed by Stefan Behnel in :issue:`22464`.) String methods :meth:`~str.find`, :meth:`~str.rfind`, :meth:`~str.split`, -:meth:`~str.partition` and :keyword:`in` string operator are now significantly +:meth:`~str.partition` and the :keyword:`in` string operator are now significantly faster for searching 1-character substrings. (Contributed by Serhiy Storchaka in :issue:`23573`.) @@ -2154,14 +2154,14 @@ (Contributed by Benjamin Peterson in :issue:`21176`. See also :pep:`465` for details.) -The :c:member:`PyTypeObject.tp_finalize` slot is now part of stable ABI. +The :c:member:`PyTypeObject.tp_finalize` slot is now part of the stable ABI. Windows builds now require Microsoft Visual C++ 14.0, which is available as part of `Visual Studio 2015 `_. -Extension modules now include platform information tag in their filename on +Extension modules now include a platform information tag in their filename on some platforms (the tag is optional, and CPython will import extensions without -it; although if the tag is present and mismatched, the extension won't be +it, although if the tag is present and mismatched, the extension won't be loaded): * On Linux, extension module filenames end with @@ -2217,7 +2217,7 @@ Deprecated Python Behavior -------------------------- -Raising :exc:`StopIteration` exception inside a generator will now generate a silent +Raising the :exc:`StopIteration` exception inside a generator will now generate a silent :exc:`PendingDeprecationWarning`, which will become a non-silent deprecation warning in Python 3.6 and will trigger a :exc:`RuntimeError` in Python 3.7. See :ref:`PEP 479: Change StopIteration handling inside generators ` @@ -2276,7 +2276,7 @@ :func:`~inspect.getargvalues`, :func:`~inspect.getcallargs`, :func:`~inspect.getargvalues`, :func:`~inspect.formatargspec`, and :func:`~inspect.formatargvalues` functions are deprecated in favor of -:func:`inspect.signature` API. +the :func:`inspect.signature` API. (Contributed by Yury Selivanov in :issue:`20438`.) Use of :const:`re.LOCALE` flag with str patterns or :const:`re.ASCII` is now @@ -2354,7 +2354,7 @@ on a non-blocking socket if the operation would block. Previously, it would return ``0``. (Contributed by Nikolaus Rath in :issue:`20951`.) -* The ``__name__`` attribute of generator is now set from the function name, +* The ``__name__`` attribute of generators is now set from the function name, instead of being set from the code name. Use ``gen.gi_code.co_name`` to retrieve the code name. Generators also have a new ``__qualname__`` attribute, the qualified name, which is now used for the representation @@ -2376,7 +2376,7 @@ * If the current directory is set to a directory that no longer exists then :exc:`FileNotFoundError` will no longer be raised and instead :meth:`~importlib.machinery.FileFinder.find_spec` will return ``None`` - **without** caching ``None`` in :data:`sys.path_importer_cache` which is + **without** caching ``None`` in :data:`sys.path_importer_cache`, which is different than the typical case (:issue:`22834`). * HTTP status code and messages from :mod:`http.client` and :mod:`http.server` @@ -2395,7 +2395,7 @@ * The :func:`re.split` function always ignored empty pattern matches, so the ``"x*"`` pattern worked the same as ``"x+"``, and the ``"\b"`` pattern never worked. Now :func:`re.split` raises a warning if the pattern could match - an empty string. For compatibility use patterns that never match an empty + an empty string. For compatibility, use patterns that never match an empty string (e.g. ``"x+"`` instead of ``"x*"``). Patterns that could only match an empty string (such as ``"\b"``) now raise an error. (Contributed by Serhiy Storchaka in :issue:`22818`.) @@ -2431,9 +2431,9 @@ * The ``pygettext.py`` Tool now uses the standard +NNNN format for timezones in the POT-Creation-Date header. -* The :mod:`smtplib` module now uses :data:`sys.stderr` instead of previous - module level :data:`stderr` variable for debug output. If your (test) - program depends on patching the module level variable to capture the debug +* The :mod:`smtplib` module now uses :data:`sys.stderr` instead of the previous + module-level :data:`stderr` variable for debug output. If your (test) + program depends on patching the module-level variable to capture the debug output, you will need to update it to capture sys.stderr instead. * The :meth:`str.startswith` and :meth:`str.endswith` methods no longer return @@ -2471,11 +2471,12 @@ (Contributed by Serhiy Storchaka in :issue:`22453`.) * Because the lack of the :attr:`__module__` attribute breaks pickling and - introspection, a deprecation warning now is raised for builtin type without - the :attr:`__module__` attribute. Would be an AttributeError in future. + introspection, a deprecation warning is now raised for builtin types without + the :attr:`__module__` attribute. This would be an AttributeError in + the future. (Contributed by Serhiy Storchaka in :issue:`20204`.) -* As part of :pep:`492` implementation, ``tp_reserved`` slot of +* As part of the :pep:`492` implementation, the ``tp_reserved`` slot of :c:type:`PyTypeObject` was replaced with a :c:member:`tp_as_async` slot. Refer to :ref:`coro-objects` for new types, structures and functions. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1674,7 +1674,7 @@ C API ----- -- Issue #20204: Deprecation warning is now raised for builtin type without the +- Issue #20204: Deprecation warning is now raised for builtin types without the __module__ attribute. Windows -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:09:00 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:09:00 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Adjust_grammar_and_punctua?= =?utf-8?q?tion_in_whatsnew/3=2E6=2Erst?= Message-ID: <20151114020859.109189.2982@psf.io> https://hg.python.org/cpython/rev/183386082eba changeset: 99126:183386082eba user: Martin Panter date: Sat Nov 14 01:29:17 2015 +0000 summary: Adjust grammar and punctuation in whatsnew/3.6.rst files: Doc/whatsnew/3.6.rst | 22 +++++++++++----------- Misc/NEWS | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -98,8 +98,8 @@ datetime -------- -:meth:`datetime.strftime ` and -:meth:`date.strftime ` methods now support ISO 8601 date +The :meth:`datetime.strftime() ` and +:meth:`date.strftime() ` methods now support ISO 8601 date directives ``%G``, ``%u`` and ``%V``. (Contributed by Ashley Anderson in :issue:`12006`.) @@ -107,17 +107,17 @@ pickle ------ -Objects that need calling ``__new__`` with keyword arguments, can now be pickled +Objects that need calling ``__new__`` with keyword arguments can now be pickled using :ref:`pickle protocols ` older than protocol version 4. Protocol version 4 already supports this case. (Contributed by Serhiy Storchaka in :issue:`24164`.) -rlcomplete ----------- +rlcompleter +----------- Private and special attribute names now are omitted unless the prefix starts -with underscores. A space or a colon can be added after completed keyword. +with underscores. A space or a colon is added after some completed keywords. (Contributed by Serhiy Storchaka in :issue:`25011` and :issue:`25209`.) Names of most attributes listed by :func:`dir` are now completed. @@ -128,7 +128,7 @@ urllib.robotparser ------------------ -:class:`~urllib.robotparser.RobotFileParser` now supports ``Crawl-delay`` and +:class:`~urllib.robotparser.RobotFileParser` now supports the ``Crawl-delay`` and ``Request-rate`` extensions. (Contributed by Nikolay Bogoychev in :issue:`16099`.) @@ -136,18 +136,18 @@ Optimizations ============= -* The ASCII decoder is now up to 60 times as fast for error handlers: +* The ASCII decoder is now up to 60 times as fast for error handlers ``surrogateescape``, ``ignore`` and ``replace`` (Contributed by Victor Stinner in :issue:`24870`). * The ASCII and the Latin1 encoders are now up to 3 times as fast for the - error ``surrogateescape`` (Contributed by Victor Stinner in :issue:`25227`). + error handler ``surrogateescape`` (Contributed by Victor Stinner in :issue:`25227`). -* The UTF-8 encoder is now up to 75 times as fast for error handlers: +* The UTF-8 encoder is now up to 75 times as fast for error handlers ``ignore``, ``replace``, ``surrogateescape``, ``surrogatepass`` (Contributed by Victor Stinner in :issue:`25267`). -* The UTF-8 decoder is now up to 15 times as fast for error handlers: +* The UTF-8 decoder is now up to 15 times as fast for error handlers ``ignore``, ``replace`` and ``surrogateescape`` (Contributed by Victor Stinner in :issue:`25301`). diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -191,10 +191,10 @@ - Issue #25203: Failed readline.set_completer_delims() no longer left the module in inconsistent state. -- Issue #25011: rlcomplete now omits private and special attribute names unless +- Issue #25011: rlcompleter now omits private and special attribute names unless the prefix starts with underscores. -- Issue #25209: rlcomplete now can add a space or a colon after completed keyword. +- Issue #25209: rlcompleter now can add a space or a colon after completed keyword. - Issue #22241: timezone.utc name is now plain 'UTC', not 'UTC-00:00'. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 13 21:09:00 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 02:09:00 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_typo_and_grammar_fixes_from_3=2E4_into_3=2E5?= Message-ID: <20151114020859.37460.63208@psf.io> https://hg.python.org/cpython/rev/186ac463cd72 changeset: 99123:186ac463cd72 branch: 3.5 parent: 99116:808279e14700 parent: 99122:c3282d91055f user: Martin Panter date: Sat Nov 14 01:14:25 2015 +0000 summary: Merge typo and grammar fixes from 3.4 into 3.5 files: Doc/library/ast.rst | 2 +- Doc/library/copy.rst | 4 ++-- Doc/library/ftplib.rst | 4 ++-- Doc/library/urllib.request.rst | 2 +- Lib/doctest.py | 2 +- Lib/http/cookiejar.py | 8 ++++---- Lib/test/test_argparse.py | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst --- a/Doc/library/ast.rst +++ b/Doc/library/ast.rst @@ -104,7 +104,7 @@ :mod:`ast` Helpers ------------------ -Apart from the node classes, :mod:`ast` module defines these utility functions +Apart from the node classes, the :mod:`ast` module defines these utility functions and classes for traversing abstract syntax trees: .. function:: parse(source, filename='', mode='exec') diff --git a/Doc/library/copy.rst b/Doc/library/copy.rst --- a/Doc/library/copy.rst +++ b/Doc/library/copy.rst @@ -67,8 +67,8 @@ Classes can use the same interfaces to control copying that they use to control pickling. See the description of module :mod:`pickle` for information on these -methods. In fact, :mod:`copy` module uses the registered pickle functions from -:mod:`copyreg` module. +methods. In fact, the :mod:`copy` module uses the registered +pickle functions from the :mod:`copyreg` module. .. index:: single: __copy__() (copy protocol) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -418,8 +418,8 @@ .. method:: FTP_TLS.auth() - Set up secure control connection by using TLS or SSL, depending on what - specified in :meth:`ssl_version` attribute. + Set up a secure control connection by using TLS or SSL, depending on what + is specified in the :attr:`ssl_version` attribute. .. versionchanged:: 3.4 The method now supports hostname check with diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -1168,7 +1168,7 @@ #!/usr/bin/env python import sys data = sys.stdin.read() - print('Content-type: text-plain\n\nGot Data: "%s"' % data) + print('Content-type: text/plain\n\nGot Data: "%s"' % data) Here is an example of doing a ``PUT`` request using :class:`Request`:: diff --git a/Lib/doctest.py b/Lib/doctest.py --- a/Lib/doctest.py +++ b/Lib/doctest.py @@ -1575,7 +1575,7 @@ # If `want` contains hex-escaped character such as "\u1234", # then `want` is a string of six characters(e.g. [\,u,1,2,3,4]). - # On the other hand, `got` could be an another sequence of + # On the other hand, `got` could be another sequence of # characters such as [\u1234], so `want` and `got` should # be folded to hex-escaped ASCII string to compare. got = self._toAscii(got) diff --git a/Lib/http/cookiejar.py b/Lib/http/cookiejar.py --- a/Lib/http/cookiejar.py +++ b/Lib/http/cookiejar.py @@ -423,10 +423,10 @@ Takes a list of lists of (key, value) pairs and produces a single header value. Attribute values are quoted if needed. - >>> join_header_words([[("text/plain", None), ("charset", "iso-8859/1")]]) - 'text/plain; charset="iso-8859/1"' - >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859/1")]]) - 'text/plain, charset="iso-8859/1"' + >>> join_header_words([[("text/plain", None), ("charset", "iso-8859-1")]]) + 'text/plain; charset="iso-8859-1"' + >>> join_header_words([[("text/plain", None)], [("charset", "iso-8859-1")]]) + 'text/plain, charset="iso-8859-1"' """ headers = [] diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -3026,7 +3026,7 @@ '''Test extremely small number of columns. TestCase prevents "COLUMNS" from being too small in the tests themselves, - but we don't want any exceptions thrown in such case. Only ugly representation. + but we don't want any exceptions thrown in such cases. Only ugly representation. ''' def setUp(self): env = support.EnvironmentVarGuard() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 03:11:26 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 08:11:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_fix_build_with?= =?utf-8?q?_older_openssl_=28=2325569=29?= Message-ID: <20151114081126.14365.36710@psf.io> https://hg.python.org/cpython/rev/3b9fb8ebf44f changeset: 99127:3b9fb8ebf44f branch: 2.7 parent: 99120:7bc8f56ef1f3 user: Benjamin Peterson date: Sat Nov 14 00:09:22 2015 -0800 summary: fix build with older openssl (#25569) files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1069,7 +1069,7 @@ done: Py_XDECREF(lst); #if OPENSSL_VERSION_NUMBER < 0x10001000L - sk_DIST_POINT_free(dsp); + sk_DIST_POINT_free(dps); #endif return res; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 03:11:26 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 08:11:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_fix_build_with?= =?utf-8?q?_older_openssl_=28=2325569=29?= Message-ID: <20151114081126.37470.55301@psf.io> https://hg.python.org/cpython/rev/f13a75544b6f changeset: 99128:f13a75544b6f branch: 3.4 parent: 99122:c3282d91055f user: Benjamin Peterson date: Sat Nov 14 00:09:22 2015 -0800 summary: fix build with older openssl (#25569) files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1081,7 +1081,7 @@ done: Py_XDECREF(lst); #if OPENSSL_VERSION_NUMBER < 0x10001000L - sk_DIST_POINT_free(dsp); + sk_DIST_POINT_free(dps); #endif return res; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 03:11:27 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 08:11:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E4_=28=2325569=29?= Message-ID: <20151114081126.120356.12411@psf.io> https://hg.python.org/cpython/rev/83ea7e75605a changeset: 99129:83ea7e75605a branch: 3.5 parent: 99124:649f3721f648 parent: 99128:f13a75544b6f user: Benjamin Peterson date: Sat Nov 14 00:11:09 2015 -0800 summary: merge 3.4 (#25569) files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1121,7 +1121,7 @@ done: Py_XDECREF(lst); #if OPENSSL_VERSION_NUMBER < 0x10001000L - sk_DIST_POINT_free(dsp); + sk_DIST_POINT_free(dps); #endif return res; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 03:11:27 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 08:11:27 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41ICgjMjU1Njkp?= Message-ID: <20151114081127.14357.52045@psf.io> https://hg.python.org/cpython/rev/8ac09e46ca45 changeset: 99130:8ac09e46ca45 parent: 99126:183386082eba parent: 99129:83ea7e75605a user: Benjamin Peterson date: Sat Nov 14 00:11:19 2015 -0800 summary: merge 3.5 (#25569) files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1121,7 +1121,7 @@ done: Py_XDECREF(lst); #if OPENSSL_VERSION_NUMBER < 0x10001000L - sk_DIST_POINT_free(dsp); + sk_DIST_POINT_free(dps); #endif return res; } -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sat Nov 14 03:43:26 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 14 Nov 2015 08:43:26 +0000 Subject: [Python-checkins] Daily reference leaks (183386082eba): sum=-9 Message-ID: <20151114084326.109189.91304@psf.io> results for 183386082eba on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_collections leaked [-12, 0, 0] references, sum=-12 test_collections leaked [-6, 2, 0] memory blocks, sum=-4 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogkC48vz', '--timeout', '7200'] From python-checkins at python.org Sat Nov 14 03:55:34 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 08:55:34 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325168=3A_Temporar?= =?utf-8?q?y_timezone_and_cache_debugging?= Message-ID: <20151114085534.37476.92370@psf.io> https://hg.python.org/cpython/rev/139c18943d9b changeset: 99131:139c18943d9b user: Martin Panter date: Sat Nov 14 08:54:30 2015 +0000 summary: Issue #25168: Temporary timezone and cache debugging files: Lib/test/datetimetester.py | 11 ++++++++++- 1 files changed, 10 insertions(+), 1 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1979,7 +1979,16 @@ seconds = tzseconds hours, minutes = divmod(seconds//60, 60) dtstr = "{}{:02d}{:02d} {}".format(sign, hours, minutes, tzname) - dt = strptime(dtstr, "%z %Z") + try: + dt = strptime(dtstr, "%z %Z") + except ValueError: + import os + self.fail( + "Issue #25168 strptime() failure info:\n" + f"_TimeRE_cache['Z']={_strptime._TimeRE_cache['Z']!r}\n" + f"TZ={os.environ.get('TZ')!r}, or {os.getenv('TZ')!r} via getenv()\n" + f"_regex_cache={_strptime._regex_cache!r}\n" + ) self.assertEqual(dt.utcoffset(), timedelta(seconds=tzseconds)) self.assertEqual(dt.tzname(), tzname) # Can produce inconsistent datetime -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 07:54:09 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 12:54:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2323883=3A_Add_news?= =?utf-8?q?_listing_modules_with_new_exported_APIs?= Message-ID: <20151114125409.4685.79025@psf.io> https://hg.python.org/cpython/rev/25a7ceed79d1 changeset: 99134:25a7ceed79d1 user: Martin Panter date: Sat Nov 14 12:52:08 2015 +0000 summary: Issue #23883: Add news listing modules with new exported APIs files: Doc/whatsnew/3.6.rst | 6 ++++++ Misc/NEWS | 5 +++++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -230,6 +230,12 @@ * The :mod:`imp` module now raises a :exc:`DeprecationWarning` instead of :exc:`PendingDeprecationWarning`. +* The following modules have had missing APIs added to their :attr:`__all__` + attributes to match the documented APIs: :mod:`csv`, :mod:`enum`, + :mod:`ftplib`, :mod:`logging`, :mod:`optparse`, :mod:`threading` and + :mod:`wave`. This means they will export new symbols when ``import *`` + is used. See :issue:`23883`. + Changes in the C API -------------------- diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -85,6 +85,11 @@ Library ------- +- Issue #23883: Added missing APIs to __all__ to match the documented APIs + for the following modules: csv, enum, ftplib, logging, optparse, threading + and wave. Also added a test.support.check__all__() helper. Patches by + Jacek Ko?odziej. + - Issue #25590: In the Readline completer, only call getattr() once per attribute. Also complete names of attributes such as properties and slots which are listed by dir() but not yet created on an instance. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 07:54:09 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 12:54:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2323883=3A_Add_miss?= =?utf-8?q?ing_APIs_to_=5F=5Fall=5F=5F=3B_patch_by_Jacek_Ko=C5=82odziej?= Message-ID: <20151114125409.18202.9266@psf.io> https://hg.python.org/cpython/rev/78d67bdc1142 changeset: 99133:78d67bdc1142 user: Martin Panter date: Sat Nov 14 12:46:42 2015 +0000 summary: Issue #23883: Add missing APIs to __all__; patch by Jacek Ko?odziej files: Lib/csv.py | 11 ++++--- Lib/enum.py | 2 +- Lib/ftplib.py | 3 +- Lib/logging/__init__.py | 5 ++- Lib/optparse.py | 3 +- Lib/test/test_csv.py | 6 ++++ Lib/test/test_enum.py | 7 +++++ Lib/test/test_ftplib.py | 11 +++++++- Lib/test/test_logging.py | 14 +++++++++- Lib/test/test_optparse.py | 7 +++++ Lib/test/test_pickletools.py | 33 ++++++++++++++++++++++++ Lib/test/test_threading.py | 8 +++++ Lib/test/test_wave.py | 7 +++++ Lib/threading.py | 8 +++-- Lib/wave.py | 2 +- 15 files changed, 111 insertions(+), 16 deletions(-) diff --git a/Lib/csv.py b/Lib/csv.py --- a/Lib/csv.py +++ b/Lib/csv.py @@ -13,11 +13,12 @@ from io import StringIO -__all__ = [ "QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", - "Error", "Dialect", "__doc__", "excel", "excel_tab", - "field_size_limit", "reader", "writer", - "register_dialect", "get_dialect", "list_dialects", "Sniffer", - "unregister_dialect", "__version__", "DictReader", "DictWriter" ] +__all__ = ["QUOTE_MINIMAL", "QUOTE_ALL", "QUOTE_NONNUMERIC", "QUOTE_NONE", + "Error", "Dialect", "__doc__", "excel", "excel_tab", + "field_size_limit", "reader", "writer", + "register_dialect", "get_dialect", "list_dialects", "Sniffer", + "unregister_dialect", "__version__", "DictReader", "DictWriter", + "unix_dialect"] class Dialect: """Describe a CSV dialect. diff --git a/Lib/enum.py b/Lib/enum.py --- a/Lib/enum.py +++ b/Lib/enum.py @@ -8,7 +8,7 @@ from collections import OrderedDict -__all__ = ['Enum', 'IntEnum', 'unique'] +__all__ = ['EnumMeta', 'Enum', 'IntEnum', 'unique'] def _is_descriptor(obj): diff --git a/Lib/ftplib.py b/Lib/ftplib.py --- a/Lib/ftplib.py +++ b/Lib/ftplib.py @@ -42,7 +42,8 @@ import warnings from socket import _GLOBAL_DEFAULT_TIMEOUT -__all__ = ["FTP"] +__all__ = ["FTP", "error_reply", "error_temp", "error_perm", "error_proto", + "all_errors"] # Magic number from MSG_OOB = 0x1 # Process data out of band diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -33,8 +33,9 @@ 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 'captureWarnings', 'critical', 'debug', 'disable', 'error', 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', - 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning', - 'getLogRecordFactory', 'setLogRecordFactory', 'lastResort'] + 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', + 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', + 'lastResort', 'raiseExceptions'] try: import threading diff --git a/Lib/optparse.py b/Lib/optparse.py --- a/Lib/optparse.py +++ b/Lib/optparse.py @@ -38,7 +38,8 @@ 'OptionError', 'OptionConflictError', 'OptionValueError', - 'BadOptionError'] + 'BadOptionError', + 'check_choice'] __copyright__ = """ Copyright (c) 2001-2006 Gregory P. Ward. All rights reserved. diff --git a/Lib/test/test_csv.py b/Lib/test/test_csv.py --- a/Lib/test/test_csv.py +++ b/Lib/test/test_csv.py @@ -1084,5 +1084,11 @@ self.assertEqual(fileobj.read(), expected) +class MiscTestCase(unittest.TestCase): + def test__all__(self): + extra = {'__doc__', '__version__'} + support.check__all__(self, csv, ('csv', '_csv'), extra=extra) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py --- a/Lib/test/test_enum.py +++ b/Lib/test/test_enum.py @@ -6,6 +6,7 @@ from enum import Enum, IntEnum, EnumMeta, unique from io import StringIO from pickle import dumps, loads, PicklingError, HIGHEST_PROTOCOL +from test import support # for pickle tests try: @@ -1708,5 +1709,11 @@ if failed: self.fail("result does not equal expected, see print above") + +class MiscTestCase(unittest.TestCase): + def test__all__(self): + support.check__all__(self, enum) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py --- a/Lib/test/test_ftplib.py +++ b/Lib/test/test_ftplib.py @@ -1049,10 +1049,19 @@ ftp.close() +class MiscTestCase(TestCase): + def test__all__(self): + blacklist = {'MSG_OOB', 'FTP_PORT', 'MAXLINE', 'CRLF', 'B_CRLF', + 'Error', 'parse150', 'parse227', 'parse229', 'parse257', + 'print_line', 'ftpcp', 'test'} + support.check__all__(self, ftplib, blacklist=blacklist) + + def test_main(): tests = [TestFTPClass, TestTimeouts, TestIPv6Environment, - TestTLS_FTPClassMixin, TestTLS_FTPClass] + TestTLS_FTPClassMixin, TestTLS_FTPClass, + MiscTestCase] thread_info = support.threading_setup() try: diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -4159,6 +4159,17 @@ msg = 'Record not found in event log, went back %d records' % GO_BACK self.assertTrue(found, msg=msg) + +class MiscTestCase(unittest.TestCase): + def test__all__(self): + blacklist = {'logThreads', 'logMultiprocessing', + 'logProcesses', 'currentframe', + 'PercentStyle', 'StrFormatStyle', 'StringTemplateStyle', + 'Filterer', 'PlaceHolder', 'Manager', 'RootLogger', + 'root'} + support.check__all__(self, logging, blacklist=blacklist) + + # Set the locale to the platform-dependent default. I have no idea # why the test does this, but in any case we save the current locale # first and restore it at the end. @@ -4175,7 +4186,8 @@ RotatingFileHandlerTest, LastResortTest, LogRecordTest, ExceptionTest, SysLogHandlerTest, HTTPHandlerTest, NTEventLogHandlerTest, TimedRotatingFileHandlerTest, - UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest) + UnixSocketHandlerTest, UnixDatagramHandlerTest, UnixSysLogHandlerTest, + MiscTestCase) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_optparse.py b/Lib/test/test_optparse.py --- a/Lib/test/test_optparse.py +++ b/Lib/test/test_optparse.py @@ -16,6 +16,7 @@ from test import support +import optparse from optparse import make_option, Option, \ TitledHelpFormatter, OptionParser, OptionGroup, \ SUPPRESS_USAGE, OptionError, OptionConflictError, \ @@ -1650,6 +1651,12 @@ "option -l: invalid integer value: '0x12x'") +class MiscTestCase(unittest.TestCase): + def test__all__(self): + blacklist = {'check_builtin', 'AmbiguousOptionError', 'NO_DEFAULT'} + support.check__all__(self, optparse, blacklist=blacklist) + + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_pickletools.py b/Lib/test/test_pickletools.py --- a/Lib/test/test_pickletools.py +++ b/Lib/test/test_pickletools.py @@ -4,6 +4,7 @@ from test import support from test.pickletester import AbstractPickleTests from test.pickletester import AbstractPickleModuleTests +import unittest class OptimizedPickleTests(AbstractPickleTests, AbstractPickleModuleTests): @@ -59,8 +60,40 @@ self.assertNotIn(pickle.BINPUT, pickled2) +class MiscTestCase(unittest.TestCase): + def test__all__(self): + blacklist = {'bytes_types', + 'UP_TO_NEWLINE', 'TAKEN_FROM_ARGUMENT1', + 'TAKEN_FROM_ARGUMENT4', 'TAKEN_FROM_ARGUMENT4U', + 'TAKEN_FROM_ARGUMENT8U', 'ArgumentDescriptor', + 'read_uint1', 'read_uint2', 'read_int4', 'read_uint4', + 'read_uint8', 'read_stringnl', 'read_stringnl_noescape', + 'read_stringnl_noescape_pair', 'read_string1', + 'read_string4', 'read_bytes1', 'read_bytes4', + 'read_bytes8', 'read_unicodestringnl', + 'read_unicodestring1', 'read_unicodestring4', + 'read_unicodestring8', 'read_decimalnl_short', + 'read_decimalnl_long', 'read_floatnl', 'read_float8', + 'read_long1', 'read_long4', + 'uint1', 'uint2', 'int4', 'uint4', 'uint8', 'stringnl', + 'stringnl_noescape', 'stringnl_noescape_pair', 'string1', + 'string4', 'bytes1', 'bytes4', 'bytes8', + 'unicodestringnl', 'unicodestring1', 'unicodestring4', + 'unicodestring8', 'decimalnl_short', 'decimalnl_long', + 'floatnl', 'float8', 'long1', 'long4', + 'StackObject', + 'pyint', 'pylong', 'pyinteger_or_bool', 'pybool', 'pyfloat', + 'pybytes_or_str', 'pystring', 'pybytes', 'pyunicode', + 'pynone', 'pytuple', 'pylist', 'pydict', 'pyset', + 'pyfrozenset', 'anyobject', 'markobject', 'stackslice', + 'OpcodeInfo', 'opcodes', 'code2op', + } + support.check__all__(self, pickletools, blacklist=blacklist) + + def test_main(): support.run_unittest(OptimizedPickleTests) + support.run_unittest(MiscTestCase) support.run_doctest(pickletools) diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py --- a/Lib/test/test_threading.py +++ b/Lib/test/test_threading.py @@ -18,6 +18,7 @@ import subprocess from test import lock_tests +from test import support # Between fork() and exec(), only async-safe functions are allowed (issues @@ -1098,5 +1099,12 @@ class BarrierTests(lock_tests.BarrierTests): barriertype = staticmethod(threading.Barrier) +class MiscTestCase(unittest.TestCase): + def test__all__(self): + extra = {"ThreadError"} + blacklist = {'currentThread', 'activeCount'} + support.check__all__(self, threading, ('threading', '_thread'), + extra=extra, blacklist=blacklist) + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_wave.py b/Lib/test/test_wave.py --- a/Lib/test/test_wave.py +++ b/Lib/test/test_wave.py @@ -1,6 +1,7 @@ from test.support import TESTFN import unittest from test import audiotests +from test import support from audioop import byteswap import sys import wave @@ -103,5 +104,11 @@ frames = byteswap(frames, 4) +class MiscTestCase(unittest.TestCase): + def test__all__(self): + blacklist = {'WAVE_FORMAT_PCM'} + support.check__all__(self, wave, blacklist=blacklist) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/threading.py b/Lib/threading.py --- a/Lib/threading.py +++ b/Lib/threading.py @@ -22,9 +22,11 @@ # with the multiprocessing module, which doesn't provide the old # Java inspired names. -__all__ = ['active_count', 'Condition', 'current_thread', 'enumerate', 'Event', - 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', 'Barrier', - 'Timer', 'ThreadError', 'setprofile', 'settrace', 'local', 'stack_size'] +__all__ = ['get_ident', 'active_count', 'Condition', 'current_thread', + 'enumerate', 'main_thread', 'TIMEOUT_MAX', + 'Event', 'Lock', 'RLock', 'Semaphore', 'BoundedSemaphore', 'Thread', + 'Barrier', 'BrokenBarrierError', 'Timer', 'ThreadError', + 'setprofile', 'settrace', 'local', 'stack_size'] # Rename some stuff so "from threading import *" is safe _start_new_thread = _thread.start_new_thread diff --git a/Lib/wave.py b/Lib/wave.py --- a/Lib/wave.py +++ b/Lib/wave.py @@ -73,7 +73,7 @@ import builtins -__all__ = ["open", "openfp", "Error"] +__all__ = ["open", "openfp", "Error", "Wave_read", "Wave_write"] class Error(Exception): pass -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 07:54:09 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 14 Nov 2015 12:54:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2323883=3A_Add_test?= =?utf-8?b?LnN1cHBvcnQuY2hlY2tfX2FsbF9fKCkgYW5kIHRlc3QgZ2V0dGV4dC5fX2Fs?= =?utf-8?b?bF9f?= Message-ID: <20151114125409.109179.24199@psf.io> https://hg.python.org/cpython/rev/f8fa7bc837a3 changeset: 99132:f8fa7bc837a3 user: Martin Panter date: Sat Nov 14 11:47:00 2015 +0000 summary: Issue #23883: Add test.support.check__all__() and test gettext.__all__ Patches by Jacek Ko?odziej. files: Doc/library/test.rst | 42 ++++++++++++++++ Lib/test/support/__init__.py | 61 ++++++++++++++++++++++++ Lib/test/test_gettext.py | 6 ++ Lib/test/test_support.py | 22 ++++++++ Misc/ACKS | 1 + 5 files changed, 132 insertions(+), 0 deletions(-) diff --git a/Doc/library/test.rst b/Doc/library/test.rst --- a/Doc/library/test.rst +++ b/Doc/library/test.rst @@ -580,6 +580,48 @@ .. versionadded:: 3.5 +.. function:: check__all__(test_case, module, name_of_module=None, extra=(), blacklist=()) + + Assert that the ``__all__`` variable of *module* contains all public names. + + The module's public names (its API) are detected automatically + based on whether they match the public name convention and were defined in + *module*. + + The *name_of_module* argument can specify (as a string or tuple thereof) what + module(s) an API could be defined in in order to be detected as a public + API. One case for this is when *module* imports part of its public API from + other modules, possibly a C backend (like ``csv`` and its ``_csv``). + + The *extra* argument can be a set of names that wouldn't otherwise be automatically + detected as "public", like objects without a proper ``__module__`` + attribute. If provided, it will be added to the automatically detected ones. + + The *blacklist* argument can be a set of names that must not be treated as part of + the public API even though their names indicate otherwise. + + Example use:: + + import bar + import foo + import unittest + from test import support + + class MiscTestCase(unittest.TestCase): + def test__all__(self): + support.check__all__(self, foo) + + class OtherTestCase(unittest.TestCase): + def test__all__(self): + extra = {'BAR_CONST', 'FOO_CONST'} + blacklist = {'baz'} # Undocumented name. + # bar imports part of its API from _bar. + support.check__all__(self, bar, ('bar', '_bar'), + extra=extra, blacklist=blacklist) + + .. versionadded:: 3.6 + + The :mod:`test.support` module defines the following classes: .. class:: TransientResource(exc, **kwargs) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -26,6 +26,7 @@ import sysconfig import tempfile import time +import types import unittest import urllib.error import warnings @@ -89,6 +90,7 @@ "bigmemtest", "bigaddrspacetest", "cpython_only", "get_attribute", "requires_IEEE_754", "skip_unless_xattr", "requires_zlib", "anticipate_failure", "load_package_tests", "detect_api_mismatch", + "check__all__", # sys "is_jython", "check_impl_detail", # network @@ -2199,6 +2201,65 @@ return missing_items +def check__all__(test_case, module, name_of_module=None, extra=(), + blacklist=()): + """Assert that the __all__ variable of 'module' contains all public names. + + The module's public names (its API) are detected automatically based on + whether they match the public name convention and were defined in + 'module'. + + The 'name_of_module' argument can specify (as a string or tuple thereof) + what module(s) an API could be defined in in order to be detected as a + public API. One case for this is when 'module' imports part of its public + API from other modules, possibly a C backend (like 'csv' and its '_csv'). + + The 'extra' argument can be a set of names that wouldn't otherwise be + automatically detected as "public", like objects without a proper + '__module__' attriubute. If provided, it will be added to the + automatically detected ones. + + The 'blacklist' argument can be a set of names that must not be treated + as part of the public API even though their names indicate otherwise. + + Usage: + import bar + import foo + import unittest + from test import support + + class MiscTestCase(unittest.TestCase): + def test__all__(self): + support.check__all__(self, foo) + + class OtherTestCase(unittest.TestCase): + def test__all__(self): + extra = {'BAR_CONST', 'FOO_CONST'} + blacklist = {'baz'} # Undocumented name. + # bar imports part of its API from _bar. + support.check__all__(self, bar, ('bar', '_bar'), + extra=extra, blacklist=blacklist) + + """ + + if name_of_module is None: + name_of_module = (module.__name__, ) + elif isinstance(name_of_module, str): + name_of_module = (name_of_module, ) + + expected = set(extra) + + for name in dir(module): + if name.startswith('_') or name in blacklist: + continue + obj = getattr(module, name) + if (getattr(obj, '__module__', None) in name_of_module or + (not hasattr(obj, '__module__') and + not isinstance(obj, types.ModuleType))): + expected.add(name) + test_case.assertCountEqual(module.__all__, expected) + + class SuppressCrashReport: """Try to prevent a crash report from popping up. diff --git a/Lib/test/test_gettext.py b/Lib/test/test_gettext.py --- a/Lib/test/test_gettext.py +++ b/Lib/test/test_gettext.py @@ -440,6 +440,12 @@ self.assertEqual(t.__class__, DummyGNUTranslations) +class MiscTestCase(unittest.TestCase): + def test__all__(self): + blacklist = {'c2py', 'ENOENT'} + support.check__all__(self, gettext, blacklist=blacklist) + + def test_main(): support.run_unittest(__name__) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -312,6 +312,28 @@ self.OtherClass, self.RefClass, ignore=ignore) self.assertEqual(set(), missing_items) + def test_check__all__(self): + extra = {'tempdir'} + blacklist = {'template'} + support.check__all__(self, + tempfile, + extra=extra, + blacklist=blacklist) + + extra = {'TextTestResult', 'installHandler'} + blacklist = {'load_tests', "TestProgram", "BaseTestSuite"} + + support.check__all__(self, + unittest, + ("unittest.result", "unittest.case", + "unittest.suite", "unittest.loader", + "unittest.main", "unittest.runner", + "unittest.signals"), + extra=extra, + blacklist=blacklist) + + self.assertRaises(AssertionError, support.check__all__, self, unittest) + # XXX -follows a list of untested API # make_legacy_pyc # is_resource_enabled diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -765,6 +765,7 @@ Marko Kohtala Vajrasky Kok Guido Kollerie +Jacek Ko?odziej Jacek Konieczny ???? ????????? Arkady Koplyarov -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 08:14:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 14 Nov 2015 13:14:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325388=3A_Fixed_tokenizer_crash_when_processing_undeco?= =?utf-8?q?dable_source_code?= Message-ID: <20151114131458.31745.18260@psf.io> https://hg.python.org/cpython/rev/e4a69eb34ad7 changeset: 99136:e4a69eb34ad7 branch: 3.5 parent: 99129:83ea7e75605a parent: 99135:73da4fd7542b user: Serhiy Storchaka date: Sat Nov 14 15:11:17 2015 +0200 summary: Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. files: Lib/test/test_compile.py | 10 ++++++++++ Misc/NEWS | 3 +++ Parser/tokenizer.c | 14 ++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -516,6 +516,16 @@ res = script_helper.run_python_until_end(fn)[0] self.assertIn(b"Non-UTF-8", res.err) + def test_yet_more_evil_still_undecodable(self): + # Issue #25388 + src = b"#\x00\n#\xfd\n" + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, "bad.py") + with open(fn, "wb") as fp: + fp.write(src) + res = script_helper.run_python_until_end(fn)[0] + self.assertIn(b"Non-UTF-8", res.err) + @support.cpython_only def test_compiler_recursion_limit(self): # Expected limit is sys.getrecursionlimit() * the scaling factor diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25388: Fixed tokenizer crash when processing undecodable source code + with a null byte. + - Issue #25462: The hash of the key now is calculated only once in most operations in C implementation of OrderedDict. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -196,7 +196,8 @@ tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ PyMem_FREE(tok->buf); - tok->buf = NULL; + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_DECODE; return NULL; /* as if it were EOF */ } @@ -952,11 +953,6 @@ } buflen = PyBytes_GET_SIZE(u); buf = PyBytes_AS_STRING(u); - if (!buf) { - Py_DECREF(u); - tok->done = E_DECODE; - return EOF; - } newtok = PyMem_MALLOC(buflen+1); strcpy(newtok, buf); Py_DECREF(u); @@ -998,7 +994,6 @@ if (tok->buf != NULL) PyMem_FREE(tok->buf); tok->buf = newtok; - tok->line_start = tok->buf; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); @@ -1021,7 +1016,8 @@ } if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), tok) == NULL) { - tok->done = E_EOF; + if (!tok->decoding_erred) + tok->done = E_EOF; done = 1; } else { @@ -1055,6 +1051,8 @@ return EOF; } tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->line_start = tok->cur; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; tok->start = curstart < 0 ? NULL : -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 08:14:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 14 Nov 2015 13:14:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Mzg4?= =?utf-8?q?=3A_Fixed_tokenizer_crash_when_processing_undecodable_source_co?= =?utf-8?q?de?= Message-ID: <20151114131458.109181.87364@psf.io> https://hg.python.org/cpython/rev/73da4fd7542b changeset: 99135:73da4fd7542b branch: 3.4 parent: 99128:f13a75544b6f user: Serhiy Storchaka date: Sat Nov 14 15:10:35 2015 +0200 summary: Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. files: Lib/test/test_compile.py | 10 ++++++++++ Misc/NEWS | 3 +++ Parser/tokenizer.c | 14 ++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -504,6 +504,16 @@ res = script_helper.run_python_until_end(fn)[0] self.assertIn(b"Non-UTF-8", res.err) + def test_yet_more_evil_still_undecodable(self): + # Issue #25388 + src = b"#\x00\n#\xfd\n" + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, "bad.py") + with open(fn, "wb") as fp: + fp.write(src) + res = script_helper.run_python_until_end(fn)[0] + self.assertIn(b"Non-UTF-8", res.err) + @support.cpython_only def test_compiler_recursion_limit(self): # Expected limit is sys.getrecursionlimit() * the scaling factor diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25388: Fixed tokenizer crash when processing undecodable source code + with a null byte. + - Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -187,7 +187,8 @@ tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ PyMem_FREE(tok->buf); - tok->buf = NULL; + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_DECODE; return NULL; /* as if it were EOF */ } @@ -943,11 +944,6 @@ } buflen = PyBytes_GET_SIZE(u); buf = PyBytes_AS_STRING(u); - if (!buf) { - Py_DECREF(u); - tok->done = E_DECODE; - return EOF; - } newtok = PyMem_MALLOC(buflen+1); strcpy(newtok, buf); Py_DECREF(u); @@ -989,7 +985,6 @@ if (tok->buf != NULL) PyMem_FREE(tok->buf); tok->buf = newtok; - tok->line_start = tok->buf; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); @@ -1012,7 +1007,8 @@ } if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), tok) == NULL) { - tok->done = E_EOF; + if (!tok->decoding_erred) + tok->done = E_EOF; done = 1; } else { @@ -1046,6 +1042,8 @@ return EOF; } tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->line_start = tok->cur; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; tok->start = curstart < 0 ? NULL : -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 08:14:59 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 14 Nov 2015 13:14:59 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325388=3A_Fixed_tokenizer_crash_when_processing_?= =?utf-8?q?undecodable_source_code?= Message-ID: <20151114131459.4669.54@psf.io> https://hg.python.org/cpython/rev/ea0c4b811eae changeset: 99137:ea0c4b811eae parent: 99134:25a7ceed79d1 parent: 99136:e4a69eb34ad7 user: Serhiy Storchaka date: Sat Nov 14 15:12:04 2015 +0200 summary: Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. files: Lib/test/test_compile.py | 10 ++++++++++ Misc/NEWS | 3 +++ Parser/tokenizer.c | 14 ++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -516,6 +516,16 @@ res = script_helper.run_python_until_end(fn)[0] self.assertIn(b"Non-UTF-8", res.err) + def test_yet_more_evil_still_undecodable(self): + # Issue #25388 + src = b"#\x00\n#\xfd\n" + with tempfile.TemporaryDirectory() as tmpd: + fn = os.path.join(tmpd, "bad.py") + with open(fn, "wb") as fp: + fp.write(src) + res = script_helper.run_python_until_end(fn)[0] + self.assertIn(b"Non-UTF-8", res.err) + @support.cpython_only def test_compiler_recursion_limit(self): # Expected limit is sys.getrecursionlimit() * the scaling factor diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25388: Fixed tokenizer crash when processing undecodable source code + with a null byte. + - Issue #25462: The hash of the key now is calculated only once in most operations in C implementation of OrderedDict. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -196,7 +196,8 @@ tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ PyMem_FREE(tok->buf); - tok->buf = NULL; + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_DECODE; return NULL; /* as if it were EOF */ } @@ -952,11 +953,6 @@ } buflen = PyBytes_GET_SIZE(u); buf = PyBytes_AS_STRING(u); - if (!buf) { - Py_DECREF(u); - tok->done = E_DECODE; - return EOF; - } newtok = PyMem_MALLOC(buflen+1); strcpy(newtok, buf); Py_DECREF(u); @@ -998,7 +994,6 @@ if (tok->buf != NULL) PyMem_FREE(tok->buf); tok->buf = newtok; - tok->line_start = tok->buf; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); @@ -1021,7 +1016,8 @@ } if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), tok) == NULL) { - tok->done = E_EOF; + if (!tok->decoding_erred) + tok->done = E_EOF; done = 1; } else { @@ -1055,6 +1051,8 @@ return EOF; } tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->line_start = tok->cur; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; tok->start = curstart < 0 ? NULL : -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 08:15:01 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 14 Nov 2015 13:15:01 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Mzg4?= =?utf-8?q?=3A_Fixed_tokenizer_hang_when_processing_undecodable_source_cod?= =?utf-8?q?e?= Message-ID: <20151114131459.37488.19152@psf.io> https://hg.python.org/cpython/rev/8e472cc258ec changeset: 99138:8e472cc258ec branch: 2.7 parent: 99127:3b9fb8ebf44f user: Serhiy Storchaka date: Sat Nov 14 15:14:29 2015 +0200 summary: Issue #25388: Fixed tokenizer hang when processing undecodable source code with a null byte. files: Lib/test/test_compile.py | 16 ++++++++++++++++ Misc/NEWS | 3 +++ Parser/tokenizer.c | 9 ++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -3,6 +3,9 @@ import sys import _ast from test import test_support +from test import script_helper +import os +import tempfile import textwrap class TestSpecifics(unittest.TestCase): @@ -555,6 +558,19 @@ ast.body = [_ast.BoolOp()] self.assertRaises(TypeError, compile, ast, '', 'exec') + def test_yet_more_evil_still_undecodable(self): + # Issue #25388 + src = b"#\x00\n#\xfd\n" + tmpd = tempfile.mkdtemp() + try: + fn = os.path.join(tmpd, "bad.py") + with open(fn, "wb") as fp: + fp.write(src) + rc, out, err = script_helper.assert_python_failure(fn) + finally: + test_support.rmtree(tmpd) + self.assertIn(b"Non-ASCII", err) + class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25388: Fixed tokenizer hang when processing undecodable source code + with a null byte. + - Issue #22995: Default implementation of __reduce__ and __reduce_ex__ now rejects builtin types with not defined __new__. diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c --- a/Parser/tokenizer.c +++ b/Parser/tokenizer.c @@ -169,7 +169,8 @@ tok->decoding_erred = 1; if (tok->fp != NULL && tok->buf != NULL) /* see PyTokenizer_Free */ PyMem_FREE(tok->buf); - tok->buf = NULL; + tok->buf = tok->cur = tok->end = tok->inp = tok->start = NULL; + tok->done = E_DECODE; return NULL; /* as if it were EOF */ } @@ -921,7 +922,6 @@ if (tok->buf != NULL) PyMem_FREE(tok->buf); tok->buf = newtok; - tok->line_start = tok->buf; tok->cur = tok->buf; tok->line_start = tok->buf; tok->inp = strchr(tok->buf, '\0'); @@ -944,7 +944,8 @@ } if (decoding_fgets(tok->buf, (int)(tok->end - tok->buf), tok) == NULL) { - tok->done = E_EOF; + if (!tok->decoding_erred) + tok->done = E_EOF; done = 1; } else { @@ -978,6 +979,8 @@ return EOF; } tok->buf = newbuf; + tok->cur = tok->buf + cur; + tok->line_start = tok->cur; tok->inp = tok->buf + curvalid; tok->end = tok->buf + newsize; tok->start = curstart < 0 ? NULL : -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 08:48:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 14 Nov 2015 13:48:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2324821=3A_Refactor?= =?utf-8?q?_STRINGLIB=28fastsearch=5Fmemchr=5F1char=29_and_split_it_on?= Message-ID: <20151114134853.109165.11800@psf.io> https://hg.python.org/cpython/rev/1412be96faf0 changeset: 99139:1412be96faf0 parent: 99137:ea0c4b811eae user: Serhiy Storchaka date: Sat Nov 14 15:42:17 2015 +0200 summary: Issue #24821: Refactor STRINGLIB(fastsearch_memchr_1char) and split it on STRINGLIB(find_char) and STRINGLIB(rfind_char) that can be used independedly without special preconditions. files: Objects/bytearrayobject.c | 19 +- Objects/bytesobject.c | 19 +- Objects/stringlib/fastsearch.h | 152 ++++++++++++-------- Objects/unicodeobject.c | 33 ++-- 4 files changed, 122 insertions(+), 101 deletions(-) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1159,16 +1159,15 @@ ADJUST_INDICES(start, end, len); if (end - start < sub_len) res = -1; - else if (sub_len == 1 -#ifndef HAVE_MEMRCHR - && dir > 0 -#endif - ) { - unsigned char needle = *sub; - int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; - res = stringlib_fastsearch_memchr_1char( - PyByteArray_AS_STRING(self) + start, end - start, - needle, needle, mode); + else if (sub_len == 1) { + if (dir > 0) + res = stringlib_find_char( + PyByteArray_AS_STRING(self) + start, end - start, + *sub); + else + res = stringlib_rfind_char( + PyByteArray_AS_STRING(self) + start, end - start, + *sub); if (res >= 0) res += start; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1937,16 +1937,15 @@ ADJUST_INDICES(start, end, len); if (end - start < sub_len) res = -1; - else if (sub_len == 1 -#ifndef HAVE_MEMRCHR - && dir > 0 -#endif - ) { - unsigned char needle = *sub; - int mode = (dir > 0) ? FAST_SEARCH : FAST_RSEARCH; - res = stringlib_fastsearch_memchr_1char( - PyBytes_AS_STRING(self) + start, end - start, - needle, needle, mode); + else if (sub_len == 1) { + if (dir > 0) + res = stringlib_find_char( + PyBytes_AS_STRING(self) + start, end - start, + *sub); + else + res = stringlib_rfind_char( + PyBytes_AS_STRING(self) + start, end - start, + *sub); if (res >= 0) res += start; } diff --git a/Objects/stringlib/fastsearch.h b/Objects/stringlib/fastsearch.h --- a/Objects/stringlib/fastsearch.h +++ b/Objects/stringlib/fastsearch.h @@ -32,52 +32,98 @@ #define STRINGLIB_BLOOM(mask, ch) \ ((mask & (1UL << ((ch) & (STRINGLIB_BLOOM_WIDTH -1))))) +Py_LOCAL_INLINE(Py_ssize_t) +STRINGLIB(find_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) +{ + const STRINGLIB_CHAR *p, *e; + + p = s; + e = s + n; + if (n > 10) { +#if STRINGLIB_SIZEOF_CHAR == 1 + p = memchr(s, ch, n); + if (p != NULL) + return (p - s); + return -1; +#else + /* use memchr if we can choose a needle without two many likely + false positives */ + unsigned char needle = ch & 0xff; + /* If looking for a multiple of 256, we'd have too + many false positives looking for the '\0' byte in UCS2 + and UCS4 representations. */ + if (needle != 0) { + while (p < e) { + void *candidate = memchr(p, needle, + (e - p) * sizeof(STRINGLIB_CHAR)); + if (candidate == NULL) + return -1; + p = (const STRINGLIB_CHAR *) + _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); + if (*p == ch) + return (p - s); + /* False positive */ + p++; + } + return -1; + } +#endif + } + while (p < e) { + if (*p == ch) + return (p - s); + p++; + } + return -1; +} Py_LOCAL_INLINE(Py_ssize_t) -STRINGLIB(fastsearch_memchr_1char)(const STRINGLIB_CHAR* s, Py_ssize_t n, - STRINGLIB_CHAR ch, unsigned char needle, - int mode) +STRINGLIB(rfind_char)(const STRINGLIB_CHAR* s, Py_ssize_t n, STRINGLIB_CHAR ch) { - if (mode == FAST_SEARCH) { - const STRINGLIB_CHAR *ptr = s; - const STRINGLIB_CHAR *e = s + n; - while (ptr < e) { - void *candidate = memchr((const void *) ptr, needle, (e - ptr) * sizeof(STRINGLIB_CHAR)); - if (candidate == NULL) - return -1; - ptr = (const STRINGLIB_CHAR *) _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); - if (sizeof(STRINGLIB_CHAR) == 1 || *ptr == ch) - return (ptr - s); - /* False positive */ - ptr++; - } - return -1; - } + const STRINGLIB_CHAR *p; #ifdef HAVE_MEMRCHR /* memrchr() is a GNU extension, available since glibc 2.1.91. it doesn't seem as optimized as memchr(), but is still quite - faster than our hand-written loop in FASTSEARCH below */ - else if (mode == FAST_RSEARCH) { - while (n > 0) { - const STRINGLIB_CHAR *found; - void *candidate = memrchr((const void *) s, needle, n * sizeof(STRINGLIB_CHAR)); - if (candidate == NULL) - return -1; - found = (const STRINGLIB_CHAR *) _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); - n = found - s; - if (sizeof(STRINGLIB_CHAR) == 1 || *found == ch) - return n; - /* False positive */ + faster than our hand-written loop below */ + + if (n > 10) { +#if STRINGLIB_SIZEOF_CHAR == 1 + p = memrchr(s, ch, n); + if (p != NULL) + return (p - s); + return -1; +#else + /* use memrchr if we can choose a needle without two many likely + false positives */ + unsigned char needle = ch & 0xff; + /* If looking for a multiple of 256, we'd have too + many false positives looking for the '\0' byte in UCS2 + and UCS4 representations. */ + if (needle != 0) { + while (n > 0) { + void *candidate = memrchr(s, needle, + n * sizeof(STRINGLIB_CHAR)); + if (candidate == NULL) + return -1; + p = (const STRINGLIB_CHAR *) + _Py_ALIGN_DOWN(candidate, sizeof(STRINGLIB_CHAR)); + n = p - s; + if (*p == ch) + return n; + /* False positive */ + } + return -1; } - return -1; +#endif } -#endif - else { - assert(0); /* Should never get here */ - return 0; +#endif /* HAVE_MEMRCHR */ + p = s + n; + while (p > s) { + p--; + if (*p == ch) + return (p - s); } - -#undef DO_MEMCHR + return -1; } Py_LOCAL_INLINE(Py_ssize_t) @@ -99,25 +145,11 @@ if (m <= 0) return -1; /* use special case for 1-character strings */ - if (n > 10 && (mode == FAST_SEARCH -#ifdef HAVE_MEMRCHR - || mode == FAST_RSEARCH -#endif - )) { - /* use memchr if we can choose a needle without two many likely - false positives */ - unsigned char needle; - needle = p[0] & 0xff; -#if STRINGLIB_SIZEOF_CHAR > 1 - /* If looking for a multiple of 256, we'd have too - many false positives looking for the '\0' byte in UCS2 - and UCS4 representations. */ - if (needle != 0) -#endif - return STRINGLIB(fastsearch_memchr_1char) - (s, n, p[0], needle, mode); - } - if (mode == FAST_COUNT) { + if (mode == FAST_SEARCH) + return STRINGLIB(find_char)(s, n, p[0]); + else if (mode == FAST_RSEARCH) + return STRINGLIB(rfind_char)(s, n, p[0]); + else { /* FAST_COUNT */ for (i = 0; i < n; i++) if (s[i] == p[0]) { count++; @@ -125,14 +157,6 @@ return maxcount; } return count; - } else if (mode == FAST_SEARCH) { - for (i = 0; i < n; i++) - if (s[i] == p[0]) - return i; - } else { /* FAST_RSEARCH */ - for (i = n - 1; i > -1; i--) - if (s[i] == p[0]) - return i; } return -1; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -811,27 +811,26 @@ Py_ssize_t size, Py_UCS4 ch, int direction) { - int mode = (direction == 1) ? FAST_SEARCH : FAST_RSEARCH; - switch (kind) { case PyUnicode_1BYTE_KIND: - { - Py_UCS1 ch1 = (Py_UCS1) ch; - if (ch1 == ch) - return ucs1lib_fastsearch((Py_UCS1 *) s, size, &ch1, 1, 0, mode); - else - return -1; - } + if ((Py_UCS1) ch != ch) + return -1; + if (direction > 0) + return ucs1lib_find_char((Py_UCS1 *) s, size, (Py_UCS1) ch); + else + return ucs1lib_rfind_char((Py_UCS1 *) s, size, (Py_UCS1) ch); case PyUnicode_2BYTE_KIND: - { - Py_UCS2 ch2 = (Py_UCS2) ch; - if (ch2 == ch) - return ucs2lib_fastsearch((Py_UCS2 *) s, size, &ch2, 1, 0, mode); - else - return -1; - } + if ((Py_UCS2) ch != ch) + return -1; + if (direction > 0) + return ucs2lib_find_char((Py_UCS2 *) s, size, (Py_UCS2) ch); + else + return ucs2lib_rfind_char((Py_UCS2 *) s, size, (Py_UCS2) ch); case PyUnicode_4BYTE_KIND: - return ucs4lib_fastsearch((Py_UCS4 *) s, size, &ch, 1, 0, mode); + if (direction > 0) + return ucs4lib_find_char((Py_UCS4 *) s, size, ch); + else + return ucs4lib_rfind_char((Py_UCS4 *) s, size, ch); default: assert(0); return -1; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:14 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_fix_possible_m?= =?utf-8?q?emory_lea_k_in_=5Fget=5Faia=5Furi_=28closes_=2325578=29?= Message-ID: <20151114231514.18212.95837@psf.io> https://hg.python.org/cpython/rev/bddc5491d0fb changeset: 99142:bddc5491d0fb branch: 3.4 parent: 99135:73da4fd7542b user: Benjamin Peterson date: Sat Nov 14 15:12:18 2015 -0800 summary: fix possible memory lea k in _get_aia_uri (closes #25578) files: Misc/NEWS | 2 ++ Modules/_ssl.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,8 @@ Library ------- +- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). + - Issue #25590: In the Readline completer, only call getattr() once per attribute. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -977,7 +977,10 @@ AUTHORITY_INFO_ACCESS *info; info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); - if ((info == NULL) || (sk_ACCESS_DESCRIPTION_num(info) == 0)) { + if (info == NULL) + return Py_None; + if (sk_ACCESS_DESCRIPTION_num(info) == 0) { + AUTHORITY_INFO_ACCESS_free(info); return Py_None; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:15 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_rm_trailing_ws?= Message-ID: <20151114231514.21875.52115@psf.io> https://hg.python.org/cpython/rev/017d77d001c5 changeset: 99141:017d77d001c5 branch: 2.7 user: Benjamin Peterson date: Sat Nov 14 15:12:38 2015 -0800 summary: rm trailing ws files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3433,7 +3433,7 @@ if (!tmp) { Py_INCREF(Py_None); target = Py_None; } \ else { target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ - } + } CONVERT(X509_get_default_cert_file_env(), ofile_env); CONVERT(X509_get_default_cert_file(), ofile); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:15 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41ICgjMjU1Nzgp?= Message-ID: <20151114231515.4679.21093@psf.io> https://hg.python.org/cpython/rev/858cb1538531 changeset: 99145:858cb1538531 parent: 99139:1412be96faf0 parent: 99144:6c733337afae user: Benjamin Peterson date: Sat Nov 14 15:14:58 2015 -0800 summary: merge 3.5 (#25578) files: Misc/NEWS | 2 ++ Modules/_ssl.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -255,6 +255,8 @@ - Issue #13248: Remove deprecated inspect.getargspec and inspect.getmoduleinfo functions. +- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). + - Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating ssl.SSLContext. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1017,7 +1017,10 @@ AUTHORITY_INFO_ACCESS *info; info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); - if ((info == NULL) || (sk_ACCESS_DESCRIPTION_num(info) == 0)) { + if (info == NULL) + return Py_None; + if (sk_ACCESS_DESCRIPTION_num(info) == 0) { + AUTHORITY_INFO_ACCESS_free(info); return Py_None; } @@ -3967,7 +3970,7 @@ else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ - } + } CONVERT(X509_get_default_cert_file_env(), ofile_env); CONVERT(X509_get_default_cert_file(), ofile); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:15 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_rm_trailing_ws?= Message-ID: <20151114231515.109165.59110@psf.io> https://hg.python.org/cpython/rev/41ddf2c47a18 changeset: 99143:41ddf2c47a18 branch: 3.4 user: Benjamin Peterson date: Sat Nov 14 15:12:38 2015 -0800 summary: rm trailing ws files: Modules/_ssl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -3380,7 +3380,7 @@ else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ - } + } CONVERT(X509_get_default_cert_file_env(), ofile_env); CONVERT(X509_get_default_cert_file(), ofile); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:15 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:15 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_merge_3=2E4_=28=2325578=29?= Message-ID: <20151114231515.37470.82122@psf.io> https://hg.python.org/cpython/rev/6c733337afae changeset: 99144:6c733337afae branch: 3.5 parent: 99136:e4a69eb34ad7 parent: 99143:41ddf2c47a18 user: Benjamin Peterson date: Sat Nov 14 15:14:42 2015 -0800 summary: merge 3.4 (#25578) files: Misc/NEWS | 2 ++ Modules/_ssl.c | 7 +++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -245,6 +245,8 @@ - Issue #24881: Fixed setting binary mode in Python implementation of FileIO on Windows and Cygwin. Patch from Akira Li. +- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). + - Issue #25530: Disable the vulnerable SSLv3 protocol by default when creating ssl.SSLContext. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -1017,7 +1017,10 @@ AUTHORITY_INFO_ACCESS *info; info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); - if ((info == NULL) || (sk_ACCESS_DESCRIPTION_num(info) == 0)) { + if (info == NULL) + return Py_None; + if (sk_ACCESS_DESCRIPTION_num(info) == 0) { + AUTHORITY_INFO_ACCESS_free(info); return Py_None; } @@ -3967,7 +3970,7 @@ else if ((target = PyUnicode_DecodeFSDefault(tmp)) == NULL) { \ target = PyBytes_FromString(tmp); } \ if (!target) goto error; \ - } + } CONVERT(X509_get_default_cert_file_env(), ofile_env); CONVERT(X509_get_default_cert_file(), ofile); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 14 18:15:15 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 14 Nov 2015 23:15:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_fix_possible_m?= =?utf-8?q?emory_lea_k_in_=5Fget=5Faia=5Furi_=28closes_=2325578=29?= Message-ID: <20151114231514.34147.62914@psf.io> https://hg.python.org/cpython/rev/79abea02a569 changeset: 99140:79abea02a569 branch: 2.7 parent: 99138:8e472cc258ec user: Benjamin Peterson date: Sat Nov 14 15:12:18 2015 -0800 summary: fix possible memory lea k in _get_aia_uri (closes #25578) files: Misc/NEWS | 2 ++ Modules/_ssl.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -55,6 +55,8 @@ Library ------- +- Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). + - Issue #25590: In the Readline completer, only call getattr() once per attribute. diff --git a/Modules/_ssl.c b/Modules/_ssl.c --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -965,7 +965,10 @@ AUTHORITY_INFO_ACCESS *info; info = X509_get_ext_d2i(certificate, NID_info_access, NULL, NULL); - if ((info == NULL) || (sk_ACCESS_DESCRIPTION_num(info) == 0)) { + if (info == NULL) + return Py_None; + if (sk_ACCESS_DESCRIPTION_num(info) == 0) { + AUTHORITY_INFO_ACCESS_free(info); return Py_None; } -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sun Nov 15 03:42:16 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 15 Nov 2015 08:42:16 +0000 Subject: [Python-checkins] Daily reference leaks (858cb1538531): sum=7 Message-ID: <20151115084216.21855.4584@psf.io> results for 858cb1538531 on branch "default" -------------------------------------------- test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogpnQiQH', '--timeout', '7200'] From python-checkins at python.org Sun Nov 15 21:31:55 2015 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 16 Nov 2015 02:31:55 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogRml4IGlzc3VlICM2?= =?utf-8?q?973=3A_When_we_know_a_subprocess=2EPopen_process_has_died=2C_do?= Message-ID: <20151116023155.18188.86727@psf.io> https://hg.python.org/cpython/rev/6bd3c8623bb2 changeset: 99146:6bd3c8623bb2 branch: 3.4 parent: 99143:41ddf2c47a18 user: Gregory P. Smith date: Sun Nov 15 18:19:10 2015 -0800 summary: Fix issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. files: Lib/subprocess.py | 19 ++++++++++++------- Misc/NEWS | 4 ++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1241,8 +1241,10 @@ return (stdout, stderr) def send_signal(self, sig): - """Send a signal to the process - """ + """Send a signal to the process.""" + # Don't signal a process that we know has already died. + if self.returncode is not None: + return if sig == signal.SIGTERM: self.terminate() elif sig == signal.CTRL_C_EVENT: @@ -1253,8 +1255,10 @@ raise ValueError("Unsupported signal: {}".format(sig)) def terminate(self): - """Terminates the process - """ + """Terminates the process.""" + # Don't terminate a process that we know has already died. + if self.returncode is not None: + return try: _winapi.TerminateProcess(self._handle, 1) except PermissionError: @@ -1678,9 +1682,10 @@ def send_signal(self, sig): - """Send a signal to the process - """ - os.kill(self.pid, sig) + """Send a signal to the process.""" + # Skip signalling a process that we know has already died. + if self.returncode is None: + os.kill(self.pid, sig) def terminate(self): """Terminate the process with SIGTERM diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,10 @@ Library ------- +- Issue #6973: When we know a subprocess.Popen process has died, do + not allow the send_signal(), terminate(), or kill() methods to do + anything as they could potentially signal a different process. + - Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). - Issue #25590: In the Readline completer, only call getattr() once per -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 15 21:31:56 2015 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 16 Nov 2015 02:31:56 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fix_issue_=236973=3A_When_we_know_a_subprocess=2EPopen_p?= =?utf-8?q?rocess_has_died=2C_do?= Message-ID: <20151116023156.21855.62740@psf.io> https://hg.python.org/cpython/rev/e51c46d12ec1 changeset: 99148:e51c46d12ec1 parent: 99145:858cb1538531 parent: 99147:bc907c76f054 user: Gregory P. Smith date: Sun Nov 15 18:31:34 2015 -0800 summary: Fix issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. files: Lib/subprocess.py | 19 ++++++++++++------- Misc/NEWS | 4 ++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1333,8 +1333,10 @@ return (stdout, stderr) def send_signal(self, sig): - """Send a signal to the process - """ + """Send a signal to the process.""" + # Don't signal a process that we know has already died. + if self.returncode is not None: + return if sig == signal.SIGTERM: self.terminate() elif sig == signal.CTRL_C_EVENT: @@ -1345,8 +1347,10 @@ raise ValueError("Unsupported signal: {}".format(sig)) def terminate(self): - """Terminates the process - """ + """Terminates the process.""" + # Don't terminate a process that we know has already died. + if self.returncode is not None: + return try: _winapi.TerminateProcess(self._handle, 1) except PermissionError: @@ -1754,9 +1758,10 @@ def send_signal(self, sig): - """Send a signal to the process - """ - os.kill(self.pid, sig) + """Send a signal to the process.""" + # Skip signalling a process that we know has already died. + if self.returncode is None: + os.kill(self.pid, sig) def terminate(self): """Terminate the process with SIGTERM diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -88,6 +88,10 @@ Library ------- +- Issue #6973: When we know a subprocess.Popen process has died, do + not allow the send_signal(), terminate(), or kill() methods to do + anything as they could potentially signal a different process. + - Issue #23883: Added missing APIs to __all__ to match the documented APIs for the following modules: csv, enum, ftplib, logging, optparse, threading and wave. Also added a test.support.check__all__() helper. Patches by -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 15 21:31:56 2015 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 16 Nov 2015 02:31:56 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Fix_issue_=236973=3A_When_we_know_a_subprocess=2EPopen_process?= =?utf-8?q?_has_died=2C_do?= Message-ID: <20151116023156.34165.1065@psf.io> https://hg.python.org/cpython/rev/bc907c76f054 changeset: 99147:bc907c76f054 branch: 3.5 parent: 99144:6c733337afae parent: 99146:6bd3c8623bb2 user: Gregory P. Smith date: Sun Nov 15 18:26:11 2015 -0800 summary: Fix issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. files: Lib/subprocess.py | 19 ++++++++++++------- Misc/NEWS | 4 ++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/Lib/subprocess.py b/Lib/subprocess.py --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1333,8 +1333,10 @@ return (stdout, stderr) def send_signal(self, sig): - """Send a signal to the process - """ + """Send a signal to the process.""" + # Don't signal a process that we know has already died. + if self.returncode is not None: + return if sig == signal.SIGTERM: self.terminate() elif sig == signal.CTRL_C_EVENT: @@ -1345,8 +1347,10 @@ raise ValueError("Unsupported signal: {}".format(sig)) def terminate(self): - """Terminates the process - """ + """Terminates the process.""" + # Don't terminate a process that we know has already died. + if self.returncode is not None: + return try: _winapi.TerminateProcess(self._handle, 1) except PermissionError: @@ -1754,9 +1758,10 @@ def send_signal(self, sig): - """Send a signal to the process - """ - os.kill(self.pid, sig) + """Send a signal to the process.""" + # Skip signalling a process that we know has already died. + if self.returncode is None: + os.kill(self.pid, sig) def terminate(self): """Terminate the process with SIGTERM diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -70,6 +70,10 @@ Library ------- +- Issue #6973: When we know a subprocess.Popen process has died, do + not allow the send_signal(), terminate(), or kill() methods to do + anything as they could potentially signal a different process. + - Issue #25590: In the Readline completer, only call getattr() once per attribute. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 00:29:51 2015 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 16 Nov 2015 05:29:51 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fixes_=2323564=3A_Fix_a_partially_broken_sanity_check_in?= =?utf-8?q?_the_=5Fposixsubprocess?= Message-ID: <20151116052951.14367.18128@psf.io> https://hg.python.org/cpython/rev/97e2a6810f7f changeset: 99150:97e2a6810f7f parent: 99148:e51c46d12ec1 parent: 99149:55f7a99a5433 user: Gregory P. Smith date: Sun Nov 15 21:29:43 2015 -0800 summary: Fixes #23564: Fix a partially broken sanity check in the _posixsubprocess internals regarding how fds_to_pass were passed to the child. The bug had no actual impact as subprocess.py already avoided it. files: Lib/test/test_subprocess.py | 30 +++++++++++++++++++++++- Misc/NEWS | 4 +++ Modules/_posixsubprocess.c | 3 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2312,8 +2312,6 @@ func = lambda: None gc.enable() - executable_list = "exec" # error: must be a sequence - for args, exe_list, cwd, env_list in ( (123, [b"exe"], None, [b"env"]), ([b"arg"], 123, None, [b"env"]), @@ -2331,6 +2329,34 @@ if not gc_enabled: gc.disable() + @support.cpython_only + def test_fork_exec_sorted_fd_sanity_check(self): + # Issue #23564: sanity check the fork_exec() fds_to_keep sanity check. + import _posixsubprocess + gc_enabled = gc.isenabled() + try: + gc.enable() + + for fds_to_keep in ( + (-1, 2, 3, 4, 5), # Negative number. + ('str', 4), # Not an int. + (18, 23, 42, 2**63), # Out of range. + (5, 4), # Not sorted. + (6, 7, 7, 8), # Duplicate. + ): + with self.assertRaises( + ValueError, + msg='fds_to_keep={}'.format(fds_to_keep)) as c: + _posixsubprocess.fork_exec( + [b"false"], [b"false"], + True, fds_to_keep, None, [b"env"], + -1, -1, -1, -1, + 1, 2, 3, 4, + True, True, None) + self.assertIn('fds_to_keep', str(c.exception)) + finally: + if not gc_enabled: + gc.disable() @unittest.skipUnless(mswindows, "Windows specific tests") diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess + internals regarding how fds_to_pass were passed to the child. The bug had + no actual impact as subprocess.py already avoided it. + - Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -109,10 +109,11 @@ for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) { PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx); long iter_fd = PyLong_AsLong(py_fd); - if (iter_fd < 0 || iter_fd < prev_fd || iter_fd > INT_MAX) { + if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { /* Negative, overflow, not a Long, unsorted, too big for a fd. */ return 1; } + prev_fd = iter_fd; } return 0; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 00:29:52 2015 From: python-checkins at python.org (gregory.p.smith) Date: Mon, 16 Nov 2015 05:29:52 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogRml4ZXMgIzIzNTY0?= =?utf-8?q?=3A_Fix_a_partially_broken_sanity_check_in_the_=5Fposixsubproce?= =?utf-8?q?ss?= Message-ID: <20151116052951.109173.78695@psf.io> https://hg.python.org/cpython/rev/55f7a99a5433 changeset: 99149:55f7a99a5433 branch: 3.5 parent: 99147:bc907c76f054 user: Gregory P. Smith date: Sun Nov 15 21:15:26 2015 -0800 summary: Fixes #23564: Fix a partially broken sanity check in the _posixsubprocess internals regarding how fds_to_pass were passed to the child. The bug had no actual impact as subprocess.py already avoided it. files: Lib/test/test_subprocess.py | 30 +++++++++++++++++++++++- Misc/NEWS | 4 +++ Modules/_posixsubprocess.c | 3 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -2312,8 +2312,6 @@ func = lambda: None gc.enable() - executable_list = "exec" # error: must be a sequence - for args, exe_list, cwd, env_list in ( (123, [b"exe"], None, [b"env"]), ([b"arg"], 123, None, [b"env"]), @@ -2331,6 +2329,34 @@ if not gc_enabled: gc.disable() + @support.cpython_only + def test_fork_exec_sorted_fd_sanity_check(self): + # Issue #23564: sanity check the fork_exec() fds_to_keep sanity check. + import _posixsubprocess + gc_enabled = gc.isenabled() + try: + gc.enable() + + for fds_to_keep in ( + (-1, 2, 3, 4, 5), # Negative number. + ('str', 4), # Not an int. + (18, 23, 42, 2**63), # Out of range. + (5, 4), # Not sorted. + (6, 7, 7, 8), # Duplicate. + ): + with self.assertRaises( + ValueError, + msg='fds_to_keep={}'.format(fds_to_keep)) as c: + _posixsubprocess.fork_exec( + [b"false"], [b"false"], + True, fds_to_keep, None, [b"env"], + -1, -1, -1, -1, + 1, 2, 3, 4, + True, True, None) + self.assertIn('fds_to_keep', str(c.exception)) + finally: + if not gc_enabled: + gc.disable() @unittest.skipUnless(mswindows, "Windows specific tests") diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,10 @@ Core and Builtins ----------------- +- Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess + internals regarding how fds_to_pass were passed to the child. The bug had + no actual impact as subprocess.py already avoided it. + - Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. diff --git a/Modules/_posixsubprocess.c b/Modules/_posixsubprocess.c --- a/Modules/_posixsubprocess.c +++ b/Modules/_posixsubprocess.c @@ -109,10 +109,11 @@ for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) { PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx); long iter_fd = PyLong_AsLong(py_fd); - if (iter_fd < 0 || iter_fd < prev_fd || iter_fd > INT_MAX) { + if (iter_fd < 0 || iter_fd <= prev_fd || iter_fd > INT_MAX) { /* Negative, overflow, not a Long, unsorted, too big for a fd. */ return 1; } + prev_fd = iter_fd; } return 0; } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 00:58:16 2015 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2015 05:58:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogbWVyZ2UgMy41ICgjMjU2MzAp?= Message-ID: <20151116055816.18190.60441@psf.io> https://hg.python.org/cpython/rev/d8d67b502bcc changeset: 99152:d8d67b502bcc parent: 99150:97e2a6810f7f parent: 99151:3ae62099d70b user: Benjamin Peterson date: Sun Nov 15 21:57:50 2015 -0800 summary: merge 3.5 (#25630) files: Misc/NEWS | 3 +++ Objects/unicodeobject.c | 1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #25630: Fix a possible segfault during argument parsing in functions + that accept filesystem paths. + - Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess internals regarding how fds_to_pass were passed to the child. The bug had no actual impact as subprocess.py already avoided it. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3775,6 +3775,7 @@ void *data; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); + *(PyObject**)addr = NULL; return 1; } if (PyBytes_Check(arg)) { -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 00:58:16 2015 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 16 Nov 2015 05:58:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_make_the_PyUni?= =?utf-8?q?code=5FFSConverter_cleanup_set_the_decrefed_argument_to_NULL?= Message-ID: <20151116055816.4669.95932@psf.io> https://hg.python.org/cpython/rev/3ae62099d70b changeset: 99151:3ae62099d70b branch: 3.5 parent: 99149:55f7a99a5433 user: Benjamin Peterson date: Sun Nov 15 21:57:39 2015 -0800 summary: make the PyUnicode_FSConverter cleanup set the decrefed argument to NULL (closes #25630) files: Misc/NEWS | 3 +++ Objects/unicodeobject.c | 1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -11,6 +11,9 @@ Core and Builtins ----------------- +- Issue #25630: Fix a possible segfault during argument parsing in functions + that accept filesystem paths. + - Issue #23564: Fixed a partially broken sanity check in the _posixsubprocess internals regarding how fds_to_pass were passed to the child. The bug had no actual impact as subprocess.py already avoided it. diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3614,6 +3614,7 @@ void *data; if (arg == NULL) { Py_DECREF(*(PyObject**)addr); + *(PyObject**)addr = NULL; return 1; } if (PyBytes_Check(arg)) { -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Mon Nov 16 03:42:38 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 16 Nov 2015 08:42:38 +0000 Subject: [Python-checkins] Daily reference leaks (97e2a6810f7f): sum=10 Message-ID: <20151116084238.37478.4533@psf.io> results for 97e2a6810f7f on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_capi leaked [1, 1, 1] references, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogBLsY2a', '--timeout', '7200'] From python-checkins at python.org Mon Nov 16 04:21:15 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 09:21:15 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzkwNTE6?= =?utf-8?q?_Added_tests_for_pickling_and_copying_the_timezone_objects=2E?= Message-ID: <20151116092115.120338.80560@psf.io> https://hg.python.org/cpython/rev/e48da8f01316 changeset: 99153:e48da8f01316 branch: 3.4 parent: 99146:6bd3c8623bb2 user: Serhiy Storchaka date: Mon Nov 16 11:12:58 2015 +0200 summary: Issue #9051: Added tests for pickling and copying the timezone objects. files: Lib/test/datetimetester.py | 29 +++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,6 +3,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import copy import sys import pickle import random @@ -223,7 +224,6 @@ tzrep = repr(tz) self.assertEqual(tz, eval(tzrep)) - def test_class_members(self): limit = timedelta(hours=23, minutes=59) self.assertEqual(timezone.utc.utcoffset(None), ZERO) @@ -310,6 +310,33 @@ self.assertEqual(tz.dst(t), t.replace(tzinfo=tz).dst()) + def test_pickle(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertIs(tz_copy, tz) + + def test_copy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.copy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.copy(tz) + self.assertIs(tz_copy, tz) + + def test_deepcopy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.deepcopy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.deepcopy(tz) + self.assertIs(tz_copy, tz) + + ############################################################################# # Base class for testing a particular aspect of timedelta, time, date and # datetime comparisons. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:21:15 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 09:21:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=239051=3A_Added_tests_for_pickling_and_copying_th?= =?utf-8?q?e_timezone_objects=2E?= Message-ID: <20151116092115.21857.94780@psf.io> https://hg.python.org/cpython/rev/9c31544d6a66 changeset: 99155:9c31544d6a66 parent: 99152:d8d67b502bcc parent: 99154:634905e9628d user: Serhiy Storchaka date: Mon Nov 16 11:20:17 2015 +0200 summary: Issue #9051: Added tests for pickling and copying the timezone objects. files: Lib/test/datetimetester.py | 29 +++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,6 +3,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import copy import decimal import sys import pickle @@ -235,7 +236,6 @@ tzrep = repr(tz) self.assertEqual(tz, eval(tzrep)) - def test_class_members(self): limit = timedelta(hours=23, minutes=59) self.assertEqual(timezone.utc.utcoffset(None), ZERO) @@ -323,6 +323,33 @@ self.assertEqual(tz.dst(t), t.replace(tzinfo=tz).dst()) + def test_pickle(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertIs(tz_copy, tz) + + def test_copy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.copy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.copy(tz) + self.assertIs(tz_copy, tz) + + def test_deepcopy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.deepcopy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.deepcopy(tz) + self.assertIs(tz_copy, tz) + + ############################################################################# # Base class for testing a particular aspect of timedelta, time, date and # datetime comparisons. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:21:15 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 09:21:15 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=239051=3A_Added_tests_for_pickling_and_copying_the_time?= =?utf-8?q?zone_objects=2E?= Message-ID: <20151116092115.18212.36502@psf.io> https://hg.python.org/cpython/rev/634905e9628d changeset: 99154:634905e9628d branch: 3.5 parent: 99151:3ae62099d70b parent: 99153:e48da8f01316 user: Serhiy Storchaka date: Mon Nov 16 11:19:31 2015 +0200 summary: Issue #9051: Added tests for pickling and copying the timezone objects. files: Lib/test/datetimetester.py | 29 +++++++++++++++++++++++++- 1 files changed, 28 insertions(+), 1 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -3,6 +3,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ +import copy import decimal import sys import pickle @@ -235,7 +236,6 @@ tzrep = repr(tz) self.assertEqual(tz, eval(tzrep)) - def test_class_members(self): limit = timedelta(hours=23, minutes=59) self.assertEqual(timezone.utc.utcoffset(None), ZERO) @@ -322,6 +322,33 @@ self.assertEqual(tz.dst(t), t.replace(tzinfo=tz).dst()) + def test_pickle(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + for pickler, unpickler, proto in pickle_choices: + tz_copy = unpickler.loads(pickler.dumps(tz, proto)) + self.assertIs(tz_copy, tz) + + def test_copy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.copy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.copy(tz) + self.assertIs(tz_copy, tz) + + def test_deepcopy(self): + for tz in self.ACDT, self.EST, timezone.min, timezone.max: + tz_copy = copy.deepcopy(tz) + self.assertEqual(tz_copy, tz) + tz = timezone.utc + tz_copy = copy.deepcopy(tz) + self.assertIs(tz_copy, tz) + + ############################################################################# # Base class for testing a particular aspect of timedelta, time, date and # datetime comparisons. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:45:29 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 16 Nov 2015 09:45:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2320220=3A_Merge_time_zone_workaround_from_3=2E4_into_3?= =?utf-8?q?=2E5?= Message-ID: <20151116094528.34151.29777@psf.io> https://hg.python.org/cpython/rev/364bd520d9f1 changeset: 99157:364bd520d9f1 branch: 3.5 parent: 99154:634905e9628d parent: 99156:673b4b093796 user: Martin Panter date: Mon Nov 16 09:42:41 2015 +0000 summary: Issue #20220: Merge time zone workaround from 3.4 into 3.5 files: Lib/test/test_imaplib.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -54,7 +54,9 @@ '"18-May-2033 05:33:20 +0200"'] @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') - @run_with_tz('STD-1DST') + # DST rules included to work around quirk where the Gnu C library may not + # otherwise restore the previous time zone + @run_with_tz('STD-1DST,M3.2.0,M11.1.0') def test_Time2Internaldate(self): expected = '"18-May-2033 05:33:20 +0200"' -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:45:28 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 16 Nov 2015 09:45:28 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2320220=3A_Revert_t?= =?utf-8?q?ime_zone_test_debugging=2C_revision_139c18943d9b?= Message-ID: <20151116094528.21857.29276@psf.io> https://hg.python.org/cpython/rev/039a370d047d changeset: 99158:039a370d047d parent: 99155:9c31544d6a66 user: Martin Panter date: Mon Nov 16 09:22:19 2015 +0000 summary: Issue #20220: Revert time zone test debugging, revision 139c18943d9b files: Lib/test/datetimetester.py | 11 +---------- 1 files changed, 1 insertions(+), 10 deletions(-) diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -2006,16 +2006,7 @@ seconds = tzseconds hours, minutes = divmod(seconds//60, 60) dtstr = "{}{:02d}{:02d} {}".format(sign, hours, minutes, tzname) - try: - dt = strptime(dtstr, "%z %Z") - except ValueError: - import os - self.fail( - "Issue #25168 strptime() failure info:\n" - f"_TimeRE_cache['Z']={_strptime._TimeRE_cache['Z']!r}\n" - f"TZ={os.environ.get('TZ')!r}, or {os.getenv('TZ')!r} via getenv()\n" - f"_regex_cache={_strptime._regex_cache!r}\n" - ) + dt = strptime(dtstr, "%z %Z") self.assertEqual(dt.utcoffset(), timedelta(seconds=tzseconds)) self.assertEqual(dt.tzname(), tzname) # Can produce inconsistent datetime -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:45:29 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 16 Nov 2015 09:45:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIwMjIw?= =?utf-8?q?=3A_Add_DST_rules_to_work_around_glibc_quirk?= Message-ID: <20151116094528.37486.63138@psf.io> https://hg.python.org/cpython/rev/673b4b093796 changeset: 99156:673b4b093796 branch: 3.4 parent: 99153:e48da8f01316 user: Martin Panter date: Mon Nov 16 07:21:38 2015 +0000 summary: Issue #20220: Add DST rules to work around glibc quirk This was triggering intermittent failures in unrelated tests. files: Lib/test/test_imaplib.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -55,7 +55,9 @@ '"18-May-2033 05:33:20 +0200"'] @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') - @run_with_tz('STD-1DST') + # DST rules included to work around quirk where the Gnu C library may not + # otherwise restore the previous time zone + @run_with_tz('STD-1DST,M3.2.0,M11.1.0') def test_Time2Internaldate(self): expected = '"18-May-2033 05:33:20 +0200"' -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 04:45:29 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 16 Nov 2015 09:45:29 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2320220=3A_Merge_time_zone_workaround_from_3=2E5?= Message-ID: <20151116094528.37468.39114@psf.io> https://hg.python.org/cpython/rev/007235e65603 changeset: 99159:007235e65603 parent: 99158:039a370d047d parent: 99157:364bd520d9f1 user: Martin Panter date: Mon Nov 16 09:43:05 2015 +0000 summary: Issue #20220: Merge time zone workaround from 3.5 files: Lib/test/test_imaplib.py | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_imaplib.py b/Lib/test/test_imaplib.py --- a/Lib/test/test_imaplib.py +++ b/Lib/test/test_imaplib.py @@ -54,7 +54,9 @@ '"18-May-2033 05:33:20 +0200"'] @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') - @run_with_tz('STD-1DST') + # DST rules included to work around quirk where the Gnu C library may not + # otherwise restore the previous time zone + @run_with_tz('STD-1DST,M3.2.0,M11.1.0') def test_Time2Internaldate(self): expected = '"18-May-2033 05:33:20 +0200"' -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:10 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI0NzUw?= =?utf-8?q?=3A_Improve_appearance_of_IDLE_editor_window_status_bar=2E?= Message-ID: <20151116123710.31765.97292@psf.io> https://hg.python.org/cpython/rev/ff31af003c35 changeset: 99160:ff31af003c35 branch: 2.7 parent: 99141:017d77d001c5 user: Terry Jan Reedy date: Mon Nov 16 07:32:19 2015 -0500 summary: Issue #24750: Improve appearance of IDLE editor window status bar. Patch by Mark Roseman. files: Lib/idlelib/EditorWindow.py | 3 +++ Lib/idlelib/MultiStatusBar.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -184,6 +184,7 @@ 'name': 'text', 'padx': 5, 'wrap': 'none', + 'highlightthickness': 0, 'width': self.width, 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} if TkVersion >= 8.5: @@ -410,6 +411,7 @@ def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) + sep = Frame(self.top, height=1, borderwidth=1, background='grey75') if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. @@ -417,6 +419,7 @@ self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) + sep.pack(side=BOTTOM, fill=X) self.text.bind("<>", self.set_line_and_column) self.text.event_add("<>", "", "") diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -8,13 +8,15 @@ Frame.__init__(self, master, **kw) self.labels = {} - def set_label(self, name, text='', side=LEFT): + def set_label(self, name, text='', side=LEFT, width=0): if name not in self.labels: - label = Label(self, bd=1, relief=SUNKEN, anchor=W) - label.pack(side=side) + label = Label(self, borderwidth=0, anchor=W) + label.pack(side=side, pady=0, padx=4) self.labels[name] = label else: label = self.labels[name] + if width != 0: + label.config(width=width) label.config(text=text) def _multistatus_bar(parent): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:10 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151116123710.21873.50122@psf.io> https://hg.python.org/cpython/rev/b0d60877608a changeset: 99162:b0d60877608a branch: 3.5 parent: 99157:364bd520d9f1 parent: 99161:ecb74f61a5d4 user: Terry Jan Reedy date: Mon Nov 16 07:32:46 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/EditorWindow.py | 3 +++ Lib/idlelib/MultiStatusBar.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -156,6 +156,7 @@ 'name': 'text', 'padx': 5, 'wrap': 'none', + 'highlightthickness': 0, 'width': self.width, 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} @@ -380,6 +381,7 @@ def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) + sep = Frame(self.top, height=1, borderwidth=1, background='grey75') if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. @@ -387,6 +389,7 @@ self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) + sep.pack(side=BOTTOM, fill=X) self.text.bind("<>", self.set_line_and_column) self.text.event_add("<>", "", "") diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -8,13 +8,15 @@ Frame.__init__(self, master, **kw) self.labels = {} - def set_label(self, name, text='', side=LEFT): + def set_label(self, name, text='', side=LEFT, width=0): if name not in self.labels: - label = Label(self, bd=1, relief=SUNKEN, anchor=W) - label.pack(side=side) + label = Label(self, borderwidth=0, anchor=W) + label.pack(side=side, pady=0, padx=4) self.labels[name] = label else: label = self.labels[name] + if width != 0: + label.config(width=width) label.config(text=text) def _multistatus_bar(parent): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:10 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151116123710.21865.93430@psf.io> https://hg.python.org/cpython/rev/961b1e82a7e5 changeset: 99163:961b1e82a7e5 parent: 99159:007235e65603 parent: 99162:b0d60877608a user: Terry Jan Reedy date: Mon Nov 16 07:33:01 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/EditorWindow.py | 3 +++ Lib/idlelib/MultiStatusBar.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -156,6 +156,7 @@ 'name': 'text', 'padx': 5, 'wrap': 'none', + 'highlightthickness': 0, 'width': self.width, 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} @@ -380,6 +381,7 @@ def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) + sep = Frame(self.top, height=1, borderwidth=1, background='grey75') if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. @@ -387,6 +389,7 @@ self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) + sep.pack(side=BOTTOM, fill=X) self.text.bind("<>", self.set_line_and_column) self.text.event_add("<>", "", "") diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -8,13 +8,15 @@ Frame.__init__(self, master, **kw) self.labels = {} - def set_label(self, name, text='', side=LEFT): + def set_label(self, name, text='', side=LEFT, width=0): if name not in self.labels: - label = Label(self, bd=1, relief=SUNKEN, anchor=W) - label.pack(side=side) + label = Label(self, borderwidth=0, anchor=W) + label.pack(side=side, pady=0, padx=4) self.labels[name] = label else: label = self.labels[name] + if width != 0: + label.config(width=width) label.config(text=text) def _multistatus_bar(parent): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:10 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0NzUw?= =?utf-8?q?=3A_Improve_appearance_of_IDLE_editor_window_status_bar=2E?= Message-ID: <20151116123710.34158.11702@psf.io> https://hg.python.org/cpython/rev/ecb74f61a5d4 changeset: 99161:ecb74f61a5d4 branch: 3.4 parent: 99156:673b4b093796 user: Terry Jan Reedy date: Mon Nov 16 07:32:26 2015 -0500 summary: Issue #24750: Improve appearance of IDLE editor window status bar. Patch by Mark Roseman. files: Lib/idlelib/EditorWindow.py | 3 +++ Lib/idlelib/MultiStatusBar.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/idlelib/EditorWindow.py b/Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py +++ b/Lib/idlelib/EditorWindow.py @@ -156,6 +156,7 @@ 'name': 'text', 'padx': 5, 'wrap': 'none', + 'highlightthickness': 0, 'width': self.width, 'height': idleConf.GetOption('main', 'EditorWindow', 'height', type='int')} @@ -380,6 +381,7 @@ def set_status_bar(self): self.status_bar = self.MultiStatusBar(self.top) + sep = Frame(self.top, height=1, borderwidth=1, background='grey75') if sys.platform == "darwin": # Insert some padding to avoid obscuring some of the statusbar # by the resize widget. @@ -387,6 +389,7 @@ self.status_bar.set_label('column', 'Col: ?', side=RIGHT) self.status_bar.set_label('line', 'Ln: ?', side=RIGHT) self.status_bar.pack(side=BOTTOM, fill=X) + sep.pack(side=BOTTOM, fill=X) self.text.bind("<>", self.set_line_and_column) self.text.event_add("<>", "", "") diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -8,13 +8,15 @@ Frame.__init__(self, master, **kw) self.labels = {} - def set_label(self, name, text='', side=LEFT): + def set_label(self, name, text='', side=LEFT, width=0): if name not in self.labels: - label = Label(self, bd=1, relief=SUNKEN, anchor=W) - label.pack(side=side) + label = Label(self, borderwidth=0, anchor=W) + label.pack(side=side, pady=0, padx=4) self.labels[name] = label else: label = self.labels[name] + if width != 0: + label.config(width=width) label.config(text=text) def _multistatus_bar(parent): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:10 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI0NzUw?= =?utf-8?q?=3A_whitespace?= Message-ID: <20151116123710.34149.58143@psf.io> https://hg.python.org/cpython/rev/483a5cd9f975 changeset: 99164:483a5cd9f975 branch: 2.7 parent: 99160:ff31af003c35 user: Terry Jan Reedy date: Mon Nov 16 07:36:12 2015 -0500 summary: Issue #24750: whitespace files: Lib/idlelib/MultiStatusBar.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -15,7 +15,7 @@ self.labels[name] = label else: label = self.labels[name] - if width != 0: + if width != 0: label.config(width=width) label.config(text=text) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:11 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151116123711.4663.56437@psf.io> https://hg.python.org/cpython/rev/c50808152a8f changeset: 99166:c50808152a8f branch: 3.5 parent: 99162:b0d60877608a parent: 99165:38d9ffbb595b user: Terry Jan Reedy date: Mon Nov 16 07:36:33 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/MultiStatusBar.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -15,7 +15,7 @@ self.labels[name] = label else: label = self.labels[name] - if width != 0: + if width != 0: label.config(width=width) label.config(text=text) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:11 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:11 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0NzUw?= =?utf-8?q?=3A_whitespace?= Message-ID: <20151116123710.109187.60292@psf.io> https://hg.python.org/cpython/rev/38d9ffbb595b changeset: 99165:38d9ffbb595b branch: 3.4 parent: 99161:ecb74f61a5d4 user: Terry Jan Reedy date: Mon Nov 16 07:36:22 2015 -0500 summary: Issue #24750: whitespace files: Lib/idlelib/MultiStatusBar.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -15,7 +15,7 @@ self.labels[name] = label else: label = self.labels[name] - if width != 0: + if width != 0: label.config(width=width) label.config(text=text) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 07:37:18 2015 From: python-checkins at python.org (terry.reedy) Date: Mon, 16 Nov 2015 12:37:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151116123716.120358.67954@psf.io> https://hg.python.org/cpython/rev/2c97612859b3 changeset: 99167:2c97612859b3 parent: 99163:961b1e82a7e5 parent: 99166:c50808152a8f user: Terry Jan Reedy date: Mon Nov 16 07:36:44 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/MultiStatusBar.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/MultiStatusBar.py b/Lib/idlelib/MultiStatusBar.py --- a/Lib/idlelib/MultiStatusBar.py +++ b/Lib/idlelib/MultiStatusBar.py @@ -15,7 +15,7 @@ self.labels[name] = label else: label = self.labels[name] - if width != 0: + if width != 0: label.config(width=width) label.config(text=text) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 11:46:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 16:46:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NDk4?= =?utf-8?q?=3A_Fixed_contributors_name=2E?= Message-ID: <20151116164629.14351.27188@psf.io> https://hg.python.org/cpython/rev/b04ae5392cf2 changeset: 99168:b04ae5392cf2 branch: 3.4 parent: 99165:38d9ffbb595b user: Serhiy Storchaka date: Mon Nov 16 18:45:23 2015 +0200 summary: Issue #25498: Fixed contributors name. files: Misc/ACKS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -391,7 +391,6 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst -Eryksun Ben Escoto Andy Eskilsson Andr? Espaze @@ -1358,6 +1357,7 @@ Nathan Sullivan Mark Summerfield Reuben Sumner +Eryk Sun Marek ?uppa Hisao Suzuki Kalle Svensson -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 11:46:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 16:46:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325498=3A_Fixed_contributors_name=2E?= Message-ID: <20151116164629.31765.45366@psf.io> https://hg.python.org/cpython/rev/3738b0ca1356 changeset: 99169:3738b0ca1356 branch: 3.5 parent: 99166:c50808152a8f parent: 99168:b04ae5392cf2 user: Serhiy Storchaka date: Mon Nov 16 18:45:39 2015 +0200 summary: Issue #25498: Fixed contributors name. files: Misc/ACKS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -398,7 +398,6 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst -Eryksun Ben Escoto Andy Eskilsson Andr? Espaze @@ -1396,6 +1395,7 @@ Nathan Sullivan Mark Summerfield Reuben Sumner +Eryk Sun Marek ?uppa Hisao Suzuki Kalle Svensson -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 11:46:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 16 Nov 2015 16:46:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325498=3A_Fixed_contributors_name=2E?= Message-ID: <20151116164630.88490.84303@psf.io> https://hg.python.org/cpython/rev/559ff2852cf2 changeset: 99170:559ff2852cf2 parent: 99167:2c97612859b3 parent: 99169:3738b0ca1356 user: Serhiy Storchaka date: Mon Nov 16 18:46:05 2015 +0200 summary: Issue #25498: Fixed contributors name. files: Misc/ACKS | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -399,7 +399,6 @@ Stoffel Erasmus J?rgen A. Erhard Michael Ernst -Eryksun Ben Escoto Andy Eskilsson Andr? Espaze @@ -1399,6 +1398,7 @@ Nathan Sullivan Mark Summerfield Reuben Sumner +Eryk Sun Marek ?uppa Hisao Suzuki Kalle Svensson -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 12:43:53 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:43:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogQWRk?= =?utf-8?q?_Transport=2Eis=5Fclosing=28=29?= Message-ID: <20151116174353.79055.59587@psf.io> https://hg.python.org/cpython/rev/52a87ee95685 changeset: 99171:52a87ee95685 branch: 3.4 parent: 99168:b04ae5392cf2 user: Yury Selivanov date: Mon Nov 16 12:43:21 2015 -0500 summary: asyncio: Add Transport.is_closing() See https://github.com/python/asyncio/pull/291 for details. files: Lib/asyncio/base_subprocess.py | 3 ++ Lib/asyncio/proactor_events.py | 3 ++ Lib/asyncio/selector_events.py | 3 ++ Lib/asyncio/sslproto.py | 3 ++ Lib/asyncio/streams.py | 2 +- Lib/asyncio/transports.py | 4 +++ Lib/asyncio/unix_events.py | 6 +++++ Lib/test/test_asyncio/test_proactor_events.py | 6 ++-- Lib/test/test_asyncio/test_selector_events.py | 6 ++-- Lib/test/test_asyncio/test_subprocess.py | 2 +- Lib/test/test_asyncio/test_unix_events.py | 12 +++++----- 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -87,6 +87,9 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError + def is_closing(self): + return self._closed + def close(self): if self._closed: return diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -65,6 +65,9 @@ def _set_extra(self, sock): self._extra['pipe'] = sock + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -556,6 +556,9 @@ def abort(self): self._force_close(None) + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -304,6 +304,9 @@ """Get optional transport information.""" return self._ssl_protocol._get_extra_info(name, default) + def is_closing(self): + return self._closed + def close(self): """Close the transport. diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -302,7 +302,7 @@ if exc is not None: raise exc if self._transport is not None: - if self._transport._closing: + if self._transport.is_closing(): # Yield to the event loop so connection_lost() may be # called. Without this, _drain_helper() would return # immediately, and code that calls diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -19,6 +19,10 @@ """Get optional transport information.""" return self._extra.get(name, default) + def is_closing(self): + """Return True if the transport is closing or closed.""" + raise NotImplementedError + def close(self): """Close the transport. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -364,6 +364,9 @@ def resume_reading(self): self._loop.add_reader(self._fileno, self._read_ready) + def is_closing(self): + return self._closing + def close(self): if not self._closing: self._close(None) @@ -548,6 +551,9 @@ self._loop.remove_reader(self._fileno) self._loop.call_soon(self._call_connection_lost, None) + def is_closing(self): + return self._closing + def close(self): if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -204,7 +204,7 @@ tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._conn_lost, 1) self.protocol.connection_lost.reset_mock() @@ -298,7 +298,7 @@ self.loop, self.sock, self.protocol) self.assertTrue(tr.can_write_eof()) tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.loop._run_once() self.assertTrue(self.sock.close.called) tr.close() @@ -309,7 +309,7 @@ tr._loop._proactor.send.return_value = f tr.write(b'data') tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.sock.shutdown.called) tr._loop._proactor.send.assert_called_with(self.sock, b'data') f.set_result(4) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -698,7 +698,7 @@ tr = self.create_transport() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[7]) self.protocol.connection_lost(None) self.assertEqual(tr._conn_lost, 1) @@ -723,7 +723,7 @@ self.loop.add_writer(7, mock.sentinel) tr._force_close(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._buffer, list_to_buffer()) self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -1436,7 +1436,7 @@ tr = self._make_one() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[1]) self.assertEqual(tr._conn_lost, 1) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -61,7 +61,7 @@ self.assertTrue(protocol.connection_lost.called) self.assertEqual(protocol.connection_lost.call_args[0], (None,)) - self.assertFalse(transport._closed) + self.assertFalse(transport.is_closing()) self.assertIsNone(transport._loop) self.assertIsNone(transport._proc) self.assertIsNone(transport._protocol) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -440,7 +440,7 @@ tr = self.read_pipe_transport() err = object() tr._close(err) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) @@ -598,7 +598,7 @@ tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -658,7 +658,7 @@ self.assertFalse(self.loop.writers) self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) m_logexc.assert_called_with( test_utils.MockPattern( 'Fatal write error on pipe transport' @@ -694,7 +694,7 @@ self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -743,7 +743,7 @@ def test_write_eof(self): tr = self.write_pipe_transport() tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -752,7 +752,7 @@ tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.protocol.connection_lost.called) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 12:43:53 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:43:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151116174353.14375.2037@psf.io> https://hg.python.org/cpython/rev/cddbb9c622e1 changeset: 99172:cddbb9c622e1 branch: 3.5 parent: 99169:3738b0ca1356 parent: 99171:52a87ee95685 user: Yury Selivanov date: Mon Nov 16 12:43:35 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/base_subprocess.py | 3 ++ Lib/asyncio/proactor_events.py | 3 ++ Lib/asyncio/selector_events.py | 3 ++ Lib/asyncio/sslproto.py | 3 ++ Lib/asyncio/streams.py | 2 +- Lib/asyncio/transports.py | 4 +++ Lib/asyncio/unix_events.py | 6 +++++ Lib/test/test_asyncio/test_proactor_events.py | 6 ++-- Lib/test/test_asyncio/test_selector_events.py | 6 ++-- Lib/test/test_asyncio/test_subprocess.py | 2 +- Lib/test/test_asyncio/test_unix_events.py | 12 +++++----- 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -87,6 +87,9 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError + def is_closing(self): + return self._closed + def close(self): if self._closed: return diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -65,6 +65,9 @@ def _set_extra(self, sock): self._extra['pipe'] = sock + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -556,6 +556,9 @@ def abort(self): self._force_close(None) + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -304,6 +304,9 @@ """Get optional transport information.""" return self._ssl_protocol._get_extra_info(name, default) + def is_closing(self): + return self._closed + def close(self): """Close the transport. diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -302,7 +302,7 @@ if exc is not None: raise exc if self._transport is not None: - if self._transport._closing: + if self._transport.is_closing(): # Yield to the event loop so connection_lost() may be # called. Without this, _drain_helper() would return # immediately, and code that calls diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -19,6 +19,10 @@ """Get optional transport information.""" return self._extra.get(name, default) + def is_closing(self): + """Return True if the transport is closing or closed.""" + raise NotImplementedError + def close(self): """Close the transport. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -364,6 +364,9 @@ def resume_reading(self): self._loop.add_reader(self._fileno, self._read_ready) + def is_closing(self): + return self._closing + def close(self): if not self._closing: self._close(None) @@ -548,6 +551,9 @@ self._loop.remove_reader(self._fileno) self._loop.call_soon(self._call_connection_lost, None) + def is_closing(self): + return self._closing + def close(self): if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -204,7 +204,7 @@ tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._conn_lost, 1) self.protocol.connection_lost.reset_mock() @@ -298,7 +298,7 @@ self.loop, self.sock, self.protocol) self.assertTrue(tr.can_write_eof()) tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.loop._run_once() self.assertTrue(self.sock.close.called) tr.close() @@ -309,7 +309,7 @@ tr._loop._proactor.send.return_value = f tr.write(b'data') tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.sock.shutdown.called) tr._loop._proactor.send.assert_called_with(self.sock, b'data') f.set_result(4) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -698,7 +698,7 @@ tr = self.create_transport() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[7]) self.protocol.connection_lost(None) self.assertEqual(tr._conn_lost, 1) @@ -723,7 +723,7 @@ self.loop.add_writer(7, mock.sentinel) tr._force_close(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._buffer, list_to_buffer()) self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -1436,7 +1436,7 @@ tr = self._make_one() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[1]) self.assertEqual(tr._conn_lost, 1) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -61,7 +61,7 @@ self.assertTrue(protocol.connection_lost.called) self.assertEqual(protocol.connection_lost.call_args[0], (None,)) - self.assertFalse(transport._closed) + self.assertFalse(transport.is_closing()) self.assertIsNone(transport._loop) self.assertIsNone(transport._proc) self.assertIsNone(transport._protocol) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -440,7 +440,7 @@ tr = self.read_pipe_transport() err = object() tr._close(err) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) @@ -598,7 +598,7 @@ tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -658,7 +658,7 @@ self.assertFalse(self.loop.writers) self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) m_logexc.assert_called_with( test_utils.MockPattern( 'Fatal write error on pipe transport' @@ -694,7 +694,7 @@ self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -743,7 +743,7 @@ def test_write_eof(self): tr = self.write_pipe_transport() tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -752,7 +752,7 @@ tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.protocol.connection_lost.called) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 12:43:53 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:43:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151116174353.79037.59171@psf.io> https://hg.python.org/cpython/rev/c8f720288140 changeset: 99173:c8f720288140 parent: 99170:559ff2852cf2 parent: 99172:cddbb9c622e1 user: Yury Selivanov date: Mon Nov 16 12:43:46 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/base_subprocess.py | 3 ++ Lib/asyncio/proactor_events.py | 3 ++ Lib/asyncio/selector_events.py | 3 ++ Lib/asyncio/sslproto.py | 3 ++ Lib/asyncio/streams.py | 2 +- Lib/asyncio/transports.py | 4 +++ Lib/asyncio/unix_events.py | 6 +++++ Lib/test/test_asyncio/test_proactor_events.py | 6 ++-- Lib/test/test_asyncio/test_selector_events.py | 6 ++-- Lib/test/test_asyncio/test_subprocess.py | 2 +- Lib/test/test_asyncio/test_unix_events.py | 12 +++++----- 11 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py --- a/Lib/asyncio/base_subprocess.py +++ b/Lib/asyncio/base_subprocess.py @@ -87,6 +87,9 @@ def _start(self, args, shell, stdin, stdout, stderr, bufsize, **kwargs): raise NotImplementedError + def is_closing(self): + return self._closed + def close(self): if self._closed: return diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -65,6 +65,9 @@ def _set_extra(self, sock): self._extra['pipe'] = sock + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -556,6 +556,9 @@ def abort(self): self._force_close(None) + def is_closing(self): + return self._closing + def close(self): if self._closing: return diff --git a/Lib/asyncio/sslproto.py b/Lib/asyncio/sslproto.py --- a/Lib/asyncio/sslproto.py +++ b/Lib/asyncio/sslproto.py @@ -304,6 +304,9 @@ """Get optional transport information.""" return self._ssl_protocol._get_extra_info(name, default) + def is_closing(self): + return self._closed + def close(self): """Close the transport. diff --git a/Lib/asyncio/streams.py b/Lib/asyncio/streams.py --- a/Lib/asyncio/streams.py +++ b/Lib/asyncio/streams.py @@ -302,7 +302,7 @@ if exc is not None: raise exc if self._transport is not None: - if self._transport._closing: + if self._transport.is_closing(): # Yield to the event loop so connection_lost() may be # called. Without this, _drain_helper() would return # immediately, and code that calls diff --git a/Lib/asyncio/transports.py b/Lib/asyncio/transports.py --- a/Lib/asyncio/transports.py +++ b/Lib/asyncio/transports.py @@ -19,6 +19,10 @@ """Get optional transport information.""" return self._extra.get(name, default) + def is_closing(self): + """Return True if the transport is closing or closed.""" + raise NotImplementedError + def close(self): """Close the transport. diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -364,6 +364,9 @@ def resume_reading(self): self._loop.add_reader(self._fileno, self._read_ready) + def is_closing(self): + return self._closing + def close(self): if not self._closing: self._close(None) @@ -548,6 +551,9 @@ self._loop.remove_reader(self._fileno) self._loop.call_soon(self._call_connection_lost, None) + def is_closing(self): + return self._closing + def close(self): if self._pipe is not None and not self._closing: # write_eof is all what we needed to close the write pipe diff --git a/Lib/test/test_asyncio/test_proactor_events.py b/Lib/test/test_asyncio/test_proactor_events.py --- a/Lib/test/test_asyncio/test_proactor_events.py +++ b/Lib/test/test_asyncio/test_proactor_events.py @@ -204,7 +204,7 @@ tr.close() test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._conn_lost, 1) self.protocol.connection_lost.reset_mock() @@ -298,7 +298,7 @@ self.loop, self.sock, self.protocol) self.assertTrue(tr.can_write_eof()) tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.loop._run_once() self.assertTrue(self.sock.close.called) tr.close() @@ -309,7 +309,7 @@ tr._loop._proactor.send.return_value = f tr.write(b'data') tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.sock.shutdown.called) tr._loop._proactor.send.assert_called_with(self.sock, b'data') f.set_result(4) diff --git a/Lib/test/test_asyncio/test_selector_events.py b/Lib/test/test_asyncio/test_selector_events.py --- a/Lib/test/test_asyncio/test_selector_events.py +++ b/Lib/test/test_asyncio/test_selector_events.py @@ -698,7 +698,7 @@ tr = self.create_transport() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[7]) self.protocol.connection_lost(None) self.assertEqual(tr._conn_lost, 1) @@ -723,7 +723,7 @@ self.loop.add_writer(7, mock.sentinel) tr._force_close(None) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(tr._buffer, list_to_buffer()) self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) @@ -1436,7 +1436,7 @@ tr = self._make_one() tr.close() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertEqual(1, self.loop.remove_reader_count[1]) self.assertEqual(tr._conn_lost, 1) diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py --- a/Lib/test/test_asyncio/test_subprocess.py +++ b/Lib/test/test_asyncio/test_subprocess.py @@ -61,7 +61,7 @@ self.assertTrue(protocol.connection_lost.called) self.assertEqual(protocol.connection_lost.call_args[0], (None,)) - self.assertFalse(transport._closed) + self.assertFalse(transport.is_closing()) self.assertIsNone(transport._loop) self.assertIsNone(transport._proc) self.assertIsNone(transport._protocol) diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -440,7 +440,7 @@ tr = self.read_pipe_transport() err = object() tr._close(err) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(err) @@ -598,7 +598,7 @@ tr._read_ready() self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -658,7 +658,7 @@ self.assertFalse(self.loop.writers) self.assertFalse(self.loop.readers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) m_logexc.assert_called_with( test_utils.MockPattern( 'Fatal write error on pipe transport' @@ -694,7 +694,7 @@ self.assertFalse(self.loop.readers) self.assertFalse(self.loop.writers) self.assertEqual([], tr._buffer) - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -743,7 +743,7 @@ def test_write_eof(self): tr = self.write_pipe_transport() tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.loop.readers) test_utils.run_briefly(self.loop) self.protocol.connection_lost.assert_called_with(None) @@ -752,7 +752,7 @@ tr = self.write_pipe_transport() tr._buffer = [b'data'] tr.write_eof() - self.assertTrue(tr._closing) + self.assertTrue(tr.is_closing()) self.assertFalse(self.protocol.connection_lost.called) -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Mon Nov 16 12:45:51 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 16 Nov 2015 17:45:51 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-16 Message-ID: <0c96f87d-8d85-4b0e-aefe-c4533d7477c9@irsmsx151.ger.corp.intel.com> Results for project Python default, build date 2015-11-16 04:02:38 +0000 commit: e51c46d12ec1752a9a7249dd6ac916b74ce96e2d revision date: 2015-11-16 02:31:34 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.44% -0.22% 8.02% 18.54% :-( pybench 0.15% -0.62% -2.43% 9.68% :-( regex_v8 2.74% 0.57% -4.07% 5.13% :-| nbody 0.07% 1.46% -0.06% 8.10% :-| json_dump_v2 0.23% -1.02% -0.37% 10.73% :-| normal_startup 1.02% -0.54% 0.04% 5.11% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Mon Nov 16 12:46:15 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 16 Nov 2015 17:46:15 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-16 Message-ID: Results for project Python 2.7, build date 2015-11-16 13:50:43 +0000 commit: 483a5cd9f97599a9fdd70d6e28bd53ea595e9917 revision date: 2015-11-16 12:36:12 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.12% -1.19% 2.81% 10.88% :-) pybench 0.19% 0.18% 6.48% 7.03% :-( regex_v8 0.55% -0.29% -2.12% 8.52% :-) nbody 0.15% 0.00% 9.09% 4.12% :-) json_dump_v2 0.22% -0.22% 3.62% 15.21% :-( normal_startup 1.68% -3.10% -1.62% 3.15% :-| ssbench 0.40% 0.84% 0.88% 0.81% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Mon Nov 16 12:47:34 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:47:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_asyncio=2Edocs=3A_Document_Transport=2Eis=5Fclosing_=28merge_3?= =?utf-8?b?LjQp?= Message-ID: <20151116174734.31763.20630@psf.io> https://hg.python.org/cpython/rev/a0c82833b892 changeset: 99175:a0c82833b892 branch: 3.5 parent: 99172:cddbb9c622e1 parent: 99174:c52981d2fb25 user: Yury Selivanov date: Mon Nov 16 12:47:15 2015 -0500 summary: asyncio.docs: Document Transport.is_closing (merge 3.4) files: Doc/library/asyncio-protocol.rst | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -41,6 +41,11 @@ protocol's :meth:`connection_lost` method will be called with :const:`None` as its argument. + .. method:: is_closing(self) + + Return ``True`` if the transport is closing or is closed. + + .. versionadded:: 3.5.1 .. method:: get_extra_info(name, default=None) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 12:47:34 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:47:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpby5kb2Nz?= =?utf-8?q?=3A_Document_Transport=2Eis=5Fclosing?= Message-ID: <20151116174734.4565.22382@psf.io> https://hg.python.org/cpython/rev/c52981d2fb25 changeset: 99174:c52981d2fb25 branch: 3.4 parent: 99171:52a87ee95685 user: Yury Selivanov date: Mon Nov 16 12:46:41 2015 -0500 summary: asyncio.docs: Document Transport.is_closing files: Doc/library/asyncio-protocol.rst | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -41,6 +41,11 @@ protocol's :meth:`connection_lost` method will be called with :const:`None` as its argument. + .. method:: is_closing(self) + + Return ``True`` if the transport is closing or is closed. + + .. versionadded:: 3.4.4 .. method:: get_extra_info(name, default=None) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 12:47:35 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 17:47:35 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151116174735.79057.77684@psf.io> https://hg.python.org/cpython/rev/152306d1d2b5 changeset: 99176:152306d1d2b5 parent: 99173:c8f720288140 parent: 99175:a0c82833b892 user: Yury Selivanov date: Mon Nov 16 12:47:25 2015 -0500 summary: Merge 3.5 files: Doc/library/asyncio-protocol.rst | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -41,6 +41,11 @@ protocol's :meth:`connection_lost` method will be called with :const:`None` as its argument. + .. method:: is_closing(self) + + Return ``True`` if the transport is closing or is closed. + + .. versionadded:: 3.5.1 .. method:: get_extra_info(name, default=None) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 15:12:59 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 20:12:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151116201259.79059.27105@psf.io> https://hg.python.org/cpython/rev/4f8c871616e8 changeset: 99178:4f8c871616e8 branch: 3.5 parent: 99175:a0c82833b892 parent: 99177:4aa6a6a701c7 user: Yury Selivanov date: Mon Nov 16 15:12:44 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/tasks.py | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,6 +93,7 @@ futures.Future.__del__(self) def _repr_info(self): + # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -221,6 +222,7 @@ return True def _step(self, value=None, exc=None): + # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -284,13 +286,20 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): + # Private method, do not use it. try: - value = future.result() + future.result() except Exception as exc: # This may also be a cancellation. self._step(None, exc) else: - self._step(value, None) + # Don't pass the value of `future.result()` explicitly, + # as `Future.__iter__` and `Future.__await__` don't need it. + # If we call `_step(value, None)` instead of `_step()`, + # Python eval loop would use `.send(value)` method call, + # instead of `__next__()`, which is slower for futures + # that return non-generator iterators from their `__iter__`. + self._step() self = None # Needed to break cycles when an exception occurs. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 15:12:59 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 20:12:59 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogT3B0?= =?utf-8?q?imize_Task=2E=5Fwakeup?= Message-ID: <20151116201258.4549.88704@psf.io> https://hg.python.org/cpython/rev/4aa6a6a701c7 changeset: 99177:4aa6a6a701c7 branch: 3.4 parent: 99174:c52981d2fb25 user: Yury Selivanov date: Mon Nov 16 15:12:10 2015 -0500 summary: asyncio: Optimize Task._wakeup See https://github.com/python/asyncio/pull/289 for details. files: Lib/asyncio/tasks.py | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,6 +93,7 @@ futures.Future.__del__(self) def _repr_info(self): + # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -221,6 +222,7 @@ return True def _step(self, value=None, exc=None): + # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -284,13 +286,20 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): + # Private method, do not use it. try: - value = future.result() + future.result() except Exception as exc: # This may also be a cancellation. self._step(None, exc) else: - self._step(value, None) + # Don't pass the value of `future.result()` explicitly, + # as `Future.__iter__` and `Future.__await__` don't need it. + # If we call `_step(value, None)` instead of `_step()`, + # Python eval loop would use `.send(value)` method call, + # instead of `__next__()`, which is slower for futures + # that return non-generator iterators from their `__iter__`. + self._step() self = None # Needed to break cycles when an exception occurs. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 15:13:00 2015 From: python-checkins at python.org (yury.selivanov) Date: Mon, 16 Nov 2015 20:13:00 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151116201259.105907.12411@psf.io> https://hg.python.org/cpython/rev/06820c2bd0b6 changeset: 99179:06820c2bd0b6 parent: 99176:152306d1d2b5 parent: 99178:4f8c871616e8 user: Yury Selivanov date: Mon Nov 16 15:12:54 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/tasks.py | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,6 +93,7 @@ futures.Future.__del__(self) def _repr_info(self): + # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -221,6 +222,7 @@ return True def _step(self, value=None, exc=None): + # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -284,13 +286,20 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): + # Private method, do not use it. try: - value = future.result() + future.result() except Exception as exc: # This may also be a cancellation. self._step(None, exc) else: - self._step(value, None) + # Don't pass the value of `future.result()` explicitly, + # as `Future.__iter__` and `Future.__await__` don't need it. + # If we call `_step(value, None)` instead of `_step()`, + # Python eval loop would use `.send(value)` method call, + # instead of `__next__()`, which is slower for futures + # that return non-generator iterators from their `__iter__`. + self._step() self = None # Needed to break cycles when an exception occurs. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 19:20:51 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 00:20:51 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjE1?= =?utf-8?q?=3A_Document_unsorted_behaviour_of_glob=3B_patch_by_Dave_Jones?= Message-ID: <20151117002051.14359.95531@psf.io> https://hg.python.org/cpython/rev/7ca6a13db0e5 changeset: 99181:7ca6a13db0e5 branch: 3.4 parent: 99177:4aa6a6a701c7 user: Martin Panter date: Mon Nov 16 23:46:22 2015 +0000 summary: Issue #25615: Document unsorted behaviour of glob; patch by Dave Jones files: Doc/library/glob.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -12,13 +12,13 @@ -------------- The :mod:`glob` module finds all the pathnames matching a specified pattern -according to the rules used by the Unix shell. No tilde expansion is done, but -``*``, ``?``, and character ranges expressed with ``[]`` will be correctly -matched. This is done by using the :func:`os.listdir` and -:func:`fnmatch.fnmatch` functions in concert, and not by actually invoking a -subshell. Note that unlike :func:`fnmatch.fnmatch`, :mod:`glob` treats -filenames beginning with a dot (``.``) as special cases. (For tilde and shell -variable expansion, use :func:`os.path.expanduser` and +according to the rules used by the Unix shell, although results are returned in +arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character +ranges expressed with ``[]`` will be correctly matched. This is done by using +the :func:`os.listdir` and :func:`fnmatch.fnmatch` functions in concert, and +not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, +:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +(For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) For a literal match, wrap the meta-characters in brackets. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 19:20:53 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 00:20:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325615=3A_Merge_glob_doc_from_3=2E5?= Message-ID: <20151117002051.79043.94874@psf.io> https://hg.python.org/cpython/rev/a6bc96c2b8be changeset: 99183:a6bc96c2b8be parent: 99179:06820c2bd0b6 parent: 99182:f928dcb448a9 user: Martin Panter date: Tue Nov 17 00:19:27 2015 +0000 summary: Issue #25615: Merge glob doc from 3.5 files: Doc/library/glob.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -12,13 +12,13 @@ -------------- The :mod:`glob` module finds all the pathnames matching a specified pattern -according to the rules used by the Unix shell. No tilde expansion is done, but -``*``, ``?``, and character ranges expressed with ``[]`` will be correctly -matched. This is done by using the :func:`os.listdir` and -:func:`fnmatch.fnmatch` functions in concert, and not by actually invoking a -subshell. Note that unlike :func:`fnmatch.fnmatch`, :mod:`glob` treats -filenames beginning with a dot (``.``) as special cases. (For tilde and shell -variable expansion, use :func:`os.path.expanduser` and +according to the rules used by the Unix shell, although results are returned in +arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character +ranges expressed with ``[]`` will be correctly matched. This is done by using +the :func:`os.listdir` and :func:`fnmatch.fnmatch` functions in concert, and +not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, +:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +(For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) For a literal match, wrap the meta-characters in brackets. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 19:31:53 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 00:31:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjE1?= =?utf-8?q?=3A_Document_unsorted_behaviour_of_glob=3B_patch_by_Dave_Jones?= Message-ID: <20151117002051.14349.71698@psf.io> https://hg.python.org/cpython/rev/fa4f0096b719 changeset: 99180:fa4f0096b719 branch: 2.7 parent: 99164:483a5cd9f975 user: Martin Panter date: Mon Nov 16 23:46:22 2015 +0000 summary: Issue #25615: Document unsorted behaviour of glob; patch by Dave Jones files: Doc/library/glob.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -12,13 +12,13 @@ -------------- The :mod:`glob` module finds all the pathnames matching a specified pattern -according to the rules used by the Unix shell. No tilde expansion is done, but -``*``, ``?``, and character ranges expressed with ``[]`` will be correctly -matched. This is done by using the :func:`os.listdir` and -:func:`fnmatch.fnmatch` functions in concert, and not by actually invoking a -subshell. Note that unlike :func:`fnmatch.fnmatch`, :mod:`glob` treats -filenames beginning with a dot (``.``) as special cases. (For tilde and shell -variable expansion, use :func:`os.path.expanduser` and +according to the rules used by the Unix shell, although results are returned in +arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character +ranges expressed with ``[]`` will be correctly matched. This is done by using +the :func:`os.listdir` and :func:`fnmatch.fnmatch` functions in concert, and +not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, +:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +(For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) For a literal match, wrap the meta-characters in brackets. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 16 19:31:53 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 00:31:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325615=3A_Merge_glob_doc_from_3=2E4_into_3=2E5?= Message-ID: <20151117002051.14359.9850@psf.io> https://hg.python.org/cpython/rev/f928dcb448a9 changeset: 99182:f928dcb448a9 branch: 3.5 parent: 99178:4f8c871616e8 parent: 99181:7ca6a13db0e5 user: Martin Panter date: Tue Nov 17 00:19:10 2015 +0000 summary: Issue #25615: Merge glob doc from 3.4 into 3.5 files: Doc/library/glob.rst | 14 +++++++------- 1 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Doc/library/glob.rst b/Doc/library/glob.rst --- a/Doc/library/glob.rst +++ b/Doc/library/glob.rst @@ -12,13 +12,13 @@ -------------- The :mod:`glob` module finds all the pathnames matching a specified pattern -according to the rules used by the Unix shell. No tilde expansion is done, but -``*``, ``?``, and character ranges expressed with ``[]`` will be correctly -matched. This is done by using the :func:`os.listdir` and -:func:`fnmatch.fnmatch` functions in concert, and not by actually invoking a -subshell. Note that unlike :func:`fnmatch.fnmatch`, :mod:`glob` treats -filenames beginning with a dot (``.``) as special cases. (For tilde and shell -variable expansion, use :func:`os.path.expanduser` and +according to the rules used by the Unix shell, although results are returned in +arbitrary order. No tilde expansion is done, but ``*``, ``?``, and character +ranges expressed with ``[]`` will be correctly matched. This is done by using +the :func:`os.listdir` and :func:`fnmatch.fnmatch` functions in concert, and +not by actually invoking a subshell. Note that unlike :func:`fnmatch.fnmatch`, +:mod:`glob` treats filenames beginning with a dot (``.``) as special cases. +(For tilde and shell variable expansion, use :func:`os.path.expanduser` and :func:`os.path.expandvars`.) For a literal match, wrap the meta-characters in brackets. -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Tue Nov 17 03:45:08 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 17 Nov 2015 08:45:08 +0000 Subject: [Python-checkins] Daily reference leaks (a6bc96c2b8be): sum=2 Message-ID: <20151117084508.4669.85379@psf.io> results for a6bc96c2b8be on branch "default" -------------------------------------------- test_asyncio leaked [0, 3, 0] memory blocks, sum=3 test_capi leaked [1, 1, 1] references, sum=3 test_collections leaked [-6, 0, 0] references, sum=-6 test_collections leaked [-3, 1, 0] memory blocks, sum=-2 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogTBkGxj', '--timeout', '7200'] From victor.stinner at gmail.com Tue Nov 17 05:24:07 2015 From: victor.stinner at gmail.com (Victor Stinner) Date: Tue, 17 Nov 2015 11:24:07 +0100 Subject: [Python-checkins] [Python-Dev] Daily reference leaks (97e2a6810f7f): sum=10 In-Reply-To: References: <20151116084238.37478.4533@psf.io> Message-ID: Hi, I opened the http://bugs.python.org/issue25645 It looks like a simple regression in _pickle. I wrote a patch. Victor 2015-11-16 19:49 GMT+01:00 Brett Cannon : > Just an FYI there seems to be a consistent, minor refcount leak found by > test_capi that has been there for what seems like a couple of weeks. > > On Mon, 16 Nov 2015 at 00:42 wrote: >> >> results for 97e2a6810f7f on branch "default" >> -------------------------------------------- >> >> test_asyncio leaked [0, 0, 3] memory blocks, sum=3 >> test_capi leaked [1, 1, 1] references, sum=3 >> test_functools leaked [0, 2, 2] memory blocks, sum=4 >> >> >> Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', >> '3:3:/home/psf-users/antoine/refleaks/reflogBLsY2a', '--timeout', '7200'] >> _______________________________________________ >> Python-checkins mailing list >> Python-checkins at python.org >> https://mail.python.org/mailman/listinfo/python-checkins > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/victor.stinner%40gmail.com > From python-checkins at python.org Tue Nov 17 06:15:16 2015 From: python-checkins at python.org (victor.stinner) Date: Tue, 17 Nov 2015 11:15:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Closes_=2325645=3A_Fix_a_r?= =?utf-8?q?eference_leak_introduced_by_change_bc5894a3a0e6_of_the?= Message-ID: <20151117111516.14355.28561@psf.io> https://hg.python.org/cpython/rev/7adc1d24d05b changeset: 99184:7adc1d24d05b user: Victor Stinner date: Tue Nov 17 12:15:07 2015 +0100 summary: Closes #25645: Fix a reference leak introduced by change bc5894a3a0e6 of the issue #24164. files: Modules/_pickle.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -193,6 +193,7 @@ Py_CLEAR(st->import_mapping_3to2); Py_CLEAR(st->codecs_encode); Py_CLEAR(st->getattr); + Py_CLEAR(st->partial); } /* Initialize the given pickle module state. */ -- Repository URL: https://hg.python.org/cpython From brett at snarky.ca Mon Nov 16 13:49:03 2015 From: brett at snarky.ca (Brett Cannon) Date: Mon, 16 Nov 2015 18:49:03 +0000 Subject: [Python-checkins] Daily reference leaks (97e2a6810f7f): sum=10 In-Reply-To: <20151116084238.37478.4533@psf.io> References: <20151116084238.37478.4533@psf.io> Message-ID: Just an FYI there seems to be a consistent, minor refcount leak found by test_capi that has been there for what seems like a couple of weeks. On Mon, 16 Nov 2015 at 00:42 wrote: > results for 97e2a6810f7f on branch "default" > -------------------------------------------- > > test_asyncio leaked [0, 0, 3] memory blocks, sum=3 > test_capi leaked [1, 1, 1] references, sum=3 > test_functools leaked [0, 2, 2] memory blocks, sum=4 > > > Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', > '3:3:/home/psf-users/antoine/refleaks/reflogBLsY2a', '--timeout', '7200'] > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > https://mail.python.org/mailman/listinfo/python-checkins > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python-checkins at python.org Tue Nov 17 11:28:04 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 17 Nov 2015 16:28:04 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325629=3A_Move_set?= =?utf-8?q?_fill/used_updates_out_of_inner_loop?= Message-ID: <20151117162802.105923.51577@psf.io> https://hg.python.org/cpython/rev/23d0cae3f8a1 changeset: 99185:23d0cae3f8a1 user: Raymond Hettinger date: Tue Nov 17 08:28:07 2015 -0800 summary: Issue #25629: Move set fill/used updates out of inner loop files: Objects/setobject.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Objects/setobject.c b/Objects/setobject.c --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -254,9 +254,10 @@ Internal routine used by set_table_resize() to insert an item which is known to be absent from the set. This routine also assumes that the set contains no deleted entries. Besides the performance benefit, -using set_insert_clean() in set_table_resize() is dangerous (SF bug #1456209). -Note that no refcounts are changed by this routine; if needed, the caller -is responsible for incref'ing `key`. +there is also safety benefit since using set_add_entry() risks making +a callback in the middle of a set_table_resize(), see issue 1456209. +The caller is responsible for updating the key's reference count and +the setobject's fill and used fields. */ static void set_insert_clean(PySetObject *so, PyObject *key, Py_hash_t hash) @@ -285,8 +286,6 @@ found_null: entry->key = key; entry->hash = hash; - so->fill++; - so->used++; } /* ======== End logic for probing the hash table ========================== */ @@ -356,8 +355,8 @@ /* Make the set empty, using the new table. */ assert(newtable != oldtable); memset(newtable, 0, sizeof(setentry) * newsize); - so->fill = 0; - so->used = 0; + so->fill = oldused; + so->used = oldused; so->mask = newsize - 1; so->table = newtable; @@ -676,6 +675,8 @@ /* If our table is empty, we can use set_insert_clean() */ if (so->fill == 0) { + so->fill = other->used; + so->used = other->used; for (i = 0; i <= other->mask; i++, other_entry++) { key = other_entry->key; if (key != NULL && key != dummy) { -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:02:51 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:02:51 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogU3lu?= =?utf-8?q?c_with_github?= Message-ID: <20151117170250.21859.58298@psf.io> https://hg.python.org/cpython/rev/eab47e37ad91 changeset: 99186:eab47e37ad91 branch: 3.4 parent: 99181:7ca6a13db0e5 user: Yury Selivanov date: Tue Nov 17 12:02:21 2015 -0500 summary: asyncio: Sync with github files: Lib/asyncio/tasks.py | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,7 +93,6 @@ futures.Future.__del__(self) def _repr_info(self): - # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -222,7 +221,6 @@ return True def _step(self, value=None, exc=None): - # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -286,7 +284,6 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): - # Private method, do not use it. try: future.result() except Exception as exc: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:02:51 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:02:51 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151117170251.21845.69635@psf.io> https://hg.python.org/cpython/rev/3d5a7871a06e changeset: 99188:3d5a7871a06e parent: 99185:23d0cae3f8a1 parent: 99187:ed3d7bd08248 user: Yury Selivanov date: Tue Nov 17 12:02:44 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/tasks.py | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,7 +93,6 @@ futures.Future.__del__(self) def _repr_info(self): - # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -222,7 +221,6 @@ return True def _step(self, value=None, exc=None): - # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -286,7 +284,6 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): - # Private method, do not use it. try: future.result() except Exception as exc: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:02:51 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:02:51 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151117170250.4667.1538@psf.io> https://hg.python.org/cpython/rev/ed3d7bd08248 changeset: 99187:ed3d7bd08248 branch: 3.5 parent: 99182:f928dcb448a9 parent: 99186:eab47e37ad91 user: Yury Selivanov date: Tue Nov 17 12:02:32 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/tasks.py | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -93,7 +93,6 @@ futures.Future.__del__(self) def _repr_info(self): - # Private method, do not use it. info = super()._repr_info() if self._must_cancel: @@ -222,7 +221,6 @@ return True def _step(self, value=None, exc=None): - # Private method, do not use it. assert not self.done(), \ '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) if self._must_cancel: @@ -286,7 +284,6 @@ self = None # Needed to break cycles when an exception occurs. def _wakeup(self, future): - # Private method, do not use it. try: future.result() except Exception as exc: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:20:34 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:20:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogQ2xl?= =?utf-8?q?anup_Future_API?= Message-ID: <20151117172033.21871.73793@psf.io> https://hg.python.org/cpython/rev/d05d2cc8df72 changeset: 99189:d05d2cc8df72 branch: 3.4 parent: 99186:eab47e37ad91 user: Yury Selivanov date: Tue Nov 17 12:19:41 2015 -0500 summary: asyncio: Cleanup Future API See https://github.com/python/asyncio/pull/292 for details. files: Lib/asyncio/futures.py | 60 +++++++------- Lib/asyncio/proactor_events.py | 3 +- Lib/asyncio/selector_events.py | 6 +- Lib/asyncio/tasks.py | 3 +- Lib/asyncio/unix_events.py | 6 +- Lib/test/test_asyncio/test_futures.py | 11 +- 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -154,7 +154,7 @@ if self._loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def _format_callbacks(self): + def __format_callbacks(self): cb = self._callbacks size = len(cb) if not size: @@ -184,7 +184,7 @@ result = reprlib.repr(self._result) info.append('result={}'.format(result)) if self._callbacks: - info.append(self._format_callbacks()) + info.append(self.__format_callbacks()) if self._source_traceback: frame = self._source_traceback[-1] info.append('created at %s:%s' % (frame[0], frame[1])) @@ -319,12 +319,6 @@ # So-called internal methods (note: no set_running_or_notify_cancel()). - def _set_result_unless_cancelled(self, result): - """Helper setting the result only if the future was not cancelled.""" - if self.cancelled(): - return - self.set_result(result) - def set_result(self, result): """Mark the future done and set its result. @@ -358,27 +352,6 @@ # have had a chance to call result() or exception(). self._loop.call_soon(self._tb_logger.activate) - # Truly internal methods. - - def _copy_state(self, other): - """Internal helper to copy state from another Future. - - The other Future may be a concurrent.futures.Future. - """ - assert other.done() - if self.cancelled(): - return - assert not self.done() - if other.cancelled(): - self.cancel() - else: - exception = other.exception() - if exception is not None: - self.set_exception(exception) - else: - result = other.result() - self.set_result(result) - def __iter__(self): if not self.done(): self._blocking = True @@ -390,6 +363,13 @@ __await__ = __iter__ # make compatible with 'await' expression +def _set_result_unless_cancelled(fut, result): + """Helper setting the result only if the future was not cancelled.""" + if fut.cancelled(): + return + fut.set_result(result) + + def _set_concurrent_future_state(concurrent, source): """Copy state from a future to a concurrent.futures.Future.""" assert source.done() @@ -405,6 +385,26 @@ concurrent.set_result(result) +def _copy_future_state(source, dest): + """Internal helper to copy state from another Future. + + The other Future may be a concurrent.futures.Future. + """ + assert source.done() + if dest.cancelled(): + return + assert not dest.done() + if source.cancelled(): + dest.cancel() + else: + exception = source.exception() + if exception is not None: + dest.set_exception(exception) + else: + result = source.result() + dest.set_result(result) + + def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. @@ -421,7 +421,7 @@ def _set_state(future, other): if isinstance(future, Future): - future._copy_state(other) + _copy_future_state(other, future) else: _set_concurrent_future_state(future, other) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -41,7 +41,8 @@ self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -636,7 +636,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def pause_reading(self): if self._closing: @@ -990,7 +991,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def get_write_buffer_size(self): return sum(len(data) for data, _ in self._buffer) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -500,7 +500,8 @@ future = futures.Future(loop=loop) h = future._loop.call_later(delay, - future._set_result_unless_cancelled, result) + futures._set_result_unless_cancelled, + future, result) try: return (yield from future) finally: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -319,7 +319,8 @@ self._fileno, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] @@ -442,7 +443,8 @@ if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -174,11 +174,13 @@ '') def test_copy_state(self): + from asyncio.futures import _copy_future_state + f = asyncio.Future(loop=self.loop) f.set_result(10) newf = asyncio.Future(loop=self.loop) - newf._copy_state(f) + _copy_future_state(f, newf) self.assertTrue(newf.done()) self.assertEqual(newf.result(), 10) @@ -186,7 +188,7 @@ f_exception.set_exception(RuntimeError()) newf_exception = asyncio.Future(loop=self.loop) - newf_exception._copy_state(f_exception) + _copy_future_state(f_exception, newf_exception) self.assertTrue(newf_exception.done()) self.assertRaises(RuntimeError, newf_exception.result) @@ -194,7 +196,7 @@ f_cancelled.cancel() newf_cancelled = asyncio.Future(loop=self.loop) - newf_cancelled._copy_state(f_cancelled) + _copy_future_state(f_cancelled, newf_cancelled) self.assertTrue(newf_cancelled.cancelled()) def test_iter(self): @@ -382,9 +384,10 @@ self.check_future_exception_never_retrieved(True) def test_set_result_unless_cancelled(self): + from asyncio import futures fut = asyncio.Future(loop=self.loop) fut.cancel() - fut._set_result_unless_cancelled(2) + futures._set_result_unless_cancelled(fut, 2) self.assertTrue(fut.cancelled()) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:20:34 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:20:34 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151117172034.14377.41553@psf.io> https://hg.python.org/cpython/rev/8312e257cb18 changeset: 99191:8312e257cb18 parent: 99188:3d5a7871a06e parent: 99190:dc8701344c56 user: Yury Selivanov date: Tue Nov 17 12:20:26 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/futures.py | 60 +++++++------- Lib/asyncio/proactor_events.py | 3 +- Lib/asyncio/selector_events.py | 6 +- Lib/asyncio/tasks.py | 3 +- Lib/asyncio/unix_events.py | 6 +- Lib/test/test_asyncio/test_futures.py | 11 +- 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -154,7 +154,7 @@ if self._loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def _format_callbacks(self): + def __format_callbacks(self): cb = self._callbacks size = len(cb) if not size: @@ -184,7 +184,7 @@ result = reprlib.repr(self._result) info.append('result={}'.format(result)) if self._callbacks: - info.append(self._format_callbacks()) + info.append(self.__format_callbacks()) if self._source_traceback: frame = self._source_traceback[-1] info.append('created at %s:%s' % (frame[0], frame[1])) @@ -319,12 +319,6 @@ # So-called internal methods (note: no set_running_or_notify_cancel()). - def _set_result_unless_cancelled(self, result): - """Helper setting the result only if the future was not cancelled.""" - if self.cancelled(): - return - self.set_result(result) - def set_result(self, result): """Mark the future done and set its result. @@ -358,27 +352,6 @@ # have had a chance to call result() or exception(). self._loop.call_soon(self._tb_logger.activate) - # Truly internal methods. - - def _copy_state(self, other): - """Internal helper to copy state from another Future. - - The other Future may be a concurrent.futures.Future. - """ - assert other.done() - if self.cancelled(): - return - assert not self.done() - if other.cancelled(): - self.cancel() - else: - exception = other.exception() - if exception is not None: - self.set_exception(exception) - else: - result = other.result() - self.set_result(result) - def __iter__(self): if not self.done(): self._blocking = True @@ -390,6 +363,13 @@ __await__ = __iter__ # make compatible with 'await' expression +def _set_result_unless_cancelled(fut, result): + """Helper setting the result only if the future was not cancelled.""" + if fut.cancelled(): + return + fut.set_result(result) + + def _set_concurrent_future_state(concurrent, source): """Copy state from a future to a concurrent.futures.Future.""" assert source.done() @@ -405,6 +385,26 @@ concurrent.set_result(result) +def _copy_future_state(source, dest): + """Internal helper to copy state from another Future. + + The other Future may be a concurrent.futures.Future. + """ + assert source.done() + if dest.cancelled(): + return + assert not dest.done() + if source.cancelled(): + dest.cancel() + else: + exception = source.exception() + if exception is not None: + dest.set_exception(exception) + else: + result = source.result() + dest.set_result(result) + + def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. @@ -421,7 +421,7 @@ def _set_state(future, other): if isinstance(future, Future): - future._copy_state(other) + _copy_future_state(other, future) else: _set_concurrent_future_state(future, other) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -41,7 +41,8 @@ self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -636,7 +636,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def pause_reading(self): if self._closing: @@ -990,7 +991,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def get_write_buffer_size(self): return sum(len(data) for data, _ in self._buffer) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -500,7 +500,8 @@ future = futures.Future(loop=loop) h = future._loop.call_later(delay, - future._set_result_unless_cancelled, result) + futures._set_result_unless_cancelled, + future, result) try: return (yield from future) finally: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -319,7 +319,8 @@ self._fileno, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] @@ -442,7 +443,8 @@ if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -174,11 +174,13 @@ '') def test_copy_state(self): + from asyncio.futures import _copy_future_state + f = asyncio.Future(loop=self.loop) f.set_result(10) newf = asyncio.Future(loop=self.loop) - newf._copy_state(f) + _copy_future_state(f, newf) self.assertTrue(newf.done()) self.assertEqual(newf.result(), 10) @@ -186,7 +188,7 @@ f_exception.set_exception(RuntimeError()) newf_exception = asyncio.Future(loop=self.loop) - newf_exception._copy_state(f_exception) + _copy_future_state(f_exception, newf_exception) self.assertTrue(newf_exception.done()) self.assertRaises(RuntimeError, newf_exception.result) @@ -194,7 +196,7 @@ f_cancelled.cancel() newf_cancelled = asyncio.Future(loop=self.loop) - newf_cancelled._copy_state(f_cancelled) + _copy_future_state(f_cancelled, newf_cancelled) self.assertTrue(newf_cancelled.cancelled()) def test_iter(self): @@ -382,9 +384,10 @@ self.check_future_exception_never_retrieved(True) def test_set_result_unless_cancelled(self): + from asyncio import futures fut = asyncio.Future(loop=self.loop) fut.cancel() - fut._set_result_unless_cancelled(2) + futures._set_result_unless_cancelled(fut, 2) self.assertTrue(fut.cancelled()) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 12:20:38 2015 From: python-checkins at python.org (yury.selivanov) Date: Tue, 17 Nov 2015 17:20:38 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151117172034.63494.28527@psf.io> https://hg.python.org/cpython/rev/dc8701344c56 changeset: 99190:dc8701344c56 branch: 3.5 parent: 99187:ed3d7bd08248 parent: 99189:d05d2cc8df72 user: Yury Selivanov date: Tue Nov 17 12:20:02 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/futures.py | 60 +++++++------- Lib/asyncio/proactor_events.py | 3 +- Lib/asyncio/selector_events.py | 6 +- Lib/asyncio/tasks.py | 3 +- Lib/asyncio/unix_events.py | 6 +- Lib/test/test_asyncio/test_futures.py | 11 +- 6 files changed, 49 insertions(+), 40 deletions(-) diff --git a/Lib/asyncio/futures.py b/Lib/asyncio/futures.py --- a/Lib/asyncio/futures.py +++ b/Lib/asyncio/futures.py @@ -154,7 +154,7 @@ if self._loop.get_debug(): self._source_traceback = traceback.extract_stack(sys._getframe(1)) - def _format_callbacks(self): + def __format_callbacks(self): cb = self._callbacks size = len(cb) if not size: @@ -184,7 +184,7 @@ result = reprlib.repr(self._result) info.append('result={}'.format(result)) if self._callbacks: - info.append(self._format_callbacks()) + info.append(self.__format_callbacks()) if self._source_traceback: frame = self._source_traceback[-1] info.append('created at %s:%s' % (frame[0], frame[1])) @@ -319,12 +319,6 @@ # So-called internal methods (note: no set_running_or_notify_cancel()). - def _set_result_unless_cancelled(self, result): - """Helper setting the result only if the future was not cancelled.""" - if self.cancelled(): - return - self.set_result(result) - def set_result(self, result): """Mark the future done and set its result. @@ -358,27 +352,6 @@ # have had a chance to call result() or exception(). self._loop.call_soon(self._tb_logger.activate) - # Truly internal methods. - - def _copy_state(self, other): - """Internal helper to copy state from another Future. - - The other Future may be a concurrent.futures.Future. - """ - assert other.done() - if self.cancelled(): - return - assert not self.done() - if other.cancelled(): - self.cancel() - else: - exception = other.exception() - if exception is not None: - self.set_exception(exception) - else: - result = other.result() - self.set_result(result) - def __iter__(self): if not self.done(): self._blocking = True @@ -390,6 +363,13 @@ __await__ = __iter__ # make compatible with 'await' expression +def _set_result_unless_cancelled(fut, result): + """Helper setting the result only if the future was not cancelled.""" + if fut.cancelled(): + return + fut.set_result(result) + + def _set_concurrent_future_state(concurrent, source): """Copy state from a future to a concurrent.futures.Future.""" assert source.done() @@ -405,6 +385,26 @@ concurrent.set_result(result) +def _copy_future_state(source, dest): + """Internal helper to copy state from another Future. + + The other Future may be a concurrent.futures.Future. + """ + assert source.done() + if dest.cancelled(): + return + assert not dest.done() + if source.cancelled(): + dest.cancel() + else: + exception = source.exception() + if exception is not None: + dest.set_exception(exception) + else: + result = source.result() + dest.set_result(result) + + def _chain_future(source, destination): """Chain two futures so that when one completes, so does the other. @@ -421,7 +421,7 @@ def _set_state(future, other): if isinstance(future, Future): - future._copy_state(other) + _copy_future_state(other, future) else: _set_concurrent_future_state(future, other) diff --git a/Lib/asyncio/proactor_events.py b/Lib/asyncio/proactor_events.py --- a/Lib/asyncio/proactor_events.py +++ b/Lib/asyncio/proactor_events.py @@ -41,7 +41,8 @@ self._loop.call_soon(self._protocol.connection_made, self) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py --- a/Lib/asyncio/selector_events.py +++ b/Lib/asyncio/selector_events.py @@ -636,7 +636,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def pause_reading(self): if self._closing: @@ -990,7 +991,8 @@ self._sock_fd, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def get_write_buffer_size(self): return sum(len(data) for data, _ in self._buffer) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -500,7 +500,8 @@ future = futures.Future(loop=loop) h = future._loop.call_later(delay, - future._set_result_unless_cancelled, result) + futures._set_result_unless_cancelled, + future, result) try: return (yield from future) finally: diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py +++ b/Lib/asyncio/unix_events.py @@ -319,7 +319,8 @@ self._fileno, self._read_ready) if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] @@ -442,7 +443,8 @@ if waiter is not None: # only wake up the waiter when connection_made() has been called - self._loop.call_soon(waiter._set_result_unless_cancelled, None) + self._loop.call_soon(futures._set_result_unless_cancelled, + waiter, None) def __repr__(self): info = [self.__class__.__name__] diff --git a/Lib/test/test_asyncio/test_futures.py b/Lib/test/test_asyncio/test_futures.py --- a/Lib/test/test_asyncio/test_futures.py +++ b/Lib/test/test_asyncio/test_futures.py @@ -174,11 +174,13 @@ '') def test_copy_state(self): + from asyncio.futures import _copy_future_state + f = asyncio.Future(loop=self.loop) f.set_result(10) newf = asyncio.Future(loop=self.loop) - newf._copy_state(f) + _copy_future_state(f, newf) self.assertTrue(newf.done()) self.assertEqual(newf.result(), 10) @@ -186,7 +188,7 @@ f_exception.set_exception(RuntimeError()) newf_exception = asyncio.Future(loop=self.loop) - newf_exception._copy_state(f_exception) + _copy_future_state(f_exception, newf_exception) self.assertTrue(newf_exception.done()) self.assertRaises(RuntimeError, newf_exception.result) @@ -194,7 +196,7 @@ f_cancelled.cancel() newf_cancelled = asyncio.Future(loop=self.loop) - newf_cancelled._copy_state(f_cancelled) + _copy_future_state(f_cancelled, newf_cancelled) self.assertTrue(newf_cancelled.cancelled()) def test_iter(self): @@ -382,9 +384,10 @@ self.check_future_exception_never_retrieved(True) def test_set_result_unless_cancelled(self): + from asyncio import futures fut = asyncio.Future(loop=self.loop) fut.cancel() - fut._set_result_unless_cancelled(2) + futures._set_result_unless_cancelled(fut, 2) self.assertTrue(fut.cancelled()) -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Tue Nov 17 16:11:57 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 17 Nov 2015 21:11:57 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-17 Message-ID: <5b3a2e35-7754-45a3-975f-282da3842d0a@irsmsx105.ger.corp.intel.com> Results for project Python default, build date 2015-11-17 04:02:25 +0000 commit: a6bc96c2b8be97cde057409a7b715bd5e27147cd revision date: 2015-11-17 00:19:27 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.40% 3.47% 11.21% 13.30% :-| pybench 0.10% 0.89% -1.52% 8.34% :-( regex_v8 3.62% -0.58% -4.67% 6.30% :-| nbody 0.11% -0.20% -0.26% 7.43% :-| json_dump_v2 0.21% 0.39% 0.02% 10.12% :-| normal_startup 0.73% 0.68% 1.15% 4.76% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Tue Nov 17 16:12:37 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 17 Nov 2015 21:12:37 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-17 Message-ID: <55557d64-2661-4abb-a19e-0e4639371500@irsmsx105.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-17 04:49:35 +0000 commit: fa4f0096b7192dae082244ec3b9b49f959d48d2c revision date: 2015-11-16 23:46:22 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% -0.23% 2.59% 10.50% :-) pybench 0.20% -0.05% 6.44% 6.40% :-( regex_v8 0.59% 0.11% -2.00% 8.41% :-) nbody 0.15% 0.01% 9.10% 1.65% :-) json_dump_v2 0.28% 0.04% 3.65% 12.33% :-| normal_startup 1.96% -0.32% -1.94% 3.34% :-| ssbench 0.32% -1.00% -0.13% 1.07% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Tue Nov 17 17:43:19 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 22:43:19 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIwNDY4?= =?utf-8?q?=3A_Remove_incorrect_information_about_maxrss_and_page_size?= Message-ID: <20151117224319.79033.10114@psf.io> https://hg.python.org/cpython/rev/5e8b06ac7c97 changeset: 99192:5e8b06ac7c97 branch: 3.4 parent: 99189:d05d2cc8df72 user: Martin Panter date: Tue Nov 17 22:13:47 2015 +0000 summary: Issue #20468: Remove incorrect information about maxrss and page size Extract of patch by Ronald Oussoren. files: Doc/library/resource.rst | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -316,10 +316,7 @@ .. function:: getpagesize() Returns the number of bytes in a system page. (This need not be the same as the - hardware page size.) This function is useful for determining the number of bytes - of memory a process is using. The third element of the tuple returned by - :func:`getrusage` describes memory usage in pages; multiplying by page size - produces number of bytes. + hardware page size.) The following :const:`RUSAGE_\*` symbols are passed to the :func:`getrusage` function to specify which processes information should be provided for. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 17:43:19 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 22:43:19 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2320468=3A_Merge_getpagesize_doc_from_3=2E4_into_3=2E5?= Message-ID: <20151117224319.18210.7819@psf.io> https://hg.python.org/cpython/rev/1579de0b72f6 changeset: 99193:1579de0b72f6 branch: 3.5 parent: 99190:dc8701344c56 parent: 99192:5e8b06ac7c97 user: Martin Panter date: Tue Nov 17 22:23:21 2015 +0000 summary: Issue #20468: Merge getpagesize doc from 3.4 into 3.5 files: Doc/library/resource.rst | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -316,10 +316,7 @@ .. function:: getpagesize() Returns the number of bytes in a system page. (This need not be the same as the - hardware page size.) This function is useful for determining the number of bytes - of memory a process is using. The third element of the tuple returned by - :func:`getrusage` describes memory usage in pages; multiplying by page size - produces number of bytes. + hardware page size.) The following :const:`RUSAGE_\*` symbols are passed to the :func:`getrusage` function to specify which processes information should be provided for. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 17:43:20 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 22:43:20 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2320468=3A_Merge_getpagesize_doc_from_3=2E5?= Message-ID: <20151117224319.63492.97200@psf.io> https://hg.python.org/cpython/rev/007dfc0ef1be changeset: 99194:007dfc0ef1be parent: 99191:8312e257cb18 parent: 99193:1579de0b72f6 user: Martin Panter date: Tue Nov 17 22:26:23 2015 +0000 summary: Issue #20468: Merge getpagesize doc from 3.5 files: Doc/library/resource.rst | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -316,10 +316,7 @@ .. function:: getpagesize() Returns the number of bytes in a system page. (This need not be the same as the - hardware page size.) This function is useful for determining the number of bytes - of memory a process is using. The third element of the tuple returned by - :func:`getrusage` describes memory usage in pages; multiplying by page size - produces number of bytes. + hardware page size.) The following :const:`RUSAGE_\*` symbols are passed to the :func:`getrusage` function to specify which processes information should be provided for. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 17:43:20 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 17 Nov 2015 22:43:20 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIwNDY4?= =?utf-8?q?=3A_Remove_incorrect_information_about_maxrss_and_page_size?= Message-ID: <20151117224320.105901.22562@psf.io> https://hg.python.org/cpython/rev/58d017d70563 changeset: 99195:58d017d70563 branch: 2.7 parent: 99180:fa4f0096b719 user: Martin Panter date: Tue Nov 17 22:13:47 2015 +0000 summary: Issue #20468: Remove incorrect information about maxrss and page size Extract of patch by Ronald Oussoren. files: Doc/library/resource.rst | 5 +---- 1 files changed, 1 insertions(+), 4 deletions(-) diff --git a/Doc/library/resource.rst b/Doc/library/resource.rst --- a/Doc/library/resource.rst +++ b/Doc/library/resource.rst @@ -223,10 +223,7 @@ .. function:: getpagesize() Returns the number of bytes in a system page. (This need not be the same as the - hardware page size.) This function is useful for determining the number of bytes - of memory a process is using. The third element of the tuple returned by - :func:`getrusage` describes memory usage in pages; multiplying by page size - produces number of bytes. + hardware page size.) The following :const:`RUSAGE_\*` symbols are passed to the :func:`getrusage` function to specify which processes information should be provided for. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 21:59:10 2015 From: python-checkins at python.org (martin.panter) Date: Wed, 18 Nov 2015 02:59:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2323200=3A_Merge_zlib_doc_from_3=2E5?= Message-ID: <20151118025910.18214.76701@psf.io> https://hg.python.org/cpython/rev/cdd403dd82cb changeset: 99199:cdd403dd82cb parent: 99194:007dfc0ef1be parent: 99198:d64bb25cf797 user: Martin Panter date: Wed Nov 18 02:46:16 2015 +0000 summary: Issue #23200: Merge zlib doc from 3.5 files: Doc/library/zlib.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -230,7 +230,7 @@ :meth:`decompress` method. Some of the input data may be preserved in internal buffers for later processing. - If the optional parameter *max_length* is supplied then the return value will be + If the optional parameter *max_length* is non-zero then the return value will be no longer than *max_length*. This may mean that not all of the compressed input can be processed; and unconsumed data will be stored in the attribute :attr:`unconsumed_tail`. This bytestring must be passed to a subsequent call to -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 21:59:10 2015 From: python-checkins at python.org (martin.panter) Date: Wed, 18 Nov 2015 02:59:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIzMjAw?= =?utf-8?q?=3A_Document_that_max=5Flength=3D0_is_not_supported?= Message-ID: <20151118025909.21851.94775@psf.io> https://hg.python.org/cpython/rev/106c49edbb12 changeset: 99196:106c49edbb12 branch: 2.7 user: Martin Panter date: Wed Nov 18 00:59:17 2015 +0000 summary: Issue #23200: Document that max_length=0 is not supported files: Doc/library/zlib.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -221,7 +221,7 @@ :meth:`decompress` method. Some of the input data may be preserved in internal buffers for later processing. - If the optional parameter *max_length* is supplied then the return value will be + If the optional parameter *max_length* is non-zero then the return value will be no longer than *max_length*. This may mean that not all of the compressed input can be processed; and unconsumed data will be stored in the attribute :attr:`unconsumed_tail`. This string must be passed to a subsequent call to -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 21:59:10 2015 From: python-checkins at python.org (martin.panter) Date: Wed, 18 Nov 2015 02:59:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2323200=3A_Merge_zlib_doc_from_3=2E4_into_3=2E5?= Message-ID: <20151118025910.4539.8528@psf.io> https://hg.python.org/cpython/rev/d64bb25cf797 changeset: 99198:d64bb25cf797 branch: 3.5 parent: 99193:1579de0b72f6 parent: 99197:660bdfaada64 user: Martin Panter date: Wed Nov 18 02:45:51 2015 +0000 summary: Issue #23200: Merge zlib doc from 3.4 into 3.5 files: Doc/library/zlib.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -230,7 +230,7 @@ :meth:`decompress` method. Some of the input data may be preserved in internal buffers for later processing. - If the optional parameter *max_length* is supplied then the return value will be + If the optional parameter *max_length* is non-zero then the return value will be no longer than *max_length*. This may mean that not all of the compressed input can be processed; and unconsumed data will be stored in the attribute :attr:`unconsumed_tail`. This bytestring must be passed to a subsequent call to -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 21:59:10 2015 From: python-checkins at python.org (martin.panter) Date: Wed, 18 Nov 2015 02:59:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIzMjAw?= =?utf-8?q?=3A_Document_that_max=5Flength=3D0_is_not_supported?= Message-ID: <20151118025910.79031.50683@psf.io> https://hg.python.org/cpython/rev/660bdfaada64 changeset: 99197:660bdfaada64 branch: 3.4 parent: 99192:5e8b06ac7c97 user: Martin Panter date: Wed Nov 18 00:59:17 2015 +0000 summary: Issue #23200: Document that max_length=0 is not supported files: Doc/library/zlib.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/zlib.rst b/Doc/library/zlib.rst --- a/Doc/library/zlib.rst +++ b/Doc/library/zlib.rst @@ -230,7 +230,7 @@ :meth:`decompress` method. Some of the input data may be preserved in internal buffers for later processing. - If the optional parameter *max_length* is supplied then the return value will be + If the optional parameter *max_length* is non-zero then the return value will be no longer than *max_length*. This may mean that not all of the compressed input can be processed; and unconsumed data will be stored in the attribute :attr:`unconsumed_tail`. This bytestring must be passed to a subsequent call to -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 17 23:58:35 2015 From: python-checkins at python.org (raymond.hettinger) Date: Wed, 18 Nov 2015 04:58:35 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Add_assertion_to_verify_th?= =?utf-8?q?e_pre-condition_in_the_comments=2E?= Message-ID: <20151118045835.31749.94551@psf.io> https://hg.python.org/cpython/rev/9d8eda95dd00 changeset: 99200:9d8eda95dd00 user: Raymond Hettinger date: Tue Nov 17 20:58:43 2015 -0800 summary: Add assertion to verify the pre-condition in the comments. files: Objects/setobject.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Objects/setobject.c b/Objects/setobject.c --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -269,6 +269,7 @@ size_t i = (size_t)hash & mask; size_t j; + assert(so->fill == so->used); while (1) { entry = &table[i]; if (entry->key == NULL) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Wed Nov 18 03:44:29 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 18 Nov 2015 08:44:29 +0000 Subject: [Python-checkins] Daily reference leaks (9d8eda95dd00): sum=4 Message-ID: <20151118084429.63512.57327@psf.io> results for 9d8eda95dd00 on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogkTBHSl', '--timeout', '7200'] From lp_benchmark_robot at intel.com Wed Nov 18 11:11:16 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 18 Nov 2015 16:11:16 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-18 Message-ID: <88d100fe-2b5b-4096-b42b-3397cde039ea@irsmsx153.ger.corp.intel.com> Results for project Python default, build date 2015-11-18 04:03:15 +0000 commit: cdd403dd82cbce0c14cdab18a23476af0dbd3578 revision date: 2015-11-18 02:46:16 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.38% 0.30% 11.48% 15.51% :-| pybench 0.12% -0.11% -1.63% 8.52% :-( regex_v8 2.68% 0.56% -4.08% 5.80% :-| nbody 0.17% -0.53% -0.79% 8.76% :-| json_dump_v2 0.29% 0.87% 0.89% 8.98% :-| normal_startup 0.85% 0.09% 0.94% 4.73% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Wed Nov 18 11:12:52 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 18 Nov 2015 16:12:52 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-18 Message-ID: <94eab27a-146f-4da9-bae9-cfe31fd15059@irsmsx153.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-18 09:01:47 +0000 commit: 106c49edbb12fdab1c19ec34bacc559ca1a87a84 revision date: 2015-11-18 00:59:17 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.19% 1.28% 3.84% 9.57% :-) pybench 0.19% -0.03% 6.41% 7.28% :-( regex_v8 0.56% -0.16% -2.17% 8.09% :-) nbody 0.53% -0.60% 8.55% 3.13% :-) json_dump_v2 0.24% -0.00% 3.65% 12.93% :-| normal_startup 7.64% 1.73% -0.18% 5.67% :-| ssbench 0.32% 1.15% 1.01% 1.19% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Wed Nov 18 12:40:46 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:40:46 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogRXJy?= =?utf-8?q?or_if_awaiting_in_parallel_on_the_same_coroutine?= Message-ID: <20151118174046.21853.69593@psf.io> https://hg.python.org/cpython/rev/89d66f912671 changeset: 99201:89d66f912671 branch: 3.4 parent: 99197:660bdfaada64 user: Yury Selivanov date: Wed Nov 18 12:39:45 2015 -0500 summary: asyncio: Error if awaiting in parallel on the same coroutine This change won't do anything in CPython 3.4 See https://github.com/python/asyncio/pull/293 for details. files: Lib/asyncio/coroutines.py | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -140,7 +140,13 @@ if compat.PY35: - __await__ = __iter__ # make compatible with 'await' expression + def __await__(self): + cr_await = getattr(self.gen, 'cr_await', None) + if cr_await is not None: + raise RuntimeError( + "Cannot await on coroutine {!r} while it's " + "awaiting for {!r}".format(self.gen, cr_await)) + return self @property def gi_yieldfrom(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 12:40:46 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:40:46 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151118174046.4659.28400@psf.io> https://hg.python.org/cpython/rev/de08cfd2e94f changeset: 99203:de08cfd2e94f parent: 99200:9d8eda95dd00 parent: 99202:6875b0bd3cd0 user: Yury Selivanov date: Wed Nov 18 12:40:41 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/coroutines.py | 8 +++++- Lib/test/test_asyncio/test_pep492.py | 20 ++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletions(-) diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -140,7 +140,13 @@ if compat.PY35: - __await__ = __iter__ # make compatible with 'await' expression + def __await__(self): + cr_await = getattr(self.gen, 'cr_await', None) + if cr_await is not None: + raise RuntimeError( + "Cannot await on coroutine {!r} while it's " + "awaiting for {!r}".format(self.gen, cr_await)) + return self @property def gi_yieldfrom(self): diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -203,6 +203,26 @@ self.loop.run_until_complete(runner()) + def test_double_await(self): + async def afunc(): + await asyncio.sleep(0.1, loop=self.loop) + + async def runner(): + coro = afunc() + t = asyncio.Task(coro, loop=self.loop) + try: + await asyncio.sleep(0, loop=self.loop) + await coro + finally: + t.cancel() + + self.loop.set_debug(True) + with self.assertRaisesRegex( + RuntimeError, + r'Cannot await.*test_double_await.*\bafunc\b.*while.*\bsleep\b'): + + self.loop.run_until_complete(runner()) + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 12:40:51 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:40:51 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_asyncio=3A_Error_if_awaiting_in_parallel_on_the_same_coroutine?= Message-ID: <20151118174046.79037.72552@psf.io> https://hg.python.org/cpython/rev/6875b0bd3cd0 changeset: 99202:6875b0bd3cd0 branch: 3.5 parent: 99198:d64bb25cf797 parent: 99201:89d66f912671 user: Yury Selivanov date: Wed Nov 18 12:40:26 2015 -0500 summary: asyncio: Error if awaiting in parallel on the same coroutine See https://github.com/python/asyncio/pull/293 for details. files: Lib/asyncio/coroutines.py | 8 +++++- Lib/test/test_asyncio/test_pep492.py | 20 ++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletions(-) diff --git a/Lib/asyncio/coroutines.py b/Lib/asyncio/coroutines.py --- a/Lib/asyncio/coroutines.py +++ b/Lib/asyncio/coroutines.py @@ -140,7 +140,13 @@ if compat.PY35: - __await__ = __iter__ # make compatible with 'await' expression + def __await__(self): + cr_await = getattr(self.gen, 'cr_await', None) + if cr_await is not None: + raise RuntimeError( + "Cannot await on coroutine {!r} while it's " + "awaiting for {!r}".format(self.gen, cr_await)) + return self @property def gi_yieldfrom(self): diff --git a/Lib/test/test_asyncio/test_pep492.py b/Lib/test/test_asyncio/test_pep492.py --- a/Lib/test/test_asyncio/test_pep492.py +++ b/Lib/test/test_asyncio/test_pep492.py @@ -203,6 +203,26 @@ self.loop.run_until_complete(runner()) + def test_double_await(self): + async def afunc(): + await asyncio.sleep(0.1, loop=self.loop) + + async def runner(): + coro = afunc() + t = asyncio.Task(coro, loop=self.loop) + try: + await asyncio.sleep(0, loop=self.loop) + await coro + finally: + t.cancel() + + self.loop.set_debug(True) + with self.assertRaisesRegex( + RuntimeError, + r'Cannot await.*test_double_await.*\bafunc\b.*while.*\bsleep\b'): + + self.loop.run_until_complete(runner()) + if __name__ == '__main__': unittest.main() -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 12:45:16 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:45:16 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpby5kb2Nz?= =?utf-8?q?=3A_Fix_versionadded?= Message-ID: <20151118174516.21855.43706@psf.io> https://hg.python.org/cpython/rev/b34c42e46e7b changeset: 99204:b34c42e46e7b branch: 3.4 parent: 99201:89d66f912671 user: Yury Selivanov date: Wed Nov 18 12:44:31 2015 -0500 summary: asyncio.docs: Fix versionadded files: Doc/library/asyncio-task.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -699,4 +699,4 @@ Unlike the functions above, :func:`run_coroutine_threadsafe` requires the *loop* argument to be passed explicitely. - .. versionadded:: 3.4.4 + .. versionadded:: 3.4.4, 3.5.1 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 12:45:17 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:45:17 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151118174516.63516.46663@psf.io> https://hg.python.org/cpython/rev/284187f3a783 changeset: 99206:284187f3a783 parent: 99203:de08cfd2e94f parent: 99205:4ae62ddf7bc7 user: Yury Selivanov date: Wed Nov 18 12:44:59 2015 -0500 summary: Merge 3.5 files: Doc/library/asyncio-task.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -721,4 +721,4 @@ Unlike the functions above, :func:`run_coroutine_threadsafe` requires the *loop* argument to be passed explicitely. - .. versionadded:: 3.4.4 + .. versionadded:: 3.4.4, 3.5.1 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 12:45:17 2015 From: python-checkins at python.org (yury.selivanov) Date: Wed, 18 Nov 2015 17:45:17 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151118174516.105903.93038@psf.io> https://hg.python.org/cpython/rev/4ae62ddf7bc7 changeset: 99205:4ae62ddf7bc7 branch: 3.5 parent: 99202:6875b0bd3cd0 parent: 99204:b34c42e46e7b user: Yury Selivanov date: Wed Nov 18 12:44:49 2015 -0500 summary: Merge 3.4 files: Doc/library/asyncio-task.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-task.rst b/Doc/library/asyncio-task.rst --- a/Doc/library/asyncio-task.rst +++ b/Doc/library/asyncio-task.rst @@ -721,4 +721,4 @@ Unlike the functions above, :func:`run_coroutine_threadsafe` requires the *loop* argument to be passed explicitely. - .. versionadded:: 3.4.4 + .. versionadded:: 3.4.4, 3.5.1 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 18 21:59:54 2015 From: python-checkins at python.org (nick.coghlan) Date: Thu, 19 Nov 2015 02:59:54 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogQ2xvc2UgIzEwMTI4?= =?utf-8?q?=3A_don=27t_rerun_=5F=5Fmain=5F=5F=2Epy_in_multiprocessing?= Message-ID: <20151119025954.63506.55113@psf.io> https://hg.python.org/cpython/rev/5d88c1d413b9 changeset: 99207:5d88c1d413b9 branch: 2.7 parent: 99196:106c49edbb12 user: Nick Coghlan date: Thu Nov 19 12:59:39 2015 +1000 summary: Close #10128: don't rerun __main__.py in multiprocessing - backports issue #10845's mitigation of incompatibilities between the multiprocessing module and directory and zipfile execution - Multiprocessing on Windows will now automatically skip rerunning top level __main__.py modules in spawned processes, rather than failing with AssertionError files: Lib/multiprocessing/forking.py | 16 +++++++++++++++- Misc/NEWS | 5 +++++ 2 files changed, 20 insertions(+), 1 deletions(-) diff --git a/Lib/multiprocessing/forking.py b/Lib/multiprocessing/forking.py --- a/Lib/multiprocessing/forking.py +++ b/Lib/multiprocessing/forking.py @@ -470,12 +470,26 @@ process.ORIGINAL_DIR = data['orig_dir'] if 'main_path' in data: + # XXX (ncoghlan): The following code makes several bogus + # assumptions regarding the relationship between __file__ + # and a module's real name. See PEP 302 and issue #10845 + # The problem is resolved properly in Python 3.4+, as + # described in issue #19946 + main_path = data['main_path'] main_name = os.path.splitext(os.path.basename(main_path))[0] if main_name == '__init__': main_name = os.path.basename(os.path.dirname(main_path)) - if main_name != 'ipython': + if main_name == '__main__': + # For directory and zipfile execution, we assume an implicit + # "if __name__ == '__main__':" around the module, and don't + # rerun the main module code in spawned processes + main_module = sys.modules['__main__'] + main_module.__file__ = main_path + elif main_name != 'ipython': + # Main modules not actually called __main__.py may + # contain additional code that should still be executed import imp if main_path is None: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -55,6 +55,11 @@ Library ------- +- Issue #10128: backport issue #10845's mitigation of incompatibilities between + the multiprocessing module and directory and zipfile execution. + Multiprocessing on Windows will now automatically skip rerunning __main__ in + spawned processes, rather than failing with AssertionError. + - Issue #25578: Fix (another) memory leak in SSLSocket.getpeercer(). - Issue #25590: In the Readline completer, only call getattr() once per -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 00:14:06 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 05:14:06 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NDcy?= =?utf-8?b?OiBJbiBCWzx0eXBlPl0sIGluc2VydCBCIGluIGZyb250IG9mIF9fYmFzZXNf?= =?utf-8?q?=5F=2C_to_make_the?= Message-ID: <20151119051405.14359.63030@psf.io> https://hg.python.org/cpython/rev/1d37f7dbbb37 changeset: 99208:1d37f7dbbb37 branch: 3.5 parent: 99205:4ae62ddf7bc7 user: Guido van Rossum date: Wed Nov 18 21:12:58 2015 -0800 summary: Issue #25472: In B[], insert B in front of __bases__, to make the __dict__ descriptor work. files: Lib/test/test_typing.py | 30 +++++++++++++++++++++++++++++ Lib/typing.py | 2 +- 2 files changed, 31 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,4 +1,5 @@ from collections import namedtuple +import pickle import re import sys from unittest import TestCase, main @@ -583,6 +584,35 @@ self.assertEqual(repr(MySimpleMapping), __name__ + '.' + 'MySimpleMapping[~XK, ~XV]') + def test_dict(self): + T = TypeVar('T') + class B(Generic[T]): + pass + b = B() + b.foo = 42 + self.assertEqual(b.__dict__, {'foo': 42}) + class C(B[int]): + pass + c = C() + c.bar = 'abc' + self.assertEqual(c.__dict__, {'bar': 'abc'}) + + def test_pickle(self): + T = TypeVar('T') + class B(Generic[T]): + pass + global C # pickle wants to reference the class by name + class C(B[int]): + pass + c = C() + c.foo = 42 + c.bar = 'abc' + z = pickle.dumps(c) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) + def test_errors(self): with self.assertRaises(TypeError): B = SimpleMapping[XK, Any] diff --git a/Lib/typing.py b/Lib/typing.py --- a/Lib/typing.py +++ b/Lib/typing.py @@ -981,7 +981,7 @@ "Cannot substitute %s for %s in %s" % (_type_repr(new), _type_repr(old), self)) - return self.__class__(self.__name__, self.__bases__, + return self.__class__(self.__name__, (self,) + self.__bases__, dict(self.__dict__), parameters=params, origin=self, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 00:14:07 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 05:14:07 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogSXNzdWUgIzI1NDcyOiBJbiBCWzx0eXBlPl0sIGluc2VydCBCIGluIGZy?= =?utf-8?q?ont_of_=5F=5Fbases=5F=5F=2C_to_make_the?= Message-ID: <20151119051406.36857.54903@psf.io> https://hg.python.org/cpython/rev/63c261185fc7 changeset: 99209:63c261185fc7 parent: 99206:284187f3a783 parent: 99208:1d37f7dbbb37 user: Guido van Rossum date: Wed Nov 18 21:13:42 2015 -0800 summary: Issue #25472: In B[], insert B in front of __bases__, to make the __dict__ descriptor work. (Merge 3.5->3.6) files: Lib/test/test_typing.py | 30 +++++++++++++++++++++++++++++ Lib/typing.py | 2 +- 2 files changed, 31 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,4 +1,5 @@ from collections import namedtuple +import pickle import re import sys from unittest import TestCase, main @@ -583,6 +584,35 @@ self.assertEqual(repr(MySimpleMapping), __name__ + '.' + 'MySimpleMapping[~XK, ~XV]') + def test_dict(self): + T = TypeVar('T') + class B(Generic[T]): + pass + b = B() + b.foo = 42 + self.assertEqual(b.__dict__, {'foo': 42}) + class C(B[int]): + pass + c = C() + c.bar = 'abc' + self.assertEqual(c.__dict__, {'bar': 'abc'}) + + def test_pickle(self): + T = TypeVar('T') + class B(Generic[T]): + pass + global C # pickle wants to reference the class by name + class C(B[int]): + pass + c = C() + c.foo = 42 + c.bar = 'abc' + z = pickle.dumps(c) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) + def test_errors(self): with self.assertRaises(TypeError): B = SimpleMapping[XK, Any] diff --git a/Lib/typing.py b/Lib/typing.py --- a/Lib/typing.py +++ b/Lib/typing.py @@ -981,7 +981,7 @@ "Cannot substitute %s for %s in %s" % (_type_repr(new), _type_repr(old), self)) - return self.__class__(self.__name__, self.__bases__, + return self.__class__(self.__name__, (self,) + self.__bases__, dict(self.__dict__), parameters=params, origin=self, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 00:20:03 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 05:20:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Remove_unused_?= =?utf-8?q?imports_from_test=5Ftyping=2Epy=2E?= Message-ID: <20151119052003.21845.82328@psf.io> https://hg.python.org/cpython/rev/2c7a58158dac changeset: 99210:2c7a58158dac branch: 3.5 parent: 99208:1d37f7dbbb37 user: Guido van Rossum date: Wed Nov 18 21:18:51 2015 -0800 summary: Remove unused imports from test_typing.py. files: Lib/test/test_typing.py | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,12 +1,7 @@ -from collections import namedtuple import pickle import re import sys from unittest import TestCase, main -try: - from unittest import mock -except ImportError: - import mock # 3rd party install, for PY3.2. from typing import Any from typing import TypeVar, AnyStr -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 00:20:03 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 05:20:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Remove_unused_imports_from_test=5Ftyping=2Epy=2E_=28Merg?= =?utf-8?b?ZSAzLjUtPjMuNik=?= Message-ID: <20151119052003.21847.14087@psf.io> https://hg.python.org/cpython/rev/312a2220100c changeset: 99211:312a2220100c parent: 99209:63c261185fc7 parent: 99210:2c7a58158dac user: Guido van Rossum date: Wed Nov 18 21:19:18 2015 -0800 summary: Remove unused imports from test_typing.py. (Merge 3.5->3.6) files: Lib/test/test_typing.py | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,12 +1,7 @@ -from collections import namedtuple import pickle import re import sys from unittest import TestCase, main -try: - from unittest import mock -except ImportError: - import mock # 3rd party install, for PY3.2. from typing import Any from typing import TypeVar, AnyStr -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Thu Nov 19 03:45:02 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 19 Nov 2015 08:45:02 +0000 Subject: [Python-checkins] Daily reference leaks (312a2220100c): sum=13 Message-ID: <20151119084459.21869.38932@psf.io> results for 312a2220100c on branch "default" -------------------------------------------- test_collections leaked [0, 6, 0] references, sum=6 test_collections leaked [0, 3, 0] memory blocks, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogWv2LKF', '--timeout', '7200'] From python-checkins at python.org Thu Nov 19 11:17:21 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 16:17:21 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325665=3A_Make_NamedTuple_picklable=2E_=28Merge_?= =?utf-8?b?My41LT4zLjYp?= Message-ID: <20151119161720.18210.2101@psf.io> https://hg.python.org/cpython/rev/8a32d44b8359 changeset: 99213:8a32d44b8359 parent: 99211:312a2220100c parent: 99212:33df0056c148 user: Guido van Rossum date: Thu Nov 19 08:16:52 2015 -0800 summary: Issue #25665: Make NamedTuple picklable. (Merge 3.5->3.6) files: Lib/test/test_typing.py | 8 ++++++++ Lib/typing.py | 5 +++++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1163,6 +1163,14 @@ assert Emp._fields == ('name', 'id') assert Emp._field_types == dict(name=str, id=int) + def test_pickle(self): + global Emp # pickle wants to reference the class by name + Emp = NamedTuple('Emp', [('name', str), ('id', int)]) + jane = Emp('jane', 37) + z = pickle.dumps(jane) + jane2 = pickle.loads(z) + assert jane == jane2 + class IOTests(TestCase): diff --git a/Lib/typing.py b/Lib/typing.py --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1479,6 +1479,11 @@ fields = [(n, t) for n, t in fields] cls = collections.namedtuple(typename, [n for n, t in fields]) cls._field_types = dict(fields) + # Set the module to the caller's module (otherwise it'd be 'typing'). + try: + cls.__module__ = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass return cls -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 11:17:25 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 16:17:25 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NjY1?= =?utf-8?q?=3A_Make_NamedTuple_picklable=2E?= Message-ID: <20151119161720.4551.13740@psf.io> https://hg.python.org/cpython/rev/33df0056c148 changeset: 99212:33df0056c148 branch: 3.5 parent: 99210:2c7a58158dac user: Guido van Rossum date: Thu Nov 19 08:16:31 2015 -0800 summary: Issue #25665: Make NamedTuple picklable. files: Lib/test/test_typing.py | 8 ++++++++ Lib/typing.py | 5 +++++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1163,6 +1163,14 @@ assert Emp._fields == ('name', 'id') assert Emp._field_types == dict(name=str, id=int) + def test_pickle(self): + global Emp # pickle wants to reference the class by name + Emp = NamedTuple('Emp', [('name', str), ('id', int)]) + jane = Emp('jane', 37) + z = pickle.dumps(jane) + jane2 = pickle.loads(z) + assert jane == jane2 + class IOTests(TestCase): diff --git a/Lib/typing.py b/Lib/typing.py --- a/Lib/typing.py +++ b/Lib/typing.py @@ -1479,6 +1479,11 @@ fields = [(n, t) for n, t in fields] cls = collections.namedtuple(typename, [n for n, t in fields]) cls._field_types = dict(fields) + # Set the module to the caller's module (otherwise it'd be 'typing'). + try: + cls.__module__ = sys._getframe(1).f_globals.get('__name__', '__main__') + except (AttributeError, ValueError): + pass return cls -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Thu Nov 19 12:12:28 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 19 Nov 2015 17:12:28 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-19 Message-ID: <42c7b66b-97f3-4a98-94a5-11b3c5a062d2@irsmsx153.ger.corp.intel.com> Results for project Python default, build date 2015-11-19 04:02:04 +0000 commit: 284187f3a7837a191d6fd5eb73914deafd72f023 revision date: 2015-11-18 17:44:59 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.40% -1.59% 10.07% 15.28% :-| pybench 0.18% 0.05% -1.58% 8.22% :-( regex_v8 2.72% -0.08% -4.16% 5.74% :-| nbody 0.13% 0.03% -0.76% 8.53% :-| json_dump_v2 0.29% -0.18% 0.71% 8.06% :-| normal_startup 0.95% 0.07% 0.73% 4.49% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Thu Nov 19 12:13:25 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 19 Nov 2015 17:13:25 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-19 Message-ID: Results for project Python 2.7, build date 2015-11-19 04:48:57 +0000 commit: 5d88c1d413b91be5016b760c18aec028558d5219 revision date: 2015-11-19 02:59:39 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.38% 0.09% 3.92% 9.97% :-) pybench 0.24% 0.11% 6.52% 7.09% :-| regex_v8 0.56% 0.20% -1.96% 8.20% :-) nbody 0.17% 0.59% 9.09% 4.93% :-) json_dump_v2 0.28% -0.15% 3.51% 12.60% :-( normal_startup 2.14% -2.11% -2.29% 3.91% :-| ssbench 0.71% -1.85% -0.86% 2.38% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Thu Nov 19 16:34:45 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 21:34:45 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325593=3A_Change_semantics_of_EventLoop=2Estop=28=29?= =?utf-8?b?LiAoTWVyZ2UgMy40LT4zLjUp?= Message-ID: <20151119213444.4665.39137@psf.io> https://hg.python.org/cpython/rev/158cc5701488 changeset: 99215:158cc5701488 branch: 3.5 parent: 99212:33df0056c148 parent: 99214:9b3144716d17 user: Guido van Rossum date: Thu Nov 19 13:33:34 2015 -0800 summary: Issue #25593: Change semantics of EventLoop.stop(). (Merge 3.4->3.5) files: Doc/library/asyncio-eventloop.rst | 22 +++- Doc/library/asyncio-protocol.rst | 2 +- Lib/asyncio/base_events.py | 25 +--- Lib/asyncio/test_utils.py | 11 +- Lib/test/test_asyncio/test_base_events.py | 53 +++++++++++ Misc/NEWS | 2 + 6 files changed, 87 insertions(+), 28 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -29,7 +29,16 @@ .. method:: BaseEventLoop.run_forever() - Run until :meth:`stop` is called. + Run until :meth:`stop` is called. If :meth:`stop` is called before + :meth:`run_forever()` is called, this polls the I/O selector once + with a timeout of zero, runs all callbacks scheduled in response to + I/O events (and those that were already scheduled), and then exits. + If :meth:`stop` is called while :meth:`run_forever` is running, + this will run the current batch of callbacks and then exit. Note + that callbacks scheduled by callbacks will not run in that case; + they will run the next time :meth:`run_forever` is called. + + .. versionchanged:: 3.5.1 .. method:: BaseEventLoop.run_until_complete(future) @@ -48,10 +57,10 @@ Stop running the event loop. - Every callback scheduled before :meth:`stop` is called will run. - Callbacks scheduled after :meth:`stop` is called will not run. - However, those callbacks will run if :meth:`run_forever` is called - again later. + This causes :meth:`run_forever` to exit at the next suitable + opportunity (see there for more details). + + .. versionchanged:: 3.5.1 .. method:: BaseEventLoop.is_closed() @@ -61,7 +70,8 @@ .. method:: BaseEventLoop.close() - Close the event loop. The loop must not be running. + Close the event loop. The loop must not be running. Pending + callbacks will be lost. This clears the queues and shuts down the executor, but does not wait for the executor to finish. diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -494,7 +494,7 @@ def connection_lost(self, exc): print('The server closed the connection') - print('Stop the event lop') + print('Stop the event loop') self.loop.stop() loop = asyncio.get_event_loop() diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -70,10 +70,6 @@ return repr(fd) -class _StopError(BaseException): - """Raised to stop the event loop.""" - - def _check_resolved_address(sock, address): # Ensure that the address is already resolved to avoid the trap of hanging # the entire event loop when the address requires doing a DNS lookup. @@ -118,9 +114,6 @@ "got host %r: %s" % (host, err)) -def _raise_stop_error(*args): - raise _StopError - def _run_until_complete_cb(fut): exc = fut._exception @@ -129,7 +122,7 @@ # Issue #22429: run_forever() already finished, no need to # stop it. return - _raise_stop_error() + fut._loop.stop() class Server(events.AbstractServer): @@ -184,6 +177,7 @@ def __init__(self): self._timer_cancelled_count = 0 self._closed = False + self._stopping = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None @@ -298,11 +292,11 @@ self._thread_id = threading.get_ident() try: while True: - try: - self._run_once() - except _StopError: + self._run_once() + if self._stopping: break finally: + self._stopping = False self._thread_id = None self._set_coroutine_wrapper(False) @@ -345,11 +339,10 @@ def stop(self): """Stop running the event loop. - Every callback scheduled before stop() is called will run. Callbacks - scheduled after stop() is called will not run. However, those callbacks - will run if run_forever is called again later. + Every callback already scheduled will still run. This simply informs + run_forever to stop looping after a complete iteration. """ - self.call_soon(_raise_stop_error) + self._stopping = True def close(self): """Close the event loop. @@ -1194,7 +1187,7 @@ handle._scheduled = False timeout = None - if self._ready: + if self._ready or self._stopping: timeout = 0 elif self._scheduled: # Compute the desired timeout. diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -71,12 +71,13 @@ def run_once(loop): - """loop.stop() schedules _raise_stop_error() - and run_forever() runs until _raise_stop_error() callback. - this wont work if test waits for some IO events, because - _raise_stop_error() runs before any of io events callbacks. + """Legacy API to run once through the event loop. + + This is the recommended pattern for test code. It will poll the + selector once and run all callbacks scheduled in response to I/O + events. """ - loop.stop() + loop.call_soon(loop.stop) loop.run_forever() diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -757,6 +757,59 @@ pass self.assertTrue(func.called) + def test_single_selecter_event_callback_after_stopping(self): + # Python issue #25593: A stopped event loop may cause event callbacks + # to run more than once. + event_sentinel = object() + callcount = 0 + doer = None + + def proc_events(event_list): + nonlocal doer + if event_sentinel in event_list: + doer = self.loop.call_soon(do_event) + + def do_event(): + nonlocal callcount + callcount += 1 + self.loop.call_soon(clear_selector) + + def clear_selector(): + doer.cancel() + self.loop._selector.select.return_value = () + + self.loop._process_events = proc_events + self.loop._selector.select.return_value = (event_sentinel,) + + for i in range(1, 3): + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) + + def test_run_once(self): + # Simple test for test_utils.run_once(). It may seem strange + # to have a test for this (the function isn't even used!) but + # it's a de-factor standard API for library tests. This tests + # the idiom: loop.call_soon(loop.stop); loop.run_forever(). + count = 0 + + def callback(): + nonlocal count + count += 1 + + self.loop._process_events = mock.Mock() + self.loop.call_soon(callback) + test_utils.run_once(self.loop) + self.assertEqual(count, 1) + + def test_run_forever_pre_stopped(self): + # Test that the old idiom for pre-stopping the loop works. + self.loop._process_events = mock.Mock() + self.loop.stop() + self.loop.run_forever() + self.loop._selector.select.assert_called_once_with(0) + class MyProto(asyncio.Protocol): done = None diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -77,6 +77,8 @@ Library ------- +- Issue #25593: Change semantics of EventLoop.stop() in asyncio. + - Issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 16:34:47 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 21:34:47 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTkz?= =?utf-8?q?=3A_Change_semantics_of_EventLoop=2Estop=28=29=2E?= Message-ID: <20151119213444.63490.24673@psf.io> https://hg.python.org/cpython/rev/9b3144716d17 changeset: 99214:9b3144716d17 branch: 3.4 parent: 99204:b34c42e46e7b user: Guido van Rossum date: Thu Nov 19 13:28:47 2015 -0800 summary: Issue #25593: Change semantics of EventLoop.stop(). files: Doc/library/asyncio-eventloop.rst | 22 +++- Doc/library/asyncio-protocol.rst | 2 +- Lib/asyncio/base_events.py | 25 +--- Lib/asyncio/test_utils.py | 11 +- Lib/test/test_asyncio/test_base_events.py | 53 +++++++++++ Misc/NEWS | 2 + 6 files changed, 87 insertions(+), 28 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -29,7 +29,16 @@ .. method:: BaseEventLoop.run_forever() - Run until :meth:`stop` is called. + Run until :meth:`stop` is called. If :meth:`stop` is called before + :meth:`run_forever()` is called, this polls the I/O selector once + with a timeout of zero, runs all callbacks scheduled in response to + I/O events (and those that were already scheduled), and then exits. + If :meth:`stop` is called while :meth:`run_forever` is running, + this will run the current batch of callbacks and then exit. Note + that callbacks scheduled by callbacks will not run in that case; + they will run the next time :meth:`run_forever` is called. + + .. versionchanged:: 3.4.4 .. method:: BaseEventLoop.run_until_complete(future) @@ -48,10 +57,10 @@ Stop running the event loop. - Every callback scheduled before :meth:`stop` is called will run. - Callbacks scheduled after :meth:`stop` is called will not run. - However, those callbacks will run if :meth:`run_forever` is called - again later. + This causes :meth:`run_forever` to exit at the next suitable + opportunity (see there for more details). + + .. versionchanged:: 3.4.4 .. method:: BaseEventLoop.is_closed() @@ -61,7 +70,8 @@ .. method:: BaseEventLoop.close() - Close the event loop. The loop must not be running. + Close the event loop. The loop must not be running. Pending + callbacks will be lost. This clears the queues and shuts down the executor, but does not wait for the executor to finish. diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -494,7 +494,7 @@ def connection_lost(self, exc): print('The server closed the connection') - print('Stop the event lop') + print('Stop the event loop') self.loop.stop() loop = asyncio.get_event_loop() diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -70,10 +70,6 @@ return repr(fd) -class _StopError(BaseException): - """Raised to stop the event loop.""" - - def _check_resolved_address(sock, address): # Ensure that the address is already resolved to avoid the trap of hanging # the entire event loop when the address requires doing a DNS lookup. @@ -118,9 +114,6 @@ "got host %r: %s" % (host, err)) -def _raise_stop_error(*args): - raise _StopError - def _run_until_complete_cb(fut): exc = fut._exception @@ -129,7 +122,7 @@ # Issue #22429: run_forever() already finished, no need to # stop it. return - _raise_stop_error() + fut._loop.stop() class Server(events.AbstractServer): @@ -184,6 +177,7 @@ def __init__(self): self._timer_cancelled_count = 0 self._closed = False + self._stopping = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None @@ -298,11 +292,11 @@ self._thread_id = threading.get_ident() try: while True: - try: - self._run_once() - except _StopError: + self._run_once() + if self._stopping: break finally: + self._stopping = False self._thread_id = None self._set_coroutine_wrapper(False) @@ -345,11 +339,10 @@ def stop(self): """Stop running the event loop. - Every callback scheduled before stop() is called will run. Callbacks - scheduled after stop() is called will not run. However, those callbacks - will run if run_forever is called again later. + Every callback already scheduled will still run. This simply informs + run_forever to stop looping after a complete iteration. """ - self.call_soon(_raise_stop_error) + self._stopping = True def close(self): """Close the event loop. @@ -1194,7 +1187,7 @@ handle._scheduled = False timeout = None - if self._ready: + if self._ready or self._stopping: timeout = 0 elif self._scheduled: # Compute the desired timeout. diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -71,12 +71,13 @@ def run_once(loop): - """loop.stop() schedules _raise_stop_error() - and run_forever() runs until _raise_stop_error() callback. - this wont work if test waits for some IO events, because - _raise_stop_error() runs before any of io events callbacks. + """Legacy API to run once through the event loop. + + This is the recommended pattern for test code. It will poll the + selector once and run all callbacks scheduled in response to I/O + events. """ - loop.stop() + loop.call_soon(loop.stop) loop.run_forever() diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -757,6 +757,59 @@ pass self.assertTrue(func.called) + def test_single_selecter_event_callback_after_stopping(self): + # Python issue #25593: A stopped event loop may cause event callbacks + # to run more than once. + event_sentinel = object() + callcount = 0 + doer = None + + def proc_events(event_list): + nonlocal doer + if event_sentinel in event_list: + doer = self.loop.call_soon(do_event) + + def do_event(): + nonlocal callcount + callcount += 1 + self.loop.call_soon(clear_selector) + + def clear_selector(): + doer.cancel() + self.loop._selector.select.return_value = () + + self.loop._process_events = proc_events + self.loop._selector.select.return_value = (event_sentinel,) + + for i in range(1, 3): + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) + + def test_run_once(self): + # Simple test for test_utils.run_once(). It may seem strange + # to have a test for this (the function isn't even used!) but + # it's a de-factor standard API for library tests. This tests + # the idiom: loop.call_soon(loop.stop); loop.run_forever(). + count = 0 + + def callback(): + nonlocal count + count += 1 + + self.loop._process_events = mock.Mock() + self.loop.call_soon(callback) + test_utils.run_once(self.loop) + self.assertEqual(count, 1) + + def test_run_forever_pre_stopped(self): + # Test that the old idiom for pre-stopping the loop works. + self.loop._process_events = mock.Mock() + self.loop.stop() + self.loop.run_forever() + self.loop._selector.select.assert_called_once_with(0) + class MyProto(asyncio.Protocol): done = None diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,8 @@ Library ------- +- Issue #25593: Change semantics of EventLoop.stop() in asyncio. + - Issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 16:34:47 2015 From: python-checkins at python.org (guido.van.rossum) Date: Thu, 19 Nov 2015 21:34:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325593=3A_Change_semantics_of_EventLoop=2Estop?= =?utf-8?b?KCkuIChNZXJnZSAzLjUtPjMuNik=?= Message-ID: <20151119213445.63486.55488@psf.io> https://hg.python.org/cpython/rev/2ebe03a94f8f changeset: 99216:2ebe03a94f8f parent: 99213:8a32d44b8359 parent: 99215:158cc5701488 user: Guido van Rossum date: Thu Nov 19 13:34:24 2015 -0800 summary: Issue #25593: Change semantics of EventLoop.stop(). (Merge 3.5->3.6) files: Doc/library/asyncio-eventloop.rst | 22 +++- Doc/library/asyncio-protocol.rst | 2 +- Lib/asyncio/base_events.py | 25 +--- Lib/asyncio/test_utils.py | 11 +- Lib/test/test_asyncio/test_base_events.py | 53 +++++++++++ Misc/NEWS | 2 + 6 files changed, 87 insertions(+), 28 deletions(-) diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst --- a/Doc/library/asyncio-eventloop.rst +++ b/Doc/library/asyncio-eventloop.rst @@ -29,7 +29,16 @@ .. method:: BaseEventLoop.run_forever() - Run until :meth:`stop` is called. + Run until :meth:`stop` is called. If :meth:`stop` is called before + :meth:`run_forever()` is called, this polls the I/O selector once + with a timeout of zero, runs all callbacks scheduled in response to + I/O events (and those that were already scheduled), and then exits. + If :meth:`stop` is called while :meth:`run_forever` is running, + this will run the current batch of callbacks and then exit. Note + that callbacks scheduled by callbacks will not run in that case; + they will run the next time :meth:`run_forever` is called. + + .. versionchanged:: 3.5.1 .. method:: BaseEventLoop.run_until_complete(future) @@ -48,10 +57,10 @@ Stop running the event loop. - Every callback scheduled before :meth:`stop` is called will run. - Callbacks scheduled after :meth:`stop` is called will not run. - However, those callbacks will run if :meth:`run_forever` is called - again later. + This causes :meth:`run_forever` to exit at the next suitable + opportunity (see there for more details). + + .. versionchanged:: 3.5.1 .. method:: BaseEventLoop.is_closed() @@ -61,7 +70,8 @@ .. method:: BaseEventLoop.close() - Close the event loop. The loop must not be running. + Close the event loop. The loop must not be running. Pending + callbacks will be lost. This clears the queues and shuts down the executor, but does not wait for the executor to finish. diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst --- a/Doc/library/asyncio-protocol.rst +++ b/Doc/library/asyncio-protocol.rst @@ -494,7 +494,7 @@ def connection_lost(self, exc): print('The server closed the connection') - print('Stop the event lop') + print('Stop the event loop') self.loop.stop() loop = asyncio.get_event_loop() diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -70,10 +70,6 @@ return repr(fd) -class _StopError(BaseException): - """Raised to stop the event loop.""" - - def _check_resolved_address(sock, address): # Ensure that the address is already resolved to avoid the trap of hanging # the entire event loop when the address requires doing a DNS lookup. @@ -118,9 +114,6 @@ "got host %r: %s" % (host, err)) -def _raise_stop_error(*args): - raise _StopError - def _run_until_complete_cb(fut): exc = fut._exception @@ -129,7 +122,7 @@ # Issue #22429: run_forever() already finished, no need to # stop it. return - _raise_stop_error() + fut._loop.stop() class Server(events.AbstractServer): @@ -184,6 +177,7 @@ def __init__(self): self._timer_cancelled_count = 0 self._closed = False + self._stopping = False self._ready = collections.deque() self._scheduled = [] self._default_executor = None @@ -298,11 +292,11 @@ self._thread_id = threading.get_ident() try: while True: - try: - self._run_once() - except _StopError: + self._run_once() + if self._stopping: break finally: + self._stopping = False self._thread_id = None self._set_coroutine_wrapper(False) @@ -345,11 +339,10 @@ def stop(self): """Stop running the event loop. - Every callback scheduled before stop() is called will run. Callbacks - scheduled after stop() is called will not run. However, those callbacks - will run if run_forever is called again later. + Every callback already scheduled will still run. This simply informs + run_forever to stop looping after a complete iteration. """ - self.call_soon(_raise_stop_error) + self._stopping = True def close(self): """Close the event loop. @@ -1194,7 +1187,7 @@ handle._scheduled = False timeout = None - if self._ready: + if self._ready or self._stopping: timeout = 0 elif self._scheduled: # Compute the desired timeout. diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -71,12 +71,13 @@ def run_once(loop): - """loop.stop() schedules _raise_stop_error() - and run_forever() runs until _raise_stop_error() callback. - this wont work if test waits for some IO events, because - _raise_stop_error() runs before any of io events callbacks. + """Legacy API to run once through the event loop. + + This is the recommended pattern for test code. It will poll the + selector once and run all callbacks scheduled in response to I/O + events. """ - loop.stop() + loop.call_soon(loop.stop) loop.run_forever() diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -757,6 +757,59 @@ pass self.assertTrue(func.called) + def test_single_selecter_event_callback_after_stopping(self): + # Python issue #25593: A stopped event loop may cause event callbacks + # to run more than once. + event_sentinel = object() + callcount = 0 + doer = None + + def proc_events(event_list): + nonlocal doer + if event_sentinel in event_list: + doer = self.loop.call_soon(do_event) + + def do_event(): + nonlocal callcount + callcount += 1 + self.loop.call_soon(clear_selector) + + def clear_selector(): + doer.cancel() + self.loop._selector.select.return_value = () + + self.loop._process_events = proc_events + self.loop._selector.select.return_value = (event_sentinel,) + + for i in range(1, 3): + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) + + def test_run_once(self): + # Simple test for test_utils.run_once(). It may seem strange + # to have a test for this (the function isn't even used!) but + # it's a de-factor standard API for library tests. This tests + # the idiom: loop.call_soon(loop.stop); loop.run_forever(). + count = 0 + + def callback(): + nonlocal count + count += 1 + + self.loop._process_events = mock.Mock() + self.loop.call_soon(callback) + test_utils.run_once(self.loop) + self.assertEqual(count, 1) + + def test_run_forever_pre_stopped(self): + # Test that the old idiom for pre-stopping the loop works. + self.loop._process_events = mock.Mock() + self.loop.stop() + self.loop.run_forever() + self.loop._selector.select.assert_called_once_with(0) + class MyProto(asyncio.Protocol): done = None diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,8 @@ Library ------- +- Issue #25593: Change semantics of EventLoop.stop() in asyncio. + - Issue #6973: When we know a subprocess.Popen process has died, do not allow the send_signal(), terminate(), or kill() methods to do anything as they could potentially signal a different process. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 21:39:33 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 20 Nov 2015 02:39:33 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTgz?= =?utf-8?q?=3A_Avoid_incorrect_errors_raised_by_os=2Emakedirs=28exist=5Fok?= =?utf-8?b?PVRydWUp?= Message-ID: <20151120023933.4544.79738@psf.io> https://hg.python.org/cpython/rev/05d6ddf2b7c2 changeset: 99217:05d6ddf2b7c2 branch: 3.4 parent: 99214:9b3144716d17 user: Martin Panter date: Thu Nov 19 04:48:44 2015 +0000 summary: Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) files: Lib/os.py | 8 +++++--- Lib/test/test_os.py | 3 +++ Misc/NEWS | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/os.py b/Lib/os.py --- a/Lib/os.py +++ b/Lib/os.py @@ -226,7 +226,7 @@ try: makedirs(head, mode, exist_ok) except FileExistsError: - # be happy if someone already created the path + # Defeats race condition when another thread created the path pass cdir = curdir if isinstance(tail, bytes): @@ -235,8 +235,10 @@ return try: mkdir(name, mode) - except OSError as e: - if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not path.isdir(name): raise def removedirs(name): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -971,6 +971,9 @@ os.makedirs(path, mode=mode, exist_ok=True) os.umask(old_mask) + # Issue #25583: A drive root could raise PermissionError on Windows + os.makedirs(os.path.abspath('/'), exist_ok=True) + @unittest.skipUnless(hasattr(os, 'chown'), 'test needs os.chown') def test_chown_uid_gid_arguments_must_be_index(self): stat = os.stat(support.TESTFN) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,9 @@ Library ------- +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + - Issue #25593: Change semantics of EventLoop.stop() in asyncio. - Issue #6973: When we know a subprocess.Popen process has died, do -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 21:39:33 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 20 Nov 2015 02:39:33 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325583=3A_Merge_makedirs_fix_from_3=2E5?= Message-ID: <20151120023933.31765.46845@psf.io> https://hg.python.org/cpython/rev/f0ad5067879b changeset: 99219:f0ad5067879b parent: 99216:2ebe03a94f8f parent: 99218:515f76bf1254 user: Martin Panter date: Fri Nov 20 02:37:29 2015 +0000 summary: Issue #25583: Merge makedirs fix from 3.5 files: Lib/os.py | 8 +++++--- Lib/test/test_os.py | 3 +++ Misc/NEWS | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/os.py b/Lib/os.py --- a/Lib/os.py +++ b/Lib/os.py @@ -230,7 +230,7 @@ try: makedirs(head, mode, exist_ok) except FileExistsError: - # be happy if someone already created the path + # Defeats race condition when another thread created the path pass cdir = curdir if isinstance(tail, bytes): @@ -239,8 +239,10 @@ return try: mkdir(name, mode) - except OSError as e: - if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not path.isdir(name): raise def removedirs(name): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1039,6 +1039,9 @@ os.makedirs(path, mode=mode, exist_ok=True) os.umask(old_mask) + # Issue #25583: A drive root could raise PermissionError on Windows + os.makedirs(os.path.abspath('/'), exist_ok=True) + def test_exist_ok_s_isgid_directory(self): path = os.path.join(support.TESTFN, 'dir1') S_ISGID = stat.S_ISGID diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -429,6 +429,9 @@ Library ------- +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + - Issue #25590: In the Readline completer, only call getattr() once per attribute. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 21:39:33 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 20 Nov 2015 02:39:33 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325583=3A_Merge_makedirs_fix_from_3=2E4_into_3=2E5?= Message-ID: <20151120023933.4539.63527@psf.io> https://hg.python.org/cpython/rev/515f76bf1254 changeset: 99218:515f76bf1254 branch: 3.5 parent: 99215:158cc5701488 parent: 99217:05d6ddf2b7c2 user: Martin Panter date: Fri Nov 20 02:35:46 2015 +0000 summary: Issue #25583: Merge makedirs fix from 3.4 into 3.5 files: Lib/os.py | 8 +++++--- Lib/test/test_os.py | 3 +++ Misc/NEWS | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Lib/os.py b/Lib/os.py --- a/Lib/os.py +++ b/Lib/os.py @@ -230,7 +230,7 @@ try: makedirs(head, mode, exist_ok) except FileExistsError: - # be happy if someone already created the path + # Defeats race condition when another thread created the path pass cdir = curdir if isinstance(tail, bytes): @@ -239,8 +239,10 @@ return try: mkdir(name, mode) - except OSError as e: - if not exist_ok or e.errno != errno.EEXIST or not path.isdir(name): + except OSError: + # Cannot rely on checking for EEXIST, since the operating system + # could give priority to other errors like EACCES or EROFS + if not exist_ok or not path.isdir(name): raise def removedirs(name): diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -1040,6 +1040,9 @@ os.makedirs(path, mode=mode, exist_ok=True) os.umask(old_mask) + # Issue #25583: A drive root could raise PermissionError on Windows + os.makedirs(os.path.abspath('/'), exist_ok=True) + def test_exist_ok_s_isgid_directory(self): path = os.path.join(support.TESTFN, 'dir1') S_ISGID = stat.S_ISGID diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -77,6 +77,9 @@ Library ------- +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + - Issue #25593: Change semantics of EventLoop.stop() in asyncio. - Issue #6973: When we know a subprocess.Popen process has died, do -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 19 21:39:34 2015 From: python-checkins at python.org (martin.panter) Date: Fri, 20 Nov 2015 02:39:34 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325583=3A_Add_news?= =?utf-8?q?_to_3=2E6_section?= Message-ID: <20151120023933.105923.40794@psf.io> https://hg.python.org/cpython/rev/6ec093f78266 changeset: 99220:6ec093f78266 user: Martin Panter date: Fri Nov 20 02:37:57 2015 +0000 summary: Issue #25583: Add news to 3.6 section files: Misc/NEWS | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,9 @@ Library ------- +- Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) + when the OS gives priority to errors such as EACCES over EEXIST. + - Issue #25593: Change semantics of EventLoop.stop() in asyncio. - Issue #6973: When we know a subprocess.Popen process has died, do -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 02:51:14 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 20 Nov 2015 07:51:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1Njcw?= =?utf-8?q?=3A_Remove_duplicate_getattr=28=29_from_ast=2ENodeTransformer?= Message-ID: <20151120075114.79059.86350@psf.io> https://hg.python.org/cpython/rev/7789f338447f changeset: 99221:7789f338447f branch: 3.5 parent: 99218:515f76bf1254 user: Victor Stinner date: Fri Nov 20 08:49:58 2015 +0100 summary: Issue #25670: Remove duplicate getattr() from ast.NodeTransformer files: Lib/ast.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py --- a/Lib/ast.py +++ b/Lib/ast.py @@ -293,7 +293,6 @@ def generic_visit(self, node): for field, old_value in iter_fields(node): - old_value = getattr(node, field, None) if isinstance(old_value, list): new_values = [] for value in old_value: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 02:51:14 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 20 Nov 2015 07:51:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41IChpc3N1ZSAjMjU2NzAp?= Message-ID: <20151120075114.21849.7061@psf.io> https://hg.python.org/cpython/rev/2d90f4b27743 changeset: 99222:2d90f4b27743 parent: 99220:6ec093f78266 parent: 99221:7789f338447f user: Victor Stinner date: Fri Nov 20 08:50:17 2015 +0100 summary: Merge 3.5 (issue #25670) files: Lib/ast.py | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py --- a/Lib/ast.py +++ b/Lib/ast.py @@ -293,7 +293,6 @@ def generic_visit(self, node): for field, old_value in iter_fields(node): - old_value = getattr(node, field, None) if isinstance(old_value, list): new_values = [] for value in old_value: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 03:27:54 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 20 Nov 2015 08:27:54 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325557=3A_Refactor?= =?utf-8?b?IF9QeURpY3RfTG9hZEdsb2JhbCgp?= Message-ID: <20151120082754.14369.43480@psf.io> https://hg.python.org/cpython/rev/c35d65c9ded3 changeset: 99223:c35d65c9ded3 user: Victor Stinner date: Fri Nov 20 09:24:02 2015 +0100 summary: Issue #25557: Refactor _PyDict_LoadGlobal() Don't fallback to PyDict_GetItemWithError() if the hash is unknown: compute the hash instead. Add also comments to explain the optimization a little bit. files: Objects/dictobject.c | 55 ++++++++++++++++--------------- Python/ceval.c | 11 +++++- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/Objects/dictobject.c b/Objects/dictobject.c --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -1165,39 +1165,42 @@ return PyDict_GetItemWithError(dp, kv); } -/* Fast version of global value lookup. +/* Fast version of global value lookup (LOAD_GLOBAL). * Lookup in globals, then builtins. + * + * Raise an exception and return NULL if an error occurred (ex: computing the + * key hash failed, key comparison failed, ...). Return NULL if the key doesn't + * exist. Return the value if the key exists. */ PyObject * _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) { - PyObject *x; - if (PyUnicode_CheckExact(key)) { - PyObject **value_addr; - Py_hash_t hash = ((PyASCIIObject *)key)->hash; - if (hash != -1) { - PyDictKeyEntry *e; - e = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr); - if (e == NULL) { - return NULL; - } - x = *value_addr; - if (x != NULL) - return x; - e = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr); - if (e == NULL) { - return NULL; - } - x = *value_addr; - return x; - } + Py_hash_t hash; + PyDictKeyEntry *entry; + PyObject **value_addr; + PyObject *value; + + if (!PyUnicode_CheckExact(key) || + (hash = ((PyASCIIObject *) key)->hash) == -1) + { + hash = PyObject_Hash(key); + if (hash == -1) + return NULL; } - x = PyDict_GetItemWithError((PyObject *)globals, key); - if (x != NULL) - return x; - if (PyErr_Occurred()) + + /* namespace 1: globals */ + entry = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr); + if (entry == NULL) return NULL; - return PyDict_GetItemWithError((PyObject *)builtins, key); + value = *value_addr; + if (value != NULL) + return value; + + /* namespace 2: builtins */ + entry = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr); + if (entry == NULL) + return NULL; + return *value_addr; } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2347,26 +2347,33 @@ PyObject *name = GETITEM(names, oparg); PyObject *v; if (PyDict_CheckExact(f->f_globals) - && PyDict_CheckExact(f->f_builtins)) { + && PyDict_CheckExact(f->f_builtins)) + { v = _PyDict_LoadGlobal((PyDictObject *)f->f_globals, (PyDictObject *)f->f_builtins, name); if (v == NULL) { - if (!_PyErr_OCCURRED()) + if (!_PyErr_OCCURRED()) { + /* _PyDict_LoadGlobal() returns NULL without raising + * an exception if the key doesn't exist */ format_exc_check_arg(PyExc_NameError, NAME_ERROR_MSG, name); + } goto error; } Py_INCREF(v); } else { /* Slow-path if globals or builtins is not a dict */ + + /* namespace 1: globals */ v = PyObject_GetItem(f->f_globals, name); if (v == NULL) { if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error; PyErr_Clear(); + /* namespace 2: builtins */ v = PyObject_GetItem(f->f_builtins, name); if (v == NULL) { if (PyErr_ExceptionMatches(PyExc_KeyError)) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Fri Nov 20 03:44:31 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 20 Nov 2015 08:44:31 +0000 Subject: [Python-checkins] Daily reference leaks (6ec093f78266): sum=4 Message-ID: <20151120084431.36859.33405@psf.io> results for 6ec093f78266 on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogVqr2Cf', '--timeout', '7200'] From lp_benchmark_robot at intel.com Fri Nov 20 09:08:45 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 20 Nov 2015 14:08:45 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-20 Message-ID: Results for project Python default, build date 2015-11-20 04:02:06 +0000 commit: 6ec093f78266838be113d267a8e002d16f5a58c1 revision date: 2015-11-20 02:37:57 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.45% -0.59% 9.54% 13.33% :-| pybench 0.07% -0.36% -1.95% 8.59% :-( regex_v8 2.68% -0.60% -4.79% 6.46% :-| nbody 0.10% -0.89% -1.66% 10.44% :-| json_dump_v2 0.22% -0.60% 0.12% 7.84% :-| normal_startup 0.84% -0.23% 0.51% 4.59% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Fri Nov 20 09:09:18 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 20 Nov 2015 14:09:18 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-20 Message-ID: <856d927a-e6ac-47e0-aa85-a7cca46df758@irsmsx153.ger.corp.intel.com> No new revisions. Here are the previous results: Results for project Python 2.7, build date 2015-11-20 04:51:40 +0000 commit: 5d88c1d413b91be5016b760c18aec028558d5219 revision date: 2015-11-19 02:59:39 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.38% 0.09% 3.92% 9.97% :-) pybench 0.24% 0.11% 6.52% 7.09% :-| regex_v8 0.56% 0.20% -1.96% 8.20% :-) nbody 0.17% 0.59% 9.09% 4.93% :-) json_dump_v2 0.28% -0.15% 3.51% 12.60% :-( normal_startup 2.14% -2.11% -2.29% 3.91% :-| ssbench 0.71% -1.85% -0.86% 2.38% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Fri Nov 20 10:16:38 2015 From: python-checkins at python.org (r.david.murray) Date: Fri, 20 Nov 2015 15:16:38 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge=3A_=2325679=3A_spelling_fix?= Message-ID: <20151120150029.105907.38173@psf.io> https://hg.python.org/cpython/rev/44ca5e073feb changeset: 99225:44ca5e073feb branch: 3.5 parent: 99221:7789f338447f parent: 99224:3e723559d9f1 user: R David Murray date: Fri Nov 20 09:58:51 2015 -0500 summary: Merge: #25679: spelling fix files: Doc/reference/executionmodel.rst | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -11,8 +11,8 @@ .. _prog_structure: -Structure of a programm -======================= +Structure of a program +====================== .. index:: block @@ -270,4 +270,3 @@ .. [#] This limitation occurs because the code that is executed by these operations is not available at the time the module is compiled. - -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 10:16:37 2015 From: python-checkins at python.org (r.david.murray) Date: Fri, 20 Nov 2015 15:16:37 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogIzI1Njc5OiBzcGVs?= =?utf-8?q?ling_fix?= Message-ID: <20151120150029.36859.26383@psf.io> https://hg.python.org/cpython/rev/3e723559d9f1 changeset: 99224:3e723559d9f1 branch: 3.4 parent: 99217:05d6ddf2b7c2 user: R David Murray date: Fri Nov 20 09:57:20 2015 -0500 summary: #25679: spelling fix files: Doc/reference/executionmodel.rst | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -11,8 +11,8 @@ .. _prog_structure: -Structure of a programm -======================= +Structure of a program +====================== .. index:: block @@ -270,4 +270,3 @@ .. [#] This limitation occurs because the code that is executed by these operations is not available at the time the module is compiled. - -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 10:16:37 2015 From: python-checkins at python.org (r.david.murray) Date: Fri, 20 Nov 2015 15:16:37 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge=3A_=2325679=3A_spelling_fix?= Message-ID: <20151120150029.105919.29280@psf.io> https://hg.python.org/cpython/rev/14a3cfc477c6 changeset: 99226:14a3cfc477c6 parent: 99223:c35d65c9ded3 parent: 99225:44ca5e073feb user: R David Murray date: Fri Nov 20 09:59:19 2015 -0500 summary: Merge: #25679: spelling fix files: Doc/reference/executionmodel.rst | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/reference/executionmodel.rst b/Doc/reference/executionmodel.rst --- a/Doc/reference/executionmodel.rst +++ b/Doc/reference/executionmodel.rst @@ -11,8 +11,8 @@ .. _prog_structure: -Structure of a programm -======================= +Structure of a program +====================== .. index:: block @@ -270,4 +270,3 @@ .. [#] This limitation occurs because the code that is executed by these operations is not available at the time the module is compiled. - -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 11:49:38 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 20 Nov 2015 16:49:38 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NjY1?= =?utf-8?q?=3A_Test_pickling_with_all_protocols_in_test=5Ftyping=2E?= Message-ID: <20151120163355.36871.7831@psf.io> https://hg.python.org/cpython/rev/4f30b0d47c24 changeset: 99227:4f30b0d47c24 branch: 3.5 parent: 99225:44ca5e073feb user: Serhiy Storchaka date: Fri Nov 20 18:33:02 2015 +0200 summary: Issue #25665: Test pickling with all protocols in test_typing. files: Lib/test/test_typing.py | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -602,11 +602,12 @@ c = C() c.foo = 42 c.bar = 'abc' - z = pickle.dumps(c) - x = pickle.loads(z) - self.assertEqual(x.foo, 42) - self.assertEqual(x.bar, 'abc') - self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(c, proto) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) def test_errors(self): with self.assertRaises(TypeError): @@ -1167,9 +1168,10 @@ global Emp # pickle wants to reference the class by name Emp = NamedTuple('Emp', [('name', str), ('id', int)]) jane = Emp('jane', 37) - z = pickle.dumps(jane) - jane2 = pickle.loads(z) - assert jane == jane2 + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) class IOTests(TestCase): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 11:49:38 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 20 Nov 2015 16:49:38 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325665=3A_Test_pickling_with_all_protocols_in_te?= =?utf-8?q?st=5Ftyping=2E?= Message-ID: <20151120163355.79037.64486@psf.io> https://hg.python.org/cpython/rev/9e65015582a5 changeset: 99228:9e65015582a5 parent: 99226:14a3cfc477c6 parent: 99227:4f30b0d47c24 user: Serhiy Storchaka date: Fri Nov 20 18:33:33 2015 +0200 summary: Issue #25665: Test pickling with all protocols in test_typing. files: Lib/test/test_typing.py | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -602,11 +602,12 @@ c = C() c.foo = 42 c.bar = 'abc' - z = pickle.dumps(c) - x = pickle.loads(z) - self.assertEqual(x.foo, 42) - self.assertEqual(x.bar, 'abc') - self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(c, proto) + x = pickle.loads(z) + self.assertEqual(x.foo, 42) + self.assertEqual(x.bar, 'abc') + self.assertEqual(x.__dict__, {'foo': 42, 'bar': 'abc'}) def test_errors(self): with self.assertRaises(TypeError): @@ -1167,9 +1168,10 @@ global Emp # pickle wants to reference the class by name Emp = NamedTuple('Emp', [('name', str), ('id', int)]) jane = Emp('jane', 37) - z = pickle.dumps(jane) - jane2 = pickle.loads(z) - assert jane == jane2 + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + z = pickle.dumps(jane, proto) + jane2 = pickle.loads(z) + self.assertEqual(jane2, jane) class IOTests(TestCase): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:22:40 2015 From: python-checkins at python.org (terry.reedy) Date: Fri, 20 Nov 2015 17:22:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151120172240.4685.24033@psf.io> https://hg.python.org/cpython/rev/96d1cb825c85 changeset: 99232:96d1cb825c85 parent: 99228:9e65015582a5 parent: 99231:64e1a6c99037 user: Terry Jan Reedy date: Fri Nov 20 12:22:18 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/PyShell.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -989,7 +989,7 @@ if self.executing: response = tkMessageBox.askokcancel( "Kill?", - "The program is still running!\n Do you want to kill it?", + "Your program is still running!\n Do you want to kill it?", default="ok", parent=self.text) if response is False: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:22:40 2015 From: python-checkins at python.org (terry.reedy) Date: Fri, 20 Nov 2015 17:22:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Make_it_slight?= =?utf-8?q?ly_clearer_that_IDLE_close_message_is_referring_to_user_program?= =?utf-8?q?=2C?= Message-ID: <20151120172240.4679.7870@psf.io> https://hg.python.org/cpython/rev/8636f0625408 changeset: 99230:8636f0625408 branch: 3.4 parent: 99224:3e723559d9f1 user: Terry Jan Reedy date: Fri Nov 20 12:21:48 2015 -0500 summary: Make it slightly clearer that IDLE close message is referring to user program, not to IDLE itself. files: Lib/idlelib/PyShell.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -989,7 +989,7 @@ if self.executing: response = tkMessageBox.askokcancel( "Kill?", - "The program is still running!\n Do you want to kill it?", + "Your program is still running!\n Do you want to kill it?", default="ok", parent=self.text) if response is False: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:22:40 2015 From: python-checkins at python.org (terry.reedy) Date: Fri, 20 Nov 2015 17:22:40 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151120172240.21869.32279@psf.io> https://hg.python.org/cpython/rev/64e1a6c99037 changeset: 99231:64e1a6c99037 branch: 3.5 parent: 99227:4f30b0d47c24 parent: 99230:8636f0625408 user: Terry Jan Reedy date: Fri Nov 20 12:22:06 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/PyShell.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -989,7 +989,7 @@ if self.executing: response = tkMessageBox.askokcancel( "Kill?", - "The program is still running!\n Do you want to kill it?", + "Your program is still running!\n Do you want to kill it?", default="ok", parent=self.text) if response is False: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:22:40 2015 From: python-checkins at python.org (terry.reedy) Date: Fri, 20 Nov 2015 17:22:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Make_it_slight?= =?utf-8?q?ly_clearer_that_IDLE_close_message_is_referring_to_user_program?= =?utf-8?q?=2C?= Message-ID: <20151120172239.36877.99881@psf.io> https://hg.python.org/cpython/rev/5588ec7f208e changeset: 99229:5588ec7f208e branch: 2.7 parent: 99207:5d88c1d413b9 user: Terry Jan Reedy date: Fri Nov 20 12:21:40 2015 -0500 summary: Make it slightly clearer that IDLE close message is referring to user program, not to IDLE itself. files: Lib/idlelib/PyShell.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/idlelib/PyShell.py b/Lib/idlelib/PyShell.py --- a/Lib/idlelib/PyShell.py +++ b/Lib/idlelib/PyShell.py @@ -1006,7 +1006,7 @@ if self.executing: response = tkMessageBox.askokcancel( "Kill?", - "The program is still running!\n Do you want to kill it?", + "Your program is still running!\n Do you want to kill it?", default="ok", parent=self.text) if response is False: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:20 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:20 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151120174420.14367.63190@psf.io> https://hg.python.org/cpython/rev/12d2ed31ed85 changeset: 99234:12d2ed31ed85 branch: 3.5 parent: 99231:64e1a6c99037 parent: 99233:ea1c1b88be89 user: Yury Selivanov date: Fri Nov 20 12:39:51 2015 -0500 summary: Merge 3.4 files: Lib/test/test_asyncio/test_base_events.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,7 +782,7 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - with self.subTest('Loop %d/2' % i): + # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. self.loop.call_soon(self.loop.stop) self.loop.run_forever() self.assertEqual(callcount, 1) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:20 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:20 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151120174420.21849.39352@psf.io> https://hg.python.org/cpython/rev/76ff3cfef410 changeset: 99235:76ff3cfef410 parent: 99232:96d1cb825c85 parent: 99234:12d2ed31ed85 user: Yury Selivanov date: Fri Nov 20 12:40:02 2015 -0500 summary: Merge 3.5 files: Lib/test/test_asyncio/test_base_events.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,7 +782,7 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - with self.subTest('Loop %d/2' % i): + # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. self.loop.call_soon(self.loop.stop) self.loop.run_forever() self.assertEqual(callcount, 1) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:20 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:20 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogU3lu?= =?utf-8?q?c_with_github?= Message-ID: <20151120174420.18216.74864@psf.io> https://hg.python.org/cpython/rev/ea1c1b88be89 changeset: 99233:ea1c1b88be89 branch: 3.4 parent: 99230:8636f0625408 user: Yury Selivanov date: Fri Nov 20 12:39:43 2015 -0500 summary: asyncio: Sync with github files: Lib/test/test_asyncio/test_base_events.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,7 +782,7 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - with self.subTest('Loop %d/2' % i): + # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. self.loop.call_soon(self.loop.stop) self.loop.run_forever() self.assertEqual(callcount, 1) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:22 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:22 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogRHJv?= =?utf-8?q?p_=22value=22_parameter_from_Task=2E=5Fstep_method=2E?= Message-ID: <20151120174420.4537.87813@psf.io> https://hg.python.org/cpython/rev/cce15765a1eb changeset: 99236:cce15765a1eb branch: 3.4 parent: 99233:ea1c1b88be89 user: Yury Selivanov date: Fri Nov 20 12:41:03 2015 -0500 summary: asyncio: Drop "value" parameter from Task._step method. files: Lib/asyncio/tasks.py | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -220,9 +220,9 @@ self._must_cancel = True return True - def _step(self, value=None, exc=None): + def _step(self, exc=None): assert not self.done(), \ - '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) + '_step(): already done: {!r}, {!r}'.format(self, exc) if self._must_cancel: if not isinstance(exc, futures.CancelledError): exc = futures.CancelledError() @@ -231,12 +231,14 @@ self._fut_waiter = None self.__class__._current_tasks[self._loop] = self - # Call either coro.throw(exc) or coro.send(value). + # Call either coro.throw(exc) or coro.send(None). try: - if exc is not None: + if exc is None: + # We use the `send` method directly, because coroutines + # don't have `__iter__` and `__next__` methods. + result = coro.send(None) + else: result = coro.throw(exc) - else: - result = coro.send(value) except StopIteration as exc: self.set_result(exc.value) except futures.CancelledError as exc: @@ -258,7 +260,7 @@ self._must_cancel = False else: self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from ' 'in task {!r} with {!r}'.format(self, result))) @@ -268,7 +270,7 @@ elif inspect.isgenerator(result): # Yielding a generator is just wrong. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from for ' 'generator in task {!r} with {}'.format( @@ -276,7 +278,7 @@ else: # Yielding something else is an error. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'Task got bad yield: {!r}'.format(result))) finally: @@ -288,7 +290,7 @@ future.result() except Exception as exc: # This may also be a cancellation. - self._step(None, exc) + self._step(exc) else: # Don't pass the value of `future.result()` explicitly, # as `Future.__iter__` and `Future.__await__` don't need it. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:22 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:22 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151120174420.63498.93449@psf.io> https://hg.python.org/cpython/rev/a3f5d053ab24 changeset: 99237:a3f5d053ab24 branch: 3.5 parent: 99234:12d2ed31ed85 parent: 99236:cce15765a1eb user: Yury Selivanov date: Fri Nov 20 12:41:43 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/tasks.py | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -220,9 +220,9 @@ self._must_cancel = True return True - def _step(self, value=None, exc=None): + def _step(self, exc=None): assert not self.done(), \ - '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) + '_step(): already done: {!r}, {!r}'.format(self, exc) if self._must_cancel: if not isinstance(exc, futures.CancelledError): exc = futures.CancelledError() @@ -231,12 +231,14 @@ self._fut_waiter = None self.__class__._current_tasks[self._loop] = self - # Call either coro.throw(exc) or coro.send(value). + # Call either coro.throw(exc) or coro.send(None). try: - if exc is not None: + if exc is None: + # We use the `send` method directly, because coroutines + # don't have `__iter__` and `__next__` methods. + result = coro.send(None) + else: result = coro.throw(exc) - else: - result = coro.send(value) except StopIteration as exc: self.set_result(exc.value) except futures.CancelledError as exc: @@ -258,7 +260,7 @@ self._must_cancel = False else: self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from ' 'in task {!r} with {!r}'.format(self, result))) @@ -268,7 +270,7 @@ elif inspect.isgenerator(result): # Yielding a generator is just wrong. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from for ' 'generator in task {!r} with {}'.format( @@ -276,7 +278,7 @@ else: # Yielding something else is an error. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'Task got bad yield: {!r}'.format(result))) finally: @@ -288,7 +290,7 @@ future.result() except Exception as exc: # This may also be a cancellation. - self._step(None, exc) + self._step(exc) else: # Don't pass the value of `future.result()` explicitly, # as `Future.__iter__` and `Future.__await__` don't need it. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:25 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:25 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151120174425.31767.72677@psf.io> https://hg.python.org/cpython/rev/4c57c36690a9 changeset: 99238:4c57c36690a9 parent: 99235:76ff3cfef410 parent: 99237:a3f5d053ab24 user: Yury Selivanov date: Fri Nov 20 12:41:53 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/tasks.py | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -220,9 +220,9 @@ self._must_cancel = True return True - def _step(self, value=None, exc=None): + def _step(self, exc=None): assert not self.done(), \ - '_step(): already done: {!r}, {!r}, {!r}'.format(self, value, exc) + '_step(): already done: {!r}, {!r}'.format(self, exc) if self._must_cancel: if not isinstance(exc, futures.CancelledError): exc = futures.CancelledError() @@ -231,12 +231,14 @@ self._fut_waiter = None self.__class__._current_tasks[self._loop] = self - # Call either coro.throw(exc) or coro.send(value). + # Call either coro.throw(exc) or coro.send(None). try: - if exc is not None: + if exc is None: + # We use the `send` method directly, because coroutines + # don't have `__iter__` and `__next__` methods. + result = coro.send(None) + else: result = coro.throw(exc) - else: - result = coro.send(value) except StopIteration as exc: self.set_result(exc.value) except futures.CancelledError as exc: @@ -258,7 +260,7 @@ self._must_cancel = False else: self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from ' 'in task {!r} with {!r}'.format(self, result))) @@ -268,7 +270,7 @@ elif inspect.isgenerator(result): # Yielding a generator is just wrong. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'yield was used instead of yield from for ' 'generator in task {!r} with {}'.format( @@ -276,7 +278,7 @@ else: # Yielding something else is an error. self._loop.call_soon( - self._step, None, + self._step, RuntimeError( 'Task got bad yield: {!r}'.format(result))) finally: @@ -288,7 +290,7 @@ future.result() except Exception as exc: # This may also be a cancellation. - self._step(None, exc) + self._step(exc) else: # Don't pass the value of `future.result()` explicitly, # as `Future.__iter__` and `Future.__await__` don't need it. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:26 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:26 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151120174426.14359.91997@psf.io> https://hg.python.org/cpython/rev/f7dc0c8a73b6 changeset: 99240:f7dc0c8a73b6 branch: 3.5 parent: 99237:a3f5d053ab24 parent: 99239:9bd5d2ed436a user: Yury Selivanov date: Fri Nov 20 12:44:03 2015 -0500 summary: Merge 3.4 files: Lib/test/test_asyncio/test_base_events.py | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,10 +782,9 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:26 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151120174426.31769.37987@psf.io> https://hg.python.org/cpython/rev/0d0a82bf4537 changeset: 99241:0d0a82bf4537 parent: 99238:4c57c36690a9 parent: 99240:f7dc0c8a73b6 user: Yury Selivanov date: Fri Nov 20 12:44:12 2015 -0500 summary: Merge 3.5 files: Lib/test/test_asyncio/test_base_events.py | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,10 +782,9 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:44:27 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:44:27 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpby50ZXN0?= =?utf-8?q?s=3A_Fix_whitespace?= Message-ID: <20151120174426.105893.90261@psf.io> https://hg.python.org/cpython/rev/9bd5d2ed436a changeset: 99239:9bd5d2ed436a branch: 3.4 parent: 99236:cce15765a1eb user: Yury Selivanov date: Fri Nov 20 12:43:52 2015 -0500 summary: asyncio.tests: Fix whitespace files: Lib/test/test_asyncio/test_base_events.py | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,10 +782,9 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - # with self.subTest('Loop %d/2' % i): # Not in Python 3.3. - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:58:07 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:58:07 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E4?= Message-ID: <20151120175807.21867.41458@psf.io> https://hg.python.org/cpython/rev/908dd4b916a6 changeset: 99243:908dd4b916a6 branch: 3.5 parent: 99240:f7dc0c8a73b6 parent: 99242:0ef231a868ef user: Yury Selivanov date: Fri Nov 20 12:57:47 2015 -0500 summary: Merge 3.4 files: Lib/asyncio/test_utils.py | 11 +++++++++++ Lib/test/test_asyncio/test_base_events.py | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -24,6 +24,7 @@ ssl = None from . import base_events +from . import compat from . import events from . import futures from . import selectors @@ -421,6 +422,16 @@ # in an except block of a generator self.assertEqual(sys.exc_info(), (None, None, None)) + if not compat.PY34: + # Python 3.3 compatibility + def subTest(self, *args, **kwargs): + class EmptyCM: + def __enter__(self): + pass + def __exit__(self, *exc): + pass + return EmptyCM() + @contextlib.contextmanager def disable_logger(): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,9 +782,10 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:58:08 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:58:08 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogYXN5bmNpbzogRml4?= =?utf-8?q?_with_github?= Message-ID: <20151120175807.79043.91469@psf.io> https://hg.python.org/cpython/rev/0ef231a868ef changeset: 99242:0ef231a868ef branch: 3.4 parent: 99239:9bd5d2ed436a user: Yury Selivanov date: Fri Nov 20 12:57:34 2015 -0500 summary: asyncio: Fix with github See https://github.com/python/asyncio/pull/295 for details files: Lib/asyncio/test_utils.py | 11 +++++++++++ Lib/test/test_asyncio/test_base_events.py | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -24,6 +24,7 @@ ssl = None from . import base_events +from . import compat from . import events from . import futures from . import selectors @@ -421,6 +422,16 @@ # in an except block of a generator self.assertEqual(sys.exc_info(), (None, None, None)) + if not compat.PY34: + # Python 3.3 compatibility + def subTest(self, *args, **kwargs): + class EmptyCM: + def __enter__(self): + pass + def __exit__(self, *exc): + pass + return EmptyCM() + @contextlib.contextmanager def disable_logger(): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,9 +782,10 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 12:58:08 2015 From: python-checkins at python.org (yury.selivanov) Date: Fri, 20 Nov 2015 17:58:08 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?b?KTogTWVyZ2UgMy41?= Message-ID: <20151120175808.105899.59090@psf.io> https://hg.python.org/cpython/rev/af1903ab6b1f changeset: 99244:af1903ab6b1f parent: 99241:0d0a82bf4537 parent: 99243:908dd4b916a6 user: Yury Selivanov date: Fri Nov 20 12:58:00 2015 -0500 summary: Merge 3.5 files: Lib/asyncio/test_utils.py | 11 +++++++++++ Lib/test/test_asyncio/test_base_events.py | 7 ++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Lib/asyncio/test_utils.py b/Lib/asyncio/test_utils.py --- a/Lib/asyncio/test_utils.py +++ b/Lib/asyncio/test_utils.py @@ -24,6 +24,7 @@ ssl = None from . import base_events +from . import compat from . import events from . import futures from . import selectors @@ -421,6 +422,16 @@ # in an except block of a generator self.assertEqual(sys.exc_info(), (None, None, None)) + if not compat.PY34: + # Python 3.3 compatibility + def subTest(self, *args, **kwargs): + class EmptyCM: + def __enter__(self): + pass + def __exit__(self, *exc): + pass + return EmptyCM() + @contextlib.contextmanager def disable_logger(): diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py --- a/Lib/test/test_asyncio/test_base_events.py +++ b/Lib/test/test_asyncio/test_base_events.py @@ -782,9 +782,10 @@ self.loop._selector.select.return_value = (event_sentinel,) for i in range(1, 3): - self.loop.call_soon(self.loop.stop) - self.loop.run_forever() - self.assertEqual(callcount, 1) + with self.subTest('Loop %d/2' % i): + self.loop.call_soon(self.loop.stop) + self.loop.run_forever() + self.assertEqual(callcount, 1) def test_run_once(self): # Simple test for test_utils.run_once(). It may seem strange -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 14:56:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Fri, 20 Nov 2015 19:56:47 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Njc4?= =?utf-8?q?=3A_Copy_buffer_objects_to_null-terminated_strings=2E?= Message-ID: <20151120195646.18202.47837@psf.io> https://hg.python.org/cpython/rev/3ef7d1af5195 changeset: 99245:3ef7d1af5195 branch: 2.7 parent: 99229:5588ec7f208e user: Serhiy Storchaka date: Fri Nov 20 21:56:21 2015 +0200 summary: Issue #25678: Copy buffer objects to null-terminated strings. Avoid buffer overreads when int(), long(), float(), and compile() are passed buffer objects. Similar code is removed from the complex() constructor, where it was not reachable. Patch backported from issue #24802 by Eryk Sun. files: Lib/test/test_compile.py | 13 ++++++++++++ Lib/test/test_float.py | 30 ++++++++++++++++++++++++++++ Lib/test/test_int.py | 25 +++++++++++++++++++--- Misc/NEWS | 4 +++ Objects/abstract.c | 27 ++++++++++++++++++++---- Objects/complexobject.c | 2 +- Objects/floatobject.c | 11 +++++++++- Python/bltinmodule.c | 21 ++++++++++++++---- 8 files changed, 117 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -571,6 +571,19 @@ test_support.rmtree(tmpd) self.assertIn(b"Non-ASCII", err) + def test_null_terminated(self): + # The source code is null-terminated internally, but bytes-like + # objects are accepted, which could be not terminated. + with self.assertRaisesRegexp(TypeError, "without null bytes"): + compile(u"123\x00", "", "eval") + with self.assertRaisesRegexp(TypeError, "without null bytes"): + compile(buffer("123\x00"), "", "eval") + code = compile(buffer("123\x00", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) + code = compile(buffer("1234", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) + code = compile(buffer("$23$", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -53,6 +53,36 @@ float('.' + '1'*1000) float(unicode('.' + '1'*1000)) + def test_non_numeric_input_types(self): + # Test possible non-numeric types for the argument x, including + # subclasses of the explicitly documented accepted types. + class CustomStr(str): pass + class CustomByteArray(bytearray): pass + factories = [str, bytearray, CustomStr, CustomByteArray, buffer] + + if test_support.have_unicode: + class CustomUnicode(unicode): pass + factories += [unicode, CustomUnicode] + + for f in factories: + x = f(" 3.14 ") + msg = 'x has value %s and type %s' % (x, type(x).__name__) + try: + self.assertEqual(float(x), 3.14, msg=msg) + except TypeError, err: + raise AssertionError('For %s got TypeError: %s' % + (type(x).__name__, err)) + errmsg = "could not convert" + with self.assertRaisesRegexp(ValueError, errmsg, msg=msg): + float(f('A' * 0x10)) + + def test_float_buffer(self): + self.assertEqual(float(buffer('12.3', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3\x00', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3 ', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3A', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.34', 1, 3)), 2.3) + def check_conversion_to_int(self, x): """Check that int(x) has the correct value and type, for a float x.""" n = int(x) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -340,20 +340,37 @@ # Test possible valid non-numeric types for x, including subclasses # of the allowed built-in types. class CustomStr(str): pass - values = ['100', CustomStr('100')] + class CustomByteArray(bytearray): pass + factories = [str, bytearray, CustomStr, CustomByteArray, buffer] if have_unicode: class CustomUnicode(unicode): pass - values += [unicode('100'), CustomUnicode(unicode('100'))] + factories += [unicode, CustomUnicode] - for x in values: + for f in factories: + x = f('100') msg = 'x has value %s and type %s' % (x, type(x).__name__) try: self.assertEqual(int(x), 100, msg=msg) - self.assertEqual(int(x, 2), 4, msg=msg) + if isinstance(x, basestring): + self.assertEqual(int(x, 2), 4, msg=msg) except TypeError, err: raise AssertionError('For %s got TypeError: %s' % (type(x).__name__, err)) + if not isinstance(x, basestring): + errmsg = "can't convert non-string" + with self.assertRaisesRegexp(TypeError, errmsg, msg=msg): + int(x, 2) + errmsg = 'invalid literal' + with self.assertRaisesRegexp(ValueError, errmsg, msg=msg): + int(f('A' * 0x10)) + + def test_int_buffer(self): + self.assertEqual(int(buffer('123', 1, 2)), 23) + self.assertEqual(int(buffer('123\x00', 1, 2)), 23) + self.assertEqual(int(buffer('123 ', 1, 2)), 23) + self.assertEqual(int(buffer('123A', 1, 2)), 23) + self.assertEqual(int(buffer('1234', 1, 2)), 23) def test_error_on_string_float_for_x(self): self.assertRaises(ValueError, int, '1.2') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #25678: Avoid buffer overreads when int(), long(), float(), and + compile() are passed buffer objects. These objects are not necessarily + terminated by a null byte, but the functions assumed they were. + - Issue #25388: Fixed tokenizer hang when processing undecodable source code with a null byte. diff --git a/Objects/abstract.c b/Objects/abstract.c --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -1666,8 +1666,17 @@ PyUnicode_GET_SIZE(o), 10); #endif - if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return int_from_string((char*)buffer, buffer_len); + if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) { + PyObject *result, *str; + + /* Copy to NUL-terminated buffer. */ + str = PyString_FromStringAndSize((const char *)buffer, buffer_len); + if (str == NULL) + return NULL; + result = int_from_string(PyString_AS_STRING(str), buffer_len); + Py_DECREF(str); + return result; + } return type_error("int() argument must be a string or a " "number, not '%.200s'", o); @@ -1765,9 +1774,17 @@ PyUnicode_GET_SIZE(o), 10); #endif - if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) - return long_from_string(buffer, buffer_len); - + if (!PyObject_AsCharBuffer(o, &buffer, &buffer_len)) { + PyObject *result, *str; + + /* Copy to NUL-terminated buffer. */ + str = PyString_FromStringAndSize((const char *)buffer, buffer_len); + if (str == NULL) + return NULL; + result = long_from_string(PyString_AS_STRING(str), buffer_len); + Py_DECREF(str); + return result; + } return type_error("long() argument must be a string or a " "number, not '%.200s'", o); } diff --git a/Objects/complexobject.c b/Objects/complexobject.c --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1000,7 +1000,7 @@ len = strlen(s); } #endif - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else { PyErr_SetString(PyExc_TypeError, "complex() arg is not a string"); return NULL; diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -180,6 +180,7 @@ char *s_buffer = NULL; #endif Py_ssize_t len; + PyObject *str = NULL; PyObject *result = NULL; if (pend) @@ -202,7 +203,14 @@ len = strlen(s); } #endif - else if (PyObject_AsCharBuffer(v, &s, &len)) { + else if (!PyObject_AsCharBuffer(v, &s, &len)) { + /* Copy to NUL-terminated buffer. */ + str = PyString_FromStringAndSize(s, len); + if (str == NULL) + return NULL; + s = PyString_AS_STRING(str); + } + else { PyErr_SetString(PyExc_TypeError, "float() argument must be a string or a number"); return NULL; @@ -233,6 +241,7 @@ if (s_buffer) PyMem_FREE(s_buffer); #endif + Py_XDECREF(str); return result; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -538,18 +538,29 @@ } return result; } - + if (PyString_Check(cmd)) { + str = PyString_AS_STRING(cmd); + length = PyString_GET_SIZE(cmd); + } #ifdef Py_USING_UNICODE - if (PyUnicode_Check(cmd)) { + else if (PyUnicode_Check(cmd)) { tmp = PyUnicode_AsUTF8String(cmd); if (tmp == NULL) return NULL; - cmd = tmp; cf.cf_flags |= PyCF_SOURCE_IS_UTF8; + str = PyString_AS_STRING(tmp); + length = PyString_GET_SIZE(tmp); } #endif - - if (PyObject_AsReadBuffer(cmd, (const void **)&str, &length)) + else if (!PyObject_AsReadBuffer(cmd, (const void **)&str, &length)) { + /* Copy to NUL-terminated buffer. */ + tmp = PyString_FromStringAndSize(str, length); + if (tmp == NULL) + return NULL; + str = PyString_AS_STRING(tmp); + length = PyString_GET_SIZE(tmp); + } + else goto cleanup; if ((size_t)length != strlen(str)) { PyErr_SetString(PyExc_TypeError, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 16:12:46 2015 From: python-checkins at python.org (ethan.furman) Date: Fri, 20 Nov 2015 21:12:46 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Close_25594=3A_advise_agai?= =?utf-8?q?nst_accessing_Enum_members_from_other_members?= Message-ID: <20151120211246.105897.60683@psf.io> https://hg.python.org/cpython/rev/f4b495ceab17 changeset: 99246:f4b495ceab17 parent: 99244:af1903ab6b1f user: Ethan Furman date: Fri Nov 20 13:12:26 2015 -0800 summary: Close 25594: advise against accessing Enum members from other members files: Doc/library/enum.rst | 24 +++++++++++++++--------- 1 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -730,18 +730,24 @@ Finer Points ^^^^^^^^^^^^ -Enum members are instances of an Enum class, and even though they are -accessible as `EnumClass.member`, they are not accessible directly from -the member:: +:class:`Enum` members are instances of an :class:`Enum` class, and even +though they are accessible as `EnumClass.member`, they should not be accessed +directly from the member as that lookup may fail or, worse, return something +besides the :class:`Enum` member you looking for:: - >>> Color.red - - >>> Color.red.blue - Traceback (most recent call last): + >>> class FieldTypes(Enum): + ... name = 0 + ... value = 1 + ... size = 2 ... - AttributeError: 'Color' object has no attribute 'blue' + >>> FieldTypes.value.size + + >>> FieldTypes.size.value + 2 -Likewise, the :attr:`__members__` is only available on the class. +.. versionchanged:: 3.5 + +The :attr:`__members__` attribute is only available on the class. If you give your :class:`Enum` subclass extra methods, like the `Planet`_ class above, those methods will show up in a :func:`dir` of the member, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 16:19:54 2015 From: python-checkins at python.org (ethan.furman) Date: Fri, 20 Nov 2015 21:19:54 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_null_merge?= Message-ID: <20151120211954.21873.80209@psf.io> https://hg.python.org/cpython/rev/3128f51967b4 changeset: 99248:3128f51967b4 parent: 99246:f4b495ceab17 parent: 99247:276cf69b911e user: Ethan Furman date: Fri Nov 20 13:19:35 2015 -0800 summary: null merge files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 16:19:56 2015 From: python-checkins at python.org (ethan.furman) Date: Fri, 20 Nov 2015 21:19:56 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Close_issue255?= =?utf-8?q?94=3A_advise_against_accessing_Enum_members_from_other_members?= Message-ID: <20151120211954.79033.37657@psf.io> https://hg.python.org/cpython/rev/276cf69b911e changeset: 99247:276cf69b911e branch: 3.5 parent: 99243:908dd4b916a6 user: Ethan Furman date: Fri Nov 20 13:17:27 2015 -0800 summary: Close issue25594: advise against accessing Enum members from other members files: Doc/library/enum.rst | 24 +++++++++++++++--------- 1 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst --- a/Doc/library/enum.rst +++ b/Doc/library/enum.rst @@ -730,18 +730,24 @@ Finer Points ^^^^^^^^^^^^ -Enum members are instances of an Enum class, and even though they are -accessible as `EnumClass.member`, they are not accessible directly from -the member:: +:class:`Enum` members are instances of an :class:`Enum` class, and even +though they are accessible as `EnumClass.member`, they should not be accessed +directly from the member as that lookup may fail or, worse, return something +besides the :class:`Enum` member you looking for:: - >>> Color.red - - >>> Color.red.blue - Traceback (most recent call last): + >>> class FieldTypes(Enum): + ... name = 0 + ... value = 1 + ... size = 2 ... - AttributeError: 'Color' object has no attribute 'blue' + >>> FieldTypes.value.size + + >>> FieldTypes.size.value + 2 -Likewise, the :attr:`__members__` is only available on the class. +.. versionchanged:: 3.5 + +The :attr:`__members__` attribute is only available on the class. If you give your :class:`Enum` subclass extra methods, like the `Planet`_ class above, those methods will show up in a :func:`dir` of the member, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 19:37:35 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 00:37:35 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151121003735.21515.11883@psf.io> https://hg.python.org/cpython/rev/dfadf250610e changeset: 99252:dfadf250610e parent: 99248:3128f51967b4 parent: 99251:2eb9c4abfee1 user: Terry Jan Reedy date: Fri Nov 20 19:37:14 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/Debugger.py | 60 +++++++++++++++++++++++++--- 1 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -17,7 +17,10 @@ self.set_step() return message = self.__frame2message(frame) - self.gui.interaction(message, frame) + try: + self.gui.interaction(message, frame) + except (TclError, RuntimeError): + pass def user_exception(self, frame, info): if self.in_rpc_code(frame): @@ -59,8 +62,42 @@ self.frame = None self.make_gui() self.interacting = 0 + self.nesting_level = 0 def run(self, *args): + # Deal with the scenario where we've already got a program running + # in the debugger and we want to start another. If that is the case, + # our second 'run' was invoked from an event dispatched not from + # the main event loop, but from the nested event loop in 'interaction' + # below. So our stack looks something like this: + # outer main event loop + # run() + # + # callback to debugger's interaction() + # nested event loop + # run() for second command + # + # This kind of nesting of event loops causes all kinds of problems + # (see e.g. issue #24455) especially when dealing with running as a + # subprocess, where there's all kinds of extra stuff happening in + # there - insert a traceback.print_stack() to check it out. + # + # By this point, we've already called restart_subprocess() in + # ScriptBinding. However, we also need to unwind the stack back to + # that outer event loop. To accomplish this, we: + # - return immediately from the nested run() + # - abort_loop ensures the nested event loop will terminate + # - the debugger's interaction routine completes normally + # - the restart_subprocess() will have taken care of stopping + # the running program, which will also let the outer run complete + # + # That leaves us back at the outer main event loop, at which point our + # after event can fire, and we'll come back to this routine with a + # clean stack. + if self.nesting_level > 0: + self.abort_loop() + self.root.after(100, lambda: self.run(*args)) + return try: self.interacting = 1 return self.idb.run(*args) @@ -71,6 +108,7 @@ if self.interacting: self.top.bell() return + self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. @@ -191,7 +229,12 @@ b.configure(state="normal") # self.top.wakeup() - self.root.mainloop() + # Nested main loop: Tkinter's main loop is not reentrant, so use + # Tcl's vwait facility, which reenters the event loop until an + # event handler sets the variable we're waiting on + self.nesting_level += 1 + self.root.tk.call('vwait', '::idledebugwait') + self.nesting_level -= 1 # for b in self.buttons: b.configure(state="disabled") @@ -215,23 +258,26 @@ def cont(self): self.idb.set_continue() - self.root.quit() + self.abort_loop() def step(self): self.idb.set_step() - self.root.quit() + self.abort_loop() def next(self): self.idb.set_next(self.frame) - self.root.quit() + self.abort_loop() def ret(self): self.idb.set_return(self.frame) - self.root.quit() + self.abort_loop() def quit(self): self.idb.set_quit() - self.root.quit() + self.abort_loop() + + def abort_loop(self): + self.root.tk.call('set', '::idledebugwait', '1') stackviewer = None -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 19:37:35 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 00:37:35 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151121003735.9708.54455@psf.io> https://hg.python.org/cpython/rev/2eb9c4abfee1 changeset: 99251:2eb9c4abfee1 branch: 3.5 parent: 99247:276cf69b911e parent: 99250:1ddd77a5e8c8 user: Terry Jan Reedy date: Fri Nov 20 19:37:00 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/Debugger.py | 60 +++++++++++++++++++++++++--- 1 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -17,7 +17,10 @@ self.set_step() return message = self.__frame2message(frame) - self.gui.interaction(message, frame) + try: + self.gui.interaction(message, frame) + except (TclError, RuntimeError): + pass def user_exception(self, frame, info): if self.in_rpc_code(frame): @@ -59,8 +62,42 @@ self.frame = None self.make_gui() self.interacting = 0 + self.nesting_level = 0 def run(self, *args): + # Deal with the scenario where we've already got a program running + # in the debugger and we want to start another. If that is the case, + # our second 'run' was invoked from an event dispatched not from + # the main event loop, but from the nested event loop in 'interaction' + # below. So our stack looks something like this: + # outer main event loop + # run() + # + # callback to debugger's interaction() + # nested event loop + # run() for second command + # + # This kind of nesting of event loops causes all kinds of problems + # (see e.g. issue #24455) especially when dealing with running as a + # subprocess, where there's all kinds of extra stuff happening in + # there - insert a traceback.print_stack() to check it out. + # + # By this point, we've already called restart_subprocess() in + # ScriptBinding. However, we also need to unwind the stack back to + # that outer event loop. To accomplish this, we: + # - return immediately from the nested run() + # - abort_loop ensures the nested event loop will terminate + # - the debugger's interaction routine completes normally + # - the restart_subprocess() will have taken care of stopping + # the running program, which will also let the outer run complete + # + # That leaves us back at the outer main event loop, at which point our + # after event can fire, and we'll come back to this routine with a + # clean stack. + if self.nesting_level > 0: + self.abort_loop() + self.root.after(100, lambda: self.run(*args)) + return try: self.interacting = 1 return self.idb.run(*args) @@ -71,6 +108,7 @@ if self.interacting: self.top.bell() return + self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. @@ -191,7 +229,12 @@ b.configure(state="normal") # self.top.wakeup() - self.root.mainloop() + # Nested main loop: Tkinter's main loop is not reentrant, so use + # Tcl's vwait facility, which reenters the event loop until an + # event handler sets the variable we're waiting on + self.nesting_level += 1 + self.root.tk.call('vwait', '::idledebugwait') + self.nesting_level -= 1 # for b in self.buttons: b.configure(state="disabled") @@ -215,23 +258,26 @@ def cont(self): self.idb.set_continue() - self.root.quit() + self.abort_loop() def step(self): self.idb.set_step() - self.root.quit() + self.abort_loop() def next(self): self.idb.set_next(self.frame) - self.root.quit() + self.abort_loop() def ret(self): self.idb.set_return(self.frame) - self.root.quit() + self.abort_loop() def quit(self): self.idb.set_quit() - self.root.quit() + self.abort_loop() + + def abort_loop(self): + self.root.tk.call('set', '::idledebugwait', '1') stackviewer = None -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 19:37:35 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 00:37:35 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0NDU1?= =?utf-8?q?=3A_Prevent_IDLE_from_hanging_when_a=29_closing_the_shell_while?= =?utf-8?q?_the?= Message-ID: <20151121003734.9697.37350@psf.io> https://hg.python.org/cpython/rev/1ddd77a5e8c8 changeset: 99250:1ddd77a5e8c8 branch: 3.4 parent: 99242:0ef231a868ef user: Terry Jan Reedy date: Fri Nov 20 19:36:43 2015 -0500 summary: Issue #24455: Prevent IDLE from hanging when a) closing the shell while the debugger is active (15347); b) closing the debugger with the [X] button (15348); and c) activating the debugger when already active (24455). The patch by Mark Roseman does this by making two changes. 1. To suspend and resume the gui.interaction method, use the tcl vwait mechanism interded for this purpose instead of root.mainloop & .quit. 2. In gui.run, allow any existing interaction to terminate first. files: Lib/idlelib/Debugger.py | 60 +++++++++++++++++++++++++--- 1 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -17,7 +17,10 @@ self.set_step() return message = self.__frame2message(frame) - self.gui.interaction(message, frame) + try: + self.gui.interaction(message, frame) + except (TclError, RuntimeError): + pass def user_exception(self, frame, info): if self.in_rpc_code(frame): @@ -59,8 +62,42 @@ self.frame = None self.make_gui() self.interacting = 0 + self.nesting_level = 0 def run(self, *args): + # Deal with the scenario where we've already got a program running + # in the debugger and we want to start another. If that is the case, + # our second 'run' was invoked from an event dispatched not from + # the main event loop, but from the nested event loop in 'interaction' + # below. So our stack looks something like this: + # outer main event loop + # run() + # + # callback to debugger's interaction() + # nested event loop + # run() for second command + # + # This kind of nesting of event loops causes all kinds of problems + # (see e.g. issue #24455) especially when dealing with running as a + # subprocess, where there's all kinds of extra stuff happening in + # there - insert a traceback.print_stack() to check it out. + # + # By this point, we've already called restart_subprocess() in + # ScriptBinding. However, we also need to unwind the stack back to + # that outer event loop. To accomplish this, we: + # - return immediately from the nested run() + # - abort_loop ensures the nested event loop will terminate + # - the debugger's interaction routine completes normally + # - the restart_subprocess() will have taken care of stopping + # the running program, which will also let the outer run complete + # + # That leaves us back at the outer main event loop, at which point our + # after event can fire, and we'll come back to this routine with a + # clean stack. + if self.nesting_level > 0: + self.abort_loop() + self.root.after(100, lambda: self.run(*args)) + return try: self.interacting = 1 return self.idb.run(*args) @@ -71,6 +108,7 @@ if self.interacting: self.top.bell() return + self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. @@ -191,7 +229,12 @@ b.configure(state="normal") # self.top.wakeup() - self.root.mainloop() + # Nested main loop: Tkinter's main loop is not reentrant, so use + # Tcl's vwait facility, which reenters the event loop until an + # event handler sets the variable we're waiting on + self.nesting_level += 1 + self.root.tk.call('vwait', '::idledebugwait') + self.nesting_level -= 1 # for b in self.buttons: b.configure(state="disabled") @@ -215,23 +258,26 @@ def cont(self): self.idb.set_continue() - self.root.quit() + self.abort_loop() def step(self): self.idb.set_step() - self.root.quit() + self.abort_loop() def next(self): self.idb.set_next(self.frame) - self.root.quit() + self.abort_loop() def ret(self): self.idb.set_return(self.frame) - self.root.quit() + self.abort_loop() def quit(self): self.idb.set_quit() - self.root.quit() + self.abort_loop() + + def abort_loop(self): + self.root.tk.call('set', '::idledebugwait', '1') stackviewer = None -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 19:37:36 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 00:37:36 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI0NDU1?= =?utf-8?q?=3A_Prevent_IDLE_from_hanging_when_a=29_closing_the_shell_while?= =?utf-8?q?_the?= Message-ID: <20151121003734.71411.1009@psf.io> https://hg.python.org/cpython/rev/f51467273d3b changeset: 99249:f51467273d3b branch: 2.7 parent: 99245:3ef7d1af5195 user: Terry Jan Reedy date: Fri Nov 20 19:36:38 2015 -0500 summary: Issue #24455: Prevent IDLE from hanging when a) closing the shell while the debugger is active (15347); b) closing the debugger with the [X] button (15348); and c) activating the debugger when already active (24455). The patch by Mark Roseman does this by making two changes. 1. To suspend and resume the gui.interaction method, use the tcl vwait mechanism interded for this purpose instead of root.mainloop & .quit. 2. In gui.run, allow any existing interaction to terminate first. files: Lib/idlelib/Debugger.py | 60 +++++++++++++++++++++++++--- 1 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -17,7 +17,10 @@ self.set_step() return message = self.__frame2message(frame) - self.gui.interaction(message, frame) + try: + self.gui.interaction(message, frame) + except (TclError, RuntimeError): + pass def user_exception(self, frame, info): if self.in_rpc_code(frame): @@ -59,8 +62,42 @@ self.frame = None self.make_gui() self.interacting = 0 + self.nesting_level = 0 def run(self, *args): + # Deal with the scenario where we've already got a program running + # in the debugger and we want to start another. If that is the case, + # our second 'run' was invoked from an event dispatched not from + # the main event loop, but from the nested event loop in 'interaction' + # below. So our stack looks something like this: + # outer main event loop + # run() + # + # callback to debugger's interaction() + # nested event loop + # run() for second command + # + # This kind of nesting of event loops causes all kinds of problems + # (see e.g. issue #24455) especially when dealing with running as a + # subprocess, where there's all kinds of extra stuff happening in + # there - insert a traceback.print_stack() to check it out. + # + # By this point, we've already called restart_subprocess() in + # ScriptBinding. However, we also need to unwind the stack back to + # that outer event loop. To accomplish this, we: + # - return immediately from the nested run() + # - abort_loop ensures the nested event loop will terminate + # - the debugger's interaction routine completes normally + # - the restart_subprocess() will have taken care of stopping + # the running program, which will also let the outer run complete + # + # That leaves us back at the outer main event loop, at which point our + # after event can fire, and we'll come back to this routine with a + # clean stack. + if self.nesting_level > 0: + self.abort_loop() + self.root.after(100, lambda: self.run(*args)) + return try: self.interacting = 1 return self.idb.run(*args) @@ -71,6 +108,7 @@ if self.interacting: self.top.bell() return + self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. @@ -191,7 +229,12 @@ b.configure(state="normal") # self.top.wakeup() - self.root.mainloop() + # Nested main loop: Tkinter's main loop is not reentrant, so use + # Tcl's vwait facility, which reenters the event loop until an + # event handler sets the variable we're waiting on + self.nesting_level += 1 + self.root.tk.call('vwait', '::idledebugwait') + self.nesting_level -= 1 # for b in self.buttons: b.configure(state="disabled") @@ -215,23 +258,26 @@ def cont(self): self.idb.set_continue() - self.root.quit() + self.abort_loop() def step(self): self.idb.set_step() - self.root.quit() + self.abort_loop() def next(self): self.idb.set_next(self.frame) - self.root.quit() + self.abort_loop() def ret(self): self.idb.set_return(self.frame) - self.root.quit() + self.abort_loop() def quit(self): self.idb.set_quit() - self.root.quit() + self.abort_loop() + + def abort_loop(self): + self.root.tk.call('set', '::idledebugwait', '1') stackviewer = None -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 20 22:14:04 2015 From: python-checkins at python.org (nick.coghlan) Date: Sat, 21 Nov 2015 03:14:04 +0000 Subject: [Python-checkins] =?utf-8?q?devguide=3A_Expand_preamble_for_motiv?= =?utf-8?q?ations_page?= Message-ID: <20151121031404.9710.65780@psf.io> https://hg.python.org/devguide/rev/cb6720c51e6e changeset: 772:cb6720c51e6e user: Nick Coghlan date: Sat Nov 21 13:13:57 2015 +1000 summary: Expand preamble for motivations page files: motivations.rst | 117 +++++++++++++++++++++++++---------- 1 files changed, 83 insertions(+), 34 deletions(-) diff --git a/motivations.rst b/motivations.rst --- a/motivations.rst +++ b/motivations.rst @@ -1,52 +1,55 @@ .. _motivations: -Motivations and Affiliations -============================ +Core Developer Motivations and Affiliations +=========================================== -CPython core contributors participate in the core development process for a -variety of reasons. Being accepted as a core contributor indicates only that +CPython core developers participate in the core development process for a +variety of reasons. Being accepted as a core reviewer indicates that an individual is interested in acquiring those responsibilities, has the -ability to collaborate effectively with existing core contributors, and has had +ability to collaborate effectively with existing core developers, and has had the time available to demonstrate both that interest and that ability. -This page allows core contributors that choose to do so to provide more +This page allows core developers that choose to do so to provide more information to the rest of the Python community regarding their personal -motivations for participating in the core development process (which can be -admittedly trying at times), as well as any personal and professional -affiliations which they consider particularly relevant. +motivations for participating in the core review process, as well as any +personal and professional affiliations which they consider particularly +relevant. -Core contributors that wish to provide this additional information add a new +Core developers that wish to provide this additional information add a new entry to the :ref:`published-motivations` section below. Guidelines relating to content and layout are included as comments in the source code for this page. -Core contributors that are available for training, consulting or contract work, +Core developers that are available for training, consulting or contract work, or are seeking crowdfunding support for their community contributions, may also choose to disclose that information here (including linking out to commercial sites with the relevant details). -Limitations on scope --------------------- +Goals of this page +------------------ -Changes to the software and documentation maintained by core contributors, -together with related design discussions, all take place in public venues, and -hence can be fully audited by anyone that cares to do so. Accordingly, core -contributors are NOT required to publish their motivations and affiliations if -they do not choose to do so. This helps to ensure that core contribution -processes remain open to anyone that is in a position to sign the `Contributor -Licensing Agreement`_, the details of which are filed privately with the Python -Software Foundation, rather than publicly. +The `issue metrics`_ automatically collected by the CPython issue tracker +strongly suggest that the current core development process is bottlenecked on +core reviewer time - this is most clearly indicated in the first metrics graph, +which shows both the number of open issues and the number of patches awaiting +review growing steadily over time, despite CPython being one of the most +active open source projects in the world. This bottleneck then impacts not only +resolving open issues and applying submitted patches, but also the process of +identifying, nominating and mentoring new core developers. -.. _Contributor Licensing Agreement: https://www.python.org/psf/contrib/contrib-form/ +The core commit statistics monitored by sites like `OpenHub`_ provide a good +record as to *who* is currently handling the bulk of the review and maintenance +work, but don't provide any indication as to the factors currently influencing +people's ability to spend time on reviewing proposed changes, or mentoring new +contributors. -While providing additional information on this page is entirely optional, -contributors that are not facing personal safety concerns are specifically -encouraged to disclose commercial affiliations in the following two cases +This page aims to provide at least some of that missing data by encouraging +core developers to disclose commercial affiliations in the following two cases (even if not currently paid for time spent participating in the core development process): -* contributors working for vendors that distribute a commercially supported +* developers working for vendors that distribute a commercially supported Python runtime -* contributors working for Sponsor Members of the Python Software Foundation +* developers working for Sponsor Members of the Python Software Foundation These are cases where disclosure of commercial interests helps to improve the overall transparency of the core development process, as well as making it @@ -54,19 +57,60 @@ them to participate in and contribute effectively to supporting the core development process. -Contributors that are available for consulting or contract work on behalf of +Core developers working for organisations with a vested interest in the +sustainability of the CPython core development process are also encouraged to +seek opportunities to spend work time on mentoring potential new core +developers, whether through the general `core mentorship program`_, through +mentoring colleagues, or through more targeted efforts like Outreachy's paid +`internships`_ and Google's `Summer of Code`_. + +Core developers that are available for consulting or contract work on behalf of the Python Software Foundation or other organisations are also encouraged to provide that information here, as this will help the PSF to better facilitate funding of core development work by organisations that don't -directly employ any core contributors themselves. +directly employ any core developers themselves. +Finally, some core developers seeking to increase the time they have available +to contribute to CPython may wish to pursue crowdfunding efforts that allow +their contributions to be funded directly by the community, rather than relying +on institutional sponsors allowing them to spend some or all of their work +time contributing to CPython development. + +.. _issue metrics: http://bugs.python.org/issue?@template=stats +.. _OpenHub: https://www.openhub.net/p/python/contributors +.. _core mentorship program: http://pythonmentors.com/ +.. _internships: https://www.gnome.org/outreachy/ +.. _Summer of Code: https://wiki.python.org/moin/SummerOfCode/2016 + + +Limitations on scope +-------------------- + +* Specific technical areas of interest for core developers should be captured in + the :ref:`Experts Index `. + +* This specific listing is limited to CPython core developers, but if this + experiment proves successful, it may make sense to create a more expansive + listing on the Python wiki that also covers issue triagers, and folks seeking + to become core developers. + +* Changes to the software and documentation maintained by core developers, + together with related design discussions, all take place in public venues, and + hence are inherently subject to full public review. Accordingly, core + developers are NOT required to publish their motivations and affiliations if + they do not choose to do so. This helps to ensure that core contribution + processes remain open to anyone that is in a position to sign the `Contributor + Licensing Agreement`_, the details of which are filed privately with the Python + Software Foundation, rather than publicly. + +.. _Contributor Licensing Agreement: https://www.python.org/psf/contrib/contrib-form/ .. _published-motivations: Published entries ----------------- -The following core contributors have chosen to provide additional details +The following core developers have chosen to provide additional details regarding their reasons for participating in the CPython core development process: @@ -76,7 +120,12 @@ avoid creating entries in the main table of contents. Topic headings should be in the form of "Name (Country)" to help give some - indication as to the geographic dispersal of core contributors. + indication as to the geographic dispersal of core developers. + + NOTE: The rest of these guidelines are highly provisional - we can evolve + them as people add entries, and we decide on the style we like. I (Nick) + made a best guess based on what I wanted to include, but it's hard to + really tell how it looks with only one entry. Entries should be written as short third person biographies, rather than being written in first person. @@ -130,6 +179,6 @@ works for Red Hat's Developer Experience team. In addition to his personal and professional interest in ensuring Python - remains an excellent choice for Linux-based network service development, he - is also interested in helping to ensure its continued suitability for - educational and data analysis use cases. + remains an excellent choice for Linux-based network service and system + utility development, he is also interested in helping to ensure its + continued suitability for educational and data analysis use cases. -- Repository URL: https://hg.python.org/devguide From python-checkins at python.org Sat Nov 21 00:05:56 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 05:05:56 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgMTUzNDg6?= =?utf-8?q?_Stop_debugger_engine_=28normally_in_user_process=29?= Message-ID: <20151121050556.21505.34652@psf.io> https://hg.python.org/cpython/rev/427ad0ede016 changeset: 99253:427ad0ede016 branch: 2.7 parent: 99249:f51467273d3b user: Terry Jan Reedy date: Sat Nov 21 00:04:58 2015 -0500 summary: Issue 15348: Stop debugger engine (normally in user process) before closing debugger window in IDLE process. This prevents one-per-line RuntimeErrors. files: Lib/idlelib/Debugger.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -19,7 +19,7 @@ message = self.__frame2message(frame) try: self.gui.interaction(message, frame) - except (TclError, RuntimeError): + except TclError: # When closing debugger window with [x] in 3.x pass def user_exception(self, frame, info): @@ -105,10 +105,13 @@ self.interacting = 0 def close(self, event=None): + try: + self.quit() + except Exception: + pass if self.interacting: self.top.bell() return - self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 00:05:57 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 05:05:57 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgMTUzNDg6?= =?utf-8?q?_Stop_debugger_engine_=28normally_in_user_process=29?= Message-ID: <20151121050556.21511.63740@psf.io> https://hg.python.org/cpython/rev/4eae64a9cd26 changeset: 99254:4eae64a9cd26 branch: 3.4 parent: 99250:1ddd77a5e8c8 user: Terry Jan Reedy date: Sat Nov 21 00:05:03 2015 -0500 summary: Issue 15348: Stop debugger engine (normally in user process) before closing debugger window in IDLE process. files: Lib/idlelib/Debugger.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -19,7 +19,7 @@ message = self.__frame2message(frame) try: self.gui.interaction(message, frame) - except (TclError, RuntimeError): + except TclError: # When closing debugger window with [x] in 3.x pass def user_exception(self, frame, info): @@ -105,10 +105,13 @@ self.interacting = 0 def close(self, event=None): + try: + self.quit() + except Exception: + pass if self.interacting: self.top.bell() return - self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 00:05:58 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 05:05:58 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Merge_with_3=2E4?= Message-ID: <20151121050557.71409.38168@psf.io> https://hg.python.org/cpython/rev/c3cc5d70a6bf changeset: 99255:c3cc5d70a6bf branch: 3.5 parent: 99251:2eb9c4abfee1 parent: 99254:4eae64a9cd26 user: Terry Jan Reedy date: Sat Nov 21 00:05:17 2015 -0500 summary: Merge with 3.4 files: Lib/idlelib/Debugger.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -19,7 +19,7 @@ message = self.__frame2message(frame) try: self.gui.interaction(message, frame) - except (TclError, RuntimeError): + except TclError: # When closing debugger window with [x] in 3.x pass def user_exception(self, frame, info): @@ -105,10 +105,13 @@ self.interacting = 0 def close(self, event=None): + try: + self.quit() + except Exception: + pass if self.interacting: self.top.bell() return - self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 00:06:02 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 05:06:02 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151121050602.9703.79836@psf.io> https://hg.python.org/cpython/rev/1b151f9d99bf changeset: 99256:1b151f9d99bf parent: 99252:dfadf250610e parent: 99255:c3cc5d70a6bf user: Terry Jan Reedy date: Sat Nov 21 00:05:35 2015 -0500 summary: Merge with 3.5 files: Lib/idlelib/Debugger.py | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/idlelib/Debugger.py b/Lib/idlelib/Debugger.py --- a/Lib/idlelib/Debugger.py +++ b/Lib/idlelib/Debugger.py @@ -19,7 +19,7 @@ message = self.__frame2message(frame) try: self.gui.interaction(message, frame) - except (TclError, RuntimeError): + except TclError: # When closing debugger window with [x] in 3.x pass def user_exception(self, frame, info): @@ -105,10 +105,13 @@ self.interacting = 0 def close(self, event=None): + try: + self.quit() + except Exception: + pass if self.interacting: self.top.bell() return - self.abort_loop() if self.stackviewer: self.stackviewer.close(); self.stackviewer = None # Clean up pyshell if user clicked debugger control close widget. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 00:30:32 2015 From: python-checkins at python.org (nick.coghlan) Date: Sat, 21 Nov 2015 05:30:32 +0000 Subject: [Python-checkins] =?utf-8?q?devguide=3A_Reviewer_-=3E_developer?= Message-ID: <20151121053031.38241.60253@psf.io> https://hg.python.org/devguide/rev/198554fa82c2 changeset: 773:198554fa82c2 user: Nick Coghlan date: Sat Nov 21 15:30:19 2015 +1000 summary: Reviewer -> developer files: motivations.rst | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/motivations.rst b/motivations.rst --- a/motivations.rst +++ b/motivations.rst @@ -4,7 +4,7 @@ =========================================== CPython core developers participate in the core development process for a -variety of reasons. Being accepted as a core reviewer indicates that +variety of reasons. Being accepted as a core developer indicates that an individual is interested in acquiring those responsibilities, has the ability to collaborate effectively with existing core developers, and has had the time available to demonstrate both that interest and that ability. @@ -29,7 +29,7 @@ The `issue metrics`_ automatically collected by the CPython issue tracker strongly suggest that the current core development process is bottlenecked on -core reviewer time - this is most clearly indicated in the first metrics graph, +core developer time - this is most clearly indicated in the first metrics graph, which shows both the number of open issues and the number of patches awaiting review growing steadily over time, despite CPython being one of the most active open source projects in the world. This bottleneck then impacts not only -- Repository URL: https://hg.python.org/devguide From solipsis at pitrou.net Sat Nov 21 03:43:34 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 21 Nov 2015 08:43:34 +0000 Subject: [Python-checkins] Daily reference leaks (1b151f9d99bf): sum=4 Message-ID: <20151121084334.38239.53574@psf.io> results for 1b151f9d99bf on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogMHB5UZ', '--timeout', '7200'] From python-checkins at python.org Sat Nov 21 05:59:42 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 10:59:42 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NjI2?= =?utf-8?q?=3A_Change_zlib_to_accept_Py=5Fssize=5Ft_and_cap_to_UINT=5FMAX?= Message-ID: <20151121105942.127558.8779@psf.io> https://hg.python.org/cpython/rev/80f6f77a7cc3 changeset: 99257:80f6f77a7cc3 branch: 3.5 parent: 99255:c3cc5d70a6bf user: Martin Panter date: Fri Nov 20 08:13:35 2015 +0000 summary: Issue #25626: Change zlib to accept Py_ssize_t and cap to UINT_MAX The underlying zlib library stores sizes in ?unsigned int?. The corresponding Python parameters are all sizes of buffers filled in by zlib, so it is okay to reduce higher values to the UINT_MAX internal cap. OverflowError is still raised for sizes that do not fit in Py_ssize_t. Sizes are now limited to Py_ssize_t rather than unsigned long, because Python byte strings cannot be larger than Py_ssize_t. Previously this could result in a SystemError on 32-bit platforms. This resolves a regression in the gzip module when reading more than UINT_MAX or LONG_MAX bytes in one call, introduced by revision 62723172412c. files: Doc/howto/clinic.rst | 16 +++--- Lib/test/support/__init__.py | 13 +++- Lib/test/test_gzip.py | 9 +++ Lib/test/test_zlib.py | 56 +++++++++++++++++++++- Misc/NEWS | 7 ++ Modules/clinic/zlibmodule.c.h | 8 +- Modules/zlibmodule.c | 58 +++++++++++----------- 7 files changed, 120 insertions(+), 47 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1249,18 +1249,18 @@ /*[python input] - class uint_converter(CConverter): + class capped_uint_converter(CConverter): type = 'unsigned int' - converter = 'uint_converter' + converter = 'capped_uint_converter' [python start generated code]*/ - /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ -This block adds a converter to Argument Clinic named ``uint``. Parameters -declared as ``uint`` will be declared as type ``unsigned int``, and will -be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` -converter function. -``uint`` variables automatically support default values. +This block adds a converter to Argument Clinic named ``capped_uint``. Parameters +declared as ``capped_uint`` will be declared as type ``unsigned int``, and will +be parsed by the ``'O&'`` format unit, which will call the +``capped_uint_converter`` converter function. ``capped_uint`` variables +automatically support default values. More sophisticated custom converters can insert custom C code to handle initialization and cleanup. diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1608,12 +1608,15 @@ def bigmemtest(size, memuse, dry_run=True): """Decorator for bigmem tests. - 'minsize' is the minimum useful size for the test (in arbitrary, - test-interpreted units.) 'memuse' is the number of 'bytes per size' for - the test, or a good estimate of it. + 'size' is a requested size for the test (in arbitrary, test-interpreted + units.) 'memuse' is the number of bytes per unit for the test, or a good + estimate of it. For example, a test that needs two byte buffers, of 4 GiB + each, could be decorated with @bigmemtest(size=_4G, memuse=2). - if 'dry_run' is False, it means the test doesn't support dummy runs - when -M is not specified. + The 'size' argument is normally passed to the decorated test method as an + extra argument. If 'dry_run' is true, the value passed to the test method + may be less than the requested value. If 'dry_run' is false, it means the + test doesn't support dummy runs when -M is not specified. """ def decorator(f): def wrapper(self): diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -3,6 +3,7 @@ import unittest from test import support +from test.support import bigmemtest, _4G import os import io import struct @@ -116,6 +117,14 @@ self.assertEqual(f.tell(), nread) self.assertEqual(b''.join(blocks), data1 * 50) + @bigmemtest(size=_4G, memuse=1) + def test_read_large(self, size): + # Read chunk size over UINT_MAX should be supported, despite zlib's + # limitation per low-level call + compressed = gzip.compress(data1, compresslevel=1) + f = gzip.GzipFile(fileobj=io.BytesIO(compressed), mode='rb') + self.assertEqual(f.read(size), data1) + def test_io_on_closed_object(self): # Test that I/O operations on closed GzipFile objects raise a # ValueError, just like the corresponding functions on file objects. diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -122,11 +122,17 @@ self.assertRaises(ValueError, zlib.decompressobj().flush, 0) self.assertRaises(ValueError, zlib.decompressobj().flush, -1) + @support.cpython_only + def test_overflow(self): + with self.assertRaisesRegex(OverflowError, 'int too large'): + zlib.decompress(b'', 15, sys.maxsize + 1) + with self.assertRaisesRegex(OverflowError, 'int too large'): + zlib.decompressobj().flush(sys.maxsize + 1) + class BaseCompressTestCase(object): def check_big_compress_buffer(self, size, compress_func): _1M = 1024 * 1024 - fmt = "%%0%dx" % (2 * _1M) # Generate 10MB worth of random, and expand it by repeating it. # The assumption is that zlib's memory is not big enough to exploit # such spread out redundancy. @@ -196,6 +202,18 @@ finally: data = None + @bigmemtest(size=_4G, memuse=1) + def test_large_bufsize(self, size): + # Test decompress(bufsize) parameter greater than the internal limit + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + self.assertEqual(zlib.decompress(compressed, 15, size), data) + + def test_custom_bufsize(self): + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data) + class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): # Test compression object @@ -364,6 +382,21 @@ self.assertRaises(ValueError, dco.decompress, b"", -1) self.assertEqual(b'', dco.unconsumed_tail) + def test_maxlen_large(self): + # Sizes up to sys.maxsize should be accepted, although zlib is + # internally limited to expressing sizes with unsigned int + data = HAMLET_SCENE * 10 + self.assertGreater(len(data), zlib.DEF_BUF_SIZE) + compressed = zlib.compress(data, 1) + dco = zlib.decompressobj() + self.assertEqual(dco.decompress(compressed, sys.maxsize), data) + + def test_maxlen_custom(self): + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + dco = zlib.decompressobj() + self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100]) + def test_clear_unconsumed_tail(self): # Issue #12050: calling decompress() without providing max_length # should clear the unconsumed_tail attribute. @@ -537,6 +570,22 @@ data = zlib.compress(input2) self.assertEqual(dco.flush(), input1[1:]) + @bigmemtest(size=_4G, memuse=1) + def test_flush_large_length(self, size): + # Test flush(length) parameter greater than internal limit UINT_MAX + input = HAMLET_SCENE * 10 + data = zlib.compress(input, 1) + dco = zlib.decompressobj() + dco.decompress(data, 1) + self.assertEqual(dco.flush(size), input[1:]) + + def test_flush_custom_length(self): + input = HAMLET_SCENE * 10 + data = zlib.compress(input, 1) + dco = zlib.decompressobj() + dco.decompress(data, 1) + self.assertEqual(dco.flush(CustomInt()), input[1:]) + @requires_Compress_copy def test_compresscopy(self): # Test copying a compression object @@ -725,5 +774,10 @@ """ +class CustomInt: + def __int__(self): + return 100 + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -77,6 +77,13 @@ Library ------- +- Issue #25626: Change three zlib functions to accept sizes that fit in + Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a + regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 + or 4 GiB. The change affects the zlib.Decompress.decompress() max_length + parameter, the zlib.decompress() bufsize parameter, and the + zlib.Decompress.flush() length parameter. + - Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS gives priority to errors such as EACCES over EEXIST. diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -68,7 +68,7 @@ unsigned int bufsize = DEF_BUF_SIZE; if (!PyArg_ParseTuple(args, "y*|iO&:decompress", - &data, &wbits, uint_converter, &bufsize)) + &data, &wbits, capped_uint_converter, &bufsize)) goto exit; return_value = zlib_decompress_impl(module, &data, wbits, bufsize); @@ -242,7 +242,7 @@ unsigned int max_length = 0; if (!PyArg_ParseTuple(args, "y*|O&:decompress", - &data, uint_converter, &max_length)) + &data, capped_uint_converter, &max_length)) goto exit; return_value = zlib_Decompress_decompress_impl(self, &data, max_length); @@ -353,7 +353,7 @@ unsigned int length = DEF_BUF_SIZE; if (!PyArg_ParseTuple(args, "|O&:flush", - uint_converter, &length)) + capped_uint_converter, &length)) goto exit; return_value = zlib_Decompress_flush_impl(self, length); @@ -438,4 +438,4 @@ #ifndef ZLIB_COMPRESS_COPY_METHODDEF #define ZLIB_COMPRESS_COPY_METHODDEF #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ -/*[clinic end generated code: output=56ed1147bbbb4788 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7734aec079550bc8 input=a9049054013a1b77]*/ diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -226,42 +226,42 @@ /*[python input] -class uint_converter(CConverter): +class capped_uint_converter(CConverter): type = 'unsigned int' - converter = 'uint_converter' + converter = 'capped_uint_converter' c_ignored_default = "0" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=22263855f7a3ebfd]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ static int -uint_converter(PyObject *obj, void *ptr) +capped_uint_converter(PyObject *obj, void *ptr) { - long val; - unsigned long uval; + PyObject *long_obj; + Py_ssize_t val; - val = PyLong_AsLong(obj); + long_obj = (PyObject *)_PyLong_FromNbInt(obj); + if (long_obj == NULL) { + return 0; + } + val = PyLong_AsSsize_t(long_obj); + Py_DECREF(long_obj); if (val == -1 && PyErr_Occurred()) { - uval = PyLong_AsUnsignedLong(obj); - if (uval == (unsigned long)-1 && PyErr_Occurred()) - return 0; + return 0; } - else { - if (val < 0) { - PyErr_SetString(PyExc_ValueError, - "value must be positive"); - return 0; - } - uval = (unsigned long)val; - } - - if (uval > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned int"); + if (val < 0) { + PyErr_SetString(PyExc_ValueError, + "value must be positive"); return 0; } - *(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int); + if ((size_t)val > UINT_MAX) { + *(unsigned int *)ptr = UINT_MAX; + } + else { + *(unsigned int *)ptr = Py_SAFE_DOWNCAST(val, Py_ssize_t, + unsigned int); + } return 1; } @@ -272,7 +272,7 @@ Compressed data. wbits: int(c_default="MAX_WBITS") = MAX_WBITS The window buffer size. - bufsize: uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE + bufsize: capped_uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE The initial output buffer size. / @@ -282,7 +282,7 @@ static PyObject * zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize) -/*[clinic end generated code: output=444d0987f3429574 input=0f4b9abb7103f50e]*/ +/*[clinic end generated code: output=444d0987f3429574 input=da095118b3243b27]*/ { PyObject *result_str = NULL; Byte *input; @@ -691,7 +691,7 @@ data: Py_buffer The binary data to decompress. - max_length: uint = 0 + max_length: capped_uint = 0 The maximum allowable length of the decompressed data. Unconsumed input data will be stored in the unconsumed_tail attribute. @@ -707,7 +707,7 @@ static PyObject * zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length) -/*[clinic end generated code: output=b82e2a2c19f5fe7b input=02cfc047377cec86]*/ +/*[clinic end generated code: output=b82e2a2c19f5fe7b input=68b6508ab07c2cf0]*/ { int err; unsigned int old_length, length = DEF_BUF_SIZE; @@ -1048,7 +1048,7 @@ /*[clinic input] zlib.Decompress.flush - length: uint(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE + length: capped_uint(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE the initial size of the output buffer. / @@ -1057,7 +1057,7 @@ static PyObject * zlib_Decompress_flush_impl(compobject *self, unsigned int length) -/*[clinic end generated code: output=db6fb753ab698e22 input=1580956505978993]*/ +/*[clinic end generated code: output=db6fb753ab698e22 input=1bb961eb21b62aa0]*/ { int err; unsigned int new_length; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 05:59:42 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 10:59:42 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325626=3A_Merge_zlib_fix_from_3=2E5?= Message-ID: <20151121105942.9712.8651@psf.io> https://hg.python.org/cpython/rev/afa1b6cd77a5 changeset: 99258:afa1b6cd77a5 parent: 99256:1b151f9d99bf parent: 99257:80f6f77a7cc3 user: Martin Panter date: Sat Nov 21 10:57:15 2015 +0000 summary: Issue #25626: Merge zlib fix from 3.5 files: Doc/howto/clinic.rst | 16 +++--- Lib/test/support/__init__.py | 13 +++- Lib/test/test_gzip.py | 9 +++ Lib/test/test_zlib.py | 56 +++++++++++++++++++++- Misc/NEWS | 7 ++ Modules/clinic/zlibmodule.c.h | 8 +- Modules/zlibmodule.c | 58 +++++++++++----------- 7 files changed, 120 insertions(+), 47 deletions(-) diff --git a/Doc/howto/clinic.rst b/Doc/howto/clinic.rst --- a/Doc/howto/clinic.rst +++ b/Doc/howto/clinic.rst @@ -1249,18 +1249,18 @@ /*[python input] - class uint_converter(CConverter): + class capped_uint_converter(CConverter): type = 'unsigned int' - converter = 'uint_converter' + converter = 'capped_uint_converter' [python start generated code]*/ - /*[python end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ -This block adds a converter to Argument Clinic named ``uint``. Parameters -declared as ``uint`` will be declared as type ``unsigned int``, and will -be parsed by the ``'O&'`` format unit, which will call the ``uint_converter`` -converter function. -``uint`` variables automatically support default values. +This block adds a converter to Argument Clinic named ``capped_uint``. Parameters +declared as ``capped_uint`` will be declared as type ``unsigned int``, and will +be parsed by the ``'O&'`` format unit, which will call the +``capped_uint_converter`` converter function. ``capped_uint`` variables +automatically support default values. More sophisticated custom converters can insert custom C code to handle initialization and cleanup. diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -1610,12 +1610,15 @@ def bigmemtest(size, memuse, dry_run=True): """Decorator for bigmem tests. - 'minsize' is the minimum useful size for the test (in arbitrary, - test-interpreted units.) 'memuse' is the number of 'bytes per size' for - the test, or a good estimate of it. + 'size' is a requested size for the test (in arbitrary, test-interpreted + units.) 'memuse' is the number of bytes per unit for the test, or a good + estimate of it. For example, a test that needs two byte buffers, of 4 GiB + each, could be decorated with @bigmemtest(size=_4G, memuse=2). - if 'dry_run' is False, it means the test doesn't support dummy runs - when -M is not specified. + The 'size' argument is normally passed to the decorated test method as an + extra argument. If 'dry_run' is true, the value passed to the test method + may be less than the requested value. If 'dry_run' is false, it means the + test doesn't support dummy runs when -M is not specified. """ def decorator(f): def wrapper(self): diff --git a/Lib/test/test_gzip.py b/Lib/test/test_gzip.py --- a/Lib/test/test_gzip.py +++ b/Lib/test/test_gzip.py @@ -3,6 +3,7 @@ import unittest from test import support +from test.support import bigmemtest, _4G import os import io import struct @@ -116,6 +117,14 @@ self.assertEqual(f.tell(), nread) self.assertEqual(b''.join(blocks), data1 * 50) + @bigmemtest(size=_4G, memuse=1) + def test_read_large(self, size): + # Read chunk size over UINT_MAX should be supported, despite zlib's + # limitation per low-level call + compressed = gzip.compress(data1, compresslevel=1) + f = gzip.GzipFile(fileobj=io.BytesIO(compressed), mode='rb') + self.assertEqual(f.read(size), data1) + def test_io_on_closed_object(self): # Test that I/O operations on closed GzipFile objects raise a # ValueError, just like the corresponding functions on file objects. diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -122,11 +122,17 @@ self.assertRaises(ValueError, zlib.decompressobj().flush, 0) self.assertRaises(ValueError, zlib.decompressobj().flush, -1) + @support.cpython_only + def test_overflow(self): + with self.assertRaisesRegex(OverflowError, 'int too large'): + zlib.decompress(b'', 15, sys.maxsize + 1) + with self.assertRaisesRegex(OverflowError, 'int too large'): + zlib.decompressobj().flush(sys.maxsize + 1) + class BaseCompressTestCase(object): def check_big_compress_buffer(self, size, compress_func): _1M = 1024 * 1024 - fmt = "%%0%dx" % (2 * _1M) # Generate 10MB worth of random, and expand it by repeating it. # The assumption is that zlib's memory is not big enough to exploit # such spread out redundancy. @@ -196,6 +202,18 @@ finally: data = None + @bigmemtest(size=_4G, memuse=1) + def test_large_bufsize(self, size): + # Test decompress(bufsize) parameter greater than the internal limit + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + self.assertEqual(zlib.decompress(compressed, 15, size), data) + + def test_custom_bufsize(self): + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data) + class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): # Test compression object @@ -364,6 +382,21 @@ self.assertRaises(ValueError, dco.decompress, b"", -1) self.assertEqual(b'', dco.unconsumed_tail) + def test_maxlen_large(self): + # Sizes up to sys.maxsize should be accepted, although zlib is + # internally limited to expressing sizes with unsigned int + data = HAMLET_SCENE * 10 + self.assertGreater(len(data), zlib.DEF_BUF_SIZE) + compressed = zlib.compress(data, 1) + dco = zlib.decompressobj() + self.assertEqual(dco.decompress(compressed, sys.maxsize), data) + + def test_maxlen_custom(self): + data = HAMLET_SCENE * 10 + compressed = zlib.compress(data, 1) + dco = zlib.decompressobj() + self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100]) + def test_clear_unconsumed_tail(self): # Issue #12050: calling decompress() without providing max_length # should clear the unconsumed_tail attribute. @@ -537,6 +570,22 @@ data = zlib.compress(input2) self.assertEqual(dco.flush(), input1[1:]) + @bigmemtest(size=_4G, memuse=1) + def test_flush_large_length(self, size): + # Test flush(length) parameter greater than internal limit UINT_MAX + input = HAMLET_SCENE * 10 + data = zlib.compress(input, 1) + dco = zlib.decompressobj() + dco.decompress(data, 1) + self.assertEqual(dco.flush(size), input[1:]) + + def test_flush_custom_length(self): + input = HAMLET_SCENE * 10 + data = zlib.compress(input, 1) + dco = zlib.decompressobj() + dco.decompress(data, 1) + self.assertEqual(dco.flush(CustomInt()), input[1:]) + @requires_Compress_copy def test_compresscopy(self): # Test copying a compression object @@ -725,5 +774,10 @@ """ +class CustomInt: + def __int__(self): + return 100 + + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -432,6 +432,13 @@ Library ------- +- Issue #25626: Change three zlib functions to accept sizes that fit in + Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a + regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 + or 4 GiB. The change affects the zlib.Decompress.decompress() max_length + parameter, the zlib.decompress() bufsize parameter, and the + zlib.Decompress.flush() length parameter. + - Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS gives priority to errors such as EACCES over EEXIST. diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h --- a/Modules/clinic/zlibmodule.c.h +++ b/Modules/clinic/zlibmodule.c.h @@ -68,7 +68,7 @@ unsigned int bufsize = DEF_BUF_SIZE; if (!PyArg_ParseTuple(args, "y*|iO&:decompress", - &data, &wbits, uint_converter, &bufsize)) + &data, &wbits, capped_uint_converter, &bufsize)) goto exit; return_value = zlib_decompress_impl(module, &data, wbits, bufsize); @@ -242,7 +242,7 @@ unsigned int max_length = 0; if (!PyArg_ParseTuple(args, "y*|O&:decompress", - &data, uint_converter, &max_length)) + &data, capped_uint_converter, &max_length)) goto exit; return_value = zlib_Decompress_decompress_impl(self, &data, max_length); @@ -353,7 +353,7 @@ unsigned int length = DEF_BUF_SIZE; if (!PyArg_ParseTuple(args, "|O&:flush", - uint_converter, &length)) + capped_uint_converter, &length)) goto exit; return_value = zlib_Decompress_flush_impl(self, length); @@ -438,4 +438,4 @@ #ifndef ZLIB_COMPRESS_COPY_METHODDEF #define ZLIB_COMPRESS_COPY_METHODDEF #endif /* !defined(ZLIB_COMPRESS_COPY_METHODDEF) */ -/*[clinic end generated code: output=56ed1147bbbb4788 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=7734aec079550bc8 input=a9049054013a1b77]*/ diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -226,42 +226,42 @@ /*[python input] -class uint_converter(CConverter): +class capped_uint_converter(CConverter): type = 'unsigned int' - converter = 'uint_converter' + converter = 'capped_uint_converter' c_ignored_default = "0" [python start generated code]*/ -/*[python end generated code: output=da39a3ee5e6b4b0d input=22263855f7a3ebfd]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=35521e4e733823c7]*/ static int -uint_converter(PyObject *obj, void *ptr) +capped_uint_converter(PyObject *obj, void *ptr) { - long val; - unsigned long uval; + PyObject *long_obj; + Py_ssize_t val; - val = PyLong_AsLong(obj); + long_obj = (PyObject *)_PyLong_FromNbInt(obj); + if (long_obj == NULL) { + return 0; + } + val = PyLong_AsSsize_t(long_obj); + Py_DECREF(long_obj); if (val == -1 && PyErr_Occurred()) { - uval = PyLong_AsUnsignedLong(obj); - if (uval == (unsigned long)-1 && PyErr_Occurred()) - return 0; + return 0; } - else { - if (val < 0) { - PyErr_SetString(PyExc_ValueError, - "value must be positive"); - return 0; - } - uval = (unsigned long)val; - } - - if (uval > UINT_MAX) { - PyErr_SetString(PyExc_OverflowError, - "Python int too large for C unsigned int"); + if (val < 0) { + PyErr_SetString(PyExc_ValueError, + "value must be positive"); return 0; } - *(unsigned int *)ptr = Py_SAFE_DOWNCAST(uval, unsigned long, unsigned int); + if ((size_t)val > UINT_MAX) { + *(unsigned int *)ptr = UINT_MAX; + } + else { + *(unsigned int *)ptr = Py_SAFE_DOWNCAST(val, Py_ssize_t, + unsigned int); + } return 1; } @@ -272,7 +272,7 @@ Compressed data. wbits: int(c_default="MAX_WBITS") = MAX_WBITS The window buffer size. - bufsize: uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE + bufsize: capped_uint(c_default="DEF_BUF_SIZE") = DEF_BUF_SIZE The initial output buffer size. / @@ -282,7 +282,7 @@ static PyObject * zlib_decompress_impl(PyModuleDef *module, Py_buffer *data, int wbits, unsigned int bufsize) -/*[clinic end generated code: output=444d0987f3429574 input=0f4b9abb7103f50e]*/ +/*[clinic end generated code: output=444d0987f3429574 input=da095118b3243b27]*/ { PyObject *result_str = NULL; Byte *input; @@ -691,7 +691,7 @@ data: Py_buffer The binary data to decompress. - max_length: uint = 0 + max_length: capped_uint = 0 The maximum allowable length of the decompressed data. Unconsumed input data will be stored in the unconsumed_tail attribute. @@ -707,7 +707,7 @@ static PyObject * zlib_Decompress_decompress_impl(compobject *self, Py_buffer *data, unsigned int max_length) -/*[clinic end generated code: output=b82e2a2c19f5fe7b input=02cfc047377cec86]*/ +/*[clinic end generated code: output=b82e2a2c19f5fe7b input=68b6508ab07c2cf0]*/ { int err; unsigned int old_length, length = DEF_BUF_SIZE; @@ -1048,7 +1048,7 @@ /*[clinic input] zlib.Decompress.flush - length: uint(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE + length: capped_uint(c_default="DEF_BUF_SIZE") = zlib.DEF_BUF_SIZE the initial size of the output buffer. / @@ -1057,7 +1057,7 @@ static PyObject * zlib_Decompress_flush_impl(compobject *self, unsigned int length) -/*[clinic end generated code: output=db6fb753ab698e22 input=1580956505978993]*/ +/*[clinic end generated code: output=db6fb753ab698e22 input=1bb961eb21b62aa0]*/ { int err; unsigned int new_length; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 05:59:47 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 10:59:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325626=3A_Add_news?= =?utf-8?q?_to_3=2E6_section?= Message-ID: <20151121105947.127572.93917@psf.io> https://hg.python.org/cpython/rev/5117f0b3be09 changeset: 99259:5117f0b3be09 user: Martin Panter date: Sat Nov 21 10:57:47 2015 +0000 summary: Issue #25626: Add news to 3.6 section files: Misc/NEWS | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,13 @@ Library ------- +- Issue #25626: Change three zlib functions to accept sizes that fit in + Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a + regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 + or 4 GiB. The change affects the zlib.Decompress.decompress() max_length + parameter, the zlib.decompress() bufsize parameter, and the + zlib.Decompress.flush() length parameter. + - Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS gives priority to errors such as EACCES over EEXIST. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 07:12:20 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 21 Nov 2015 12:12:20 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325686=3A_test=5Fshutil_no_longer_uses_the_distu?= =?utf-8?q?tils_package_for_searching?= Message-ID: <20151121121220.3548.90454@psf.io> https://hg.python.org/cpython/rev/3ccd9dfb8ab7 changeset: 99262:3ccd9dfb8ab7 parent: 99259:5117f0b3be09 parent: 99261:df11d58fce00 user: Serhiy Storchaka date: Sat Nov 21 14:10:30 2015 +0200 summary: Issue #25686: test_shutil no longer uses the distutils package for searching and running external archivers. files: Lib/test/test_shutil.py | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -12,8 +12,6 @@ import functools import subprocess from contextlib import ExitStack -from os.path import splitdrive -from distutils.spawn import find_executable, spawn from shutil import (make_archive, register_archive_format, unregister_archive_format, get_archive_formats, Error, unpack_archive, @@ -51,7 +49,7 @@ import zipfile ZIP_SUPPORT = True except ImportError: - ZIP_SUPPORT = find_executable('zip') + ZIP_SUPPORT = shutil.which('zip') def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. @@ -1023,7 +1021,7 @@ return root_dir, base_dir @requires_zlib - @unittest.skipUnless(find_executable('tar'), + @unittest.skipUnless(shutil.which('tar'), 'Need the tar command to run') def test_tarfile_vs_tar(self): root_dir, base_dir = self._create_files() @@ -1037,8 +1035,8 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir): - spawn(tar_cmd) + subprocess.check_call(tar_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(tarball2)) # let's compare both tarballs @@ -1082,7 +1080,7 @@ @requires_zlib @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') - @unittest.skipUnless(find_executable('zip'), + @unittest.skipUnless(shutil.which('zip'), 'Need the zip command to run') def test_zipfile_vs_zip(self): root_dir, base_dir = self._create_files() @@ -1096,8 +1094,8 @@ # now create another ZIP file using `zip` archive2 = os.path.join(root_dir, 'archive2.zip') zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir] - with support.change_cwd(root_dir): - spawn(zip_cmd) + subprocess.check_call(zip_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(archive2)) # let's compare both ZIP files -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 07:12:20 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 21 Nov 2015 12:12:20 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Njg2?= =?utf-8?q?=3A_test=5Fshutil_no_longer_uses_the_distutils_package_for_runn?= =?utf-8?q?ing?= Message-ID: <20151121121220.22159.88114@psf.io> https://hg.python.org/cpython/rev/81b4b130a891 changeset: 99263:81b4b130a891 branch: 2.7 parent: 99253:427ad0ede016 user: Serhiy Storchaka date: Sat Nov 21 14:11:57 2015 +0200 summary: Issue #25686: test_shutil no longer uses the distutils package for running external archivers. files: Lib/test/test_shutil.py | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -8,8 +8,8 @@ import os import os.path import errno -from os.path import splitdrive -from distutils.spawn import find_executable, spawn +import subprocess +from distutils.spawn import find_executable from shutil import (make_archive, register_archive_format, unregister_archive_format, get_archive_formats) @@ -443,8 +443,7 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir): - spawn(tar_cmd) + subprocess.check_call(tar_cmd, cwd=root_dir) self.assertTrue(os.path.isfile(tarball2)) # let's compare both tarballs @@ -502,8 +501,7 @@ # now create another ZIP file using `zip` archive2 = os.path.join(root_dir, 'archive2.zip') zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir] - with support.change_cwd(root_dir): - spawn(zip_cmd) + subprocess.check_call(zip_cmd, cwd=root_dir) self.assertTrue(os.path.isfile(archive2)) # let's compare both ZIP files -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 07:12:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 21 Nov 2015 12:12:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Njg2?= =?utf-8?q?=3A_test=5Fshutil_no_longer_uses_the_distutils_package_for_sear?= =?utf-8?q?ching?= Message-ID: <20151121121220.71405.70107@psf.io> https://hg.python.org/cpython/rev/c50cbb5d5ece changeset: 99260:c50cbb5d5ece branch: 3.4 parent: 99254:4eae64a9cd26 user: Serhiy Storchaka date: Sat Nov 21 14:09:26 2015 +0200 summary: Issue #25686: test_shutil no longer uses the distutils package for searching and running external archivers. files: Lib/test/test_shutil.py | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -12,8 +12,6 @@ import functools import subprocess from contextlib import ExitStack -from os.path import splitdrive -from distutils.spawn import find_executable, spawn from shutil import (make_archive, register_archive_format, unregister_archive_format, get_archive_formats, Error, unpack_archive, @@ -45,7 +43,7 @@ import zipfile ZIP_SUPPORT = True except ImportError: - ZIP_SUPPORT = find_executable('zip') + ZIP_SUPPORT = shutil.which('zip') def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. @@ -1017,7 +1015,7 @@ return root_dir, base_dir @requires_zlib - @unittest.skipUnless(find_executable('tar'), + @unittest.skipUnless(shutil.which('tar'), 'Need the tar command to run') def test_tarfile_vs_tar(self): root_dir, base_dir = self._create_files() @@ -1031,8 +1029,8 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir): - spawn(tar_cmd) + subprocess.check_call(tar_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(tarball2)) # let's compare both tarballs @@ -1076,7 +1074,7 @@ @requires_zlib @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') - @unittest.skipUnless(find_executable('zip'), + @unittest.skipUnless(shutil.which('zip'), 'Need the zip command to run') def test_zipfile_vs_zip(self): root_dir, base_dir = self._create_files() @@ -1090,8 +1088,8 @@ # now create another ZIP file using `zip` archive2 = os.path.join(root_dir, 'archive2.zip') zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir] - with support.change_cwd(root_dir): - spawn(zip_cmd) + subprocess.check_call(zip_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(archive2)) # let's compare both ZIP files -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 07:12:30 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sat, 21 Nov 2015 12:12:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325686=3A_test=5Fshutil_no_longer_uses_the_distutils_p?= =?utf-8?q?ackage_for_searching?= Message-ID: <20151121121220.130847.89607@psf.io> https://hg.python.org/cpython/rev/df11d58fce00 changeset: 99261:df11d58fce00 branch: 3.5 parent: 99257:80f6f77a7cc3 parent: 99260:c50cbb5d5ece user: Serhiy Storchaka date: Sat Nov 21 14:09:58 2015 +0200 summary: Issue #25686: test_shutil no longer uses the distutils package for searching and running external archivers. files: Lib/test/test_shutil.py | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -12,8 +12,6 @@ import functools import subprocess from contextlib import ExitStack -from os.path import splitdrive -from distutils.spawn import find_executable, spawn from shutil import (make_archive, register_archive_format, unregister_archive_format, get_archive_formats, Error, unpack_archive, @@ -51,7 +49,7 @@ import zipfile ZIP_SUPPORT = True except ImportError: - ZIP_SUPPORT = find_executable('zip') + ZIP_SUPPORT = shutil.which('zip') def _fake_rename(*args, **kwargs): # Pretend the destination path is on a different filesystem. @@ -1023,7 +1021,7 @@ return root_dir, base_dir @requires_zlib - @unittest.skipUnless(find_executable('tar'), + @unittest.skipUnless(shutil.which('tar'), 'Need the tar command to run') def test_tarfile_vs_tar(self): root_dir, base_dir = self._create_files() @@ -1037,8 +1035,8 @@ # now create another tarball using `tar` tarball2 = os.path.join(root_dir, 'archive2.tar') tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir] - with support.change_cwd(root_dir): - spawn(tar_cmd) + subprocess.check_call(tar_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(tarball2)) # let's compare both tarballs @@ -1082,7 +1080,7 @@ @requires_zlib @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') - @unittest.skipUnless(find_executable('zip'), + @unittest.skipUnless(shutil.which('zip'), 'Need the zip command to run') def test_zipfile_vs_zip(self): root_dir, base_dir = self._create_files() @@ -1096,8 +1094,8 @@ # now create another ZIP file using `zip` archive2 = os.path.join(root_dir, 'archive2.zip') zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir] - with support.change_cwd(root_dir): - spawn(zip_cmd) + subprocess.check_call(zip_cmd, cwd=root_dir, + stdout=subprocess.DEVNULL) self.assertTrue(os.path.isfile(archive2)) # let's compare both ZIP files -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:20:50 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:20:50 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Misc/NEWS_entr?= =?utf-8?q?ies_for_IDLE=2E?= Message-ID: <20151121182049.20252.30041@psf.io> https://hg.python.org/cpython/rev/569818249be3 changeset: 99264:569818249be3 branch: 2.7 user: Terry Jan Reedy date: Sat Nov 21 13:18:50 2015 -0500 summary: Misc/NEWS entries for IDLE. files: Misc/NEWS | 51 +++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -230,27 +230,53 @@ IDLE ---- +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -296,9 +322,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). - Issue #23672: Allow Idle to edit and run files with astral chars in name. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:20:50 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:20:50 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Misc/NEWS_entries_for_IDLE=2E?= Message-ID: <20151121182050.38217.92435@psf.io> https://hg.python.org/cpython/rev/3d0691401f43 changeset: 99266:3d0691401f43 branch: 3.5 parent: 99261:df11d58fce00 parent: 99265:1a02f7176721 user: Terry Jan Reedy date: Sat Nov 21 13:20:09 2015 -0500 summary: Misc/NEWS entries for IDLE. files: Misc/NEWS | 51 +++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -307,27 +307,53 @@ IDLE ---- +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -373,9 +399,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). Documentation -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:20:50 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:20:50 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Misc/NEWS_entr?= =?utf-8?q?ies_for_IDLE=2E?= Message-ID: <20151121182050.130861.56675@psf.io> https://hg.python.org/cpython/rev/1a02f7176721 changeset: 99265:1a02f7176721 branch: 3.4 parent: 99260:c50cbb5d5ece user: Terry Jan Reedy date: Sat Nov 21 13:19:03 2015 -0500 summary: Misc/NEWS entries for IDLE. files: Misc/NEWS | 51 +++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -562,27 +562,53 @@ IDLE ---- +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -628,9 +654,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). - Issue #23672: Allow Idle to edit and run files with astral chars in name. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:20:51 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:20:51 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_with_3=2E5?= Message-ID: <20151121182050.127582.66083@psf.io> https://hg.python.org/cpython/rev/29a6b11c61f8 changeset: 99267:29a6b11c61f8 parent: 99262:3ccd9dfb8ab7 parent: 99266:3d0691401f43 user: Terry Jan Reedy date: Sat Nov 21 13:20:26 2015 -0500 summary: Merge with 3.5 files: Misc/NEWS | 51 +++++++++++++++++++++++++++++++----------- 1 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -294,27 +294,53 @@ IDLE ---- +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -360,9 +386,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). Documentation -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:34:26 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:34:26 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Update_idlelib/NEWS=2Etxt=2E?= Message-ID: <20151121183426.130859.97858@psf.io> https://hg.python.org/cpython/rev/a70281b5d076 changeset: 99270:a70281b5d076 branch: 3.5 parent: 99266:3d0691401f43 parent: 99269:5f9c7162c04d user: Terry Jan Reedy date: Sat Nov 21 13:33:06 2015 -0500 summary: Update idlelib/NEWS.txt. files: Lib/idlelib/NEWS.txt | 55 ++++++++++++++++++++++--------- 1 files changed, 39 insertions(+), 16 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,28 +1,54 @@ What's New in IDLE 3.5.1? ========================= -*Release date: 2015-09-13* +*Release date: 2015-12-06* + +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -42,7 +68,7 @@ * Give code snippet a very Sphinx-like light blueish-gray background. * Re-use initial width and height set by users for shell and editor. * When the Table of Contents (TOC) menu is used, put the section header - at the top of the screen. + at the top of the screen. - Issue #25225: Condense and rewrite Idle doc section on text colors. @@ -68,9 +94,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:34:26 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:34:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Update_idlelib?= =?utf-8?q?/NEWS=2Etxt=2E?= Message-ID: <20151121183426.20254.32724@psf.io> https://hg.python.org/cpython/rev/4d86c1e53ff4 changeset: 99268:4d86c1e53ff4 branch: 2.7 parent: 99264:569818249be3 user: Terry Jan Reedy date: Sat Nov 21 13:31:00 2015 -0500 summary: Update idlelib/NEWS.txt. files: Lib/idlelib/NEWS.txt | 57 ++++++++++++++++++++++--------- 1 files changed, 40 insertions(+), 17 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,28 +1,54 @@ What's New in IDLE 2.7.11? -========================= -*Release date: +========================== +*Release date: 2015-12-06* + +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -42,7 +68,7 @@ * Give code snippet a very Sphinx-like light blueish-gray background. * Re-use initial width and height set by users for shell and editor. * When the Table of Contents (TOC) menu is used, put the section header - at the top of the screen. + at the top of the screen. - Issue #25225: Condense and rewrite Idle doc section on text colors. @@ -68,9 +94,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). - Issue #23672: Allow Idle to edit and run files with astral chars in name. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:34:26 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:34:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Update_idlelib?= =?utf-8?q?/NEWS=2Etxt=2E?= Message-ID: <20151121183426.3548.94137@psf.io> https://hg.python.org/cpython/rev/5f9c7162c04d changeset: 99269:5f9c7162c04d branch: 3.4 parent: 99265:1a02f7176721 user: Terry Jan Reedy date: Sat Nov 21 13:31:27 2015 -0500 summary: Update idlelib/NEWS.txt. files: Lib/idlelib/NEWS.txt | 55 ++++++++++++++++++++++--------- 1 files changed, 39 insertions(+), 16 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -1,28 +1,54 @@ What's New in Idle 3.4.4? ========================= -*Release date: 2015-??-??* +*Release date: 2015-12-20* + +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -42,7 +68,7 @@ * Give code snippet a very Sphinx-like light blueish-gray background. * Re-use initial width and height set by users for shell and editor. * When the Table of Contents (TOC) menu is used, put the section header - at the top of the screen. + at the top of the screen. - Issue #25225: Condense and rewrite Idle doc section on text colors. @@ -68,9 +94,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). - Issue #23672: Allow Idle to edit and run files with astral chars in name. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 13:34:26 2015 From: python-checkins at python.org (terry.reedy) Date: Sat, 21 Nov 2015 18:34:26 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Update_idlelib/NEWS=2Etxt=2E?= Message-ID: <20151121183426.127554.62146@psf.io> https://hg.python.org/cpython/rev/2e1a9e327859 changeset: 99271:2e1a9e327859 parent: 99267:29a6b11c61f8 parent: 99270:a70281b5d076 user: Terry Jan Reedy date: Sat Nov 21 13:33:57 2015 -0500 summary: Update idlelib/NEWS.txt. files: Lib/idlelib/NEWS.txt | 53 ++++++++++++++++++++++--------- 1 files changed, 38 insertions(+), 15 deletions(-) diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -2,27 +2,53 @@ =========================== *Release date: 2017?* +- Issue 15348: Stop the debugger engine (normally in a user process) + before closing the debugger window (running in the IDLE process). + This prevents the RuntimeErrors that were being caught and ignored. + +- Issue #24455: Prevent IDLE from hanging when a) closing the shell while the + debugger is active (15347); b) closing the debugger with the [X] button + (15348); and c) activating the debugger when already active (24455). + The patch by Mark Roseman does this by making two changes. + 1. Suspend and resume the gui.interaction method with the tcl vwait + mechanism intended for this purpose (instead of root.mainloop & .quit). + 2. In gui.run, allow any existing interaction to terminate first. + +- Change 'The program' to 'Your program' in an IDLE 'kill program?' message + to make it clearer that the program referred to is the currently running + user program, not IDLE itself. + +- Issue #24750: Improve the appearance of the IDLE editor window status bar. + Patch by Mark Roseman. + +- Issue #25313: Change the handling of new built-in text color themes to better + address the compatibility problem introduced by the addition of IDLE Dark. + Consistently use the revised idleConf.CurrentTheme everywhere in idlelib. + +- Issue #24782: Extension configuration is now a tab in the IDLE Preferences + dialog rather than a separate dialog. The former tabs are now a sorted + list. Patch by Mark Roseman. + +- Issue #22726: Re-activate the config dialog help button with some content + about the other buttons and the new IDLE Dark theme. + - Issue #24820: IDLE now has an 'IDLE Dark' built-in text color theme. It is more or less IDLE Classic inverted, with a cobalt blue background. Strings, comments, keywords, ... are still green, red, orange, ... . - Selecting it displays the following warning and solution. - "IDLE Dark is new in October, 2015. Trying to run earlier versions - of IDLE with it selected will disable colorizing, or worse. - If you might ever run an earlier release of IDLE, then before - exiting this version, either switch to another theme or hit the - 'Save as New Custom Theme' button. The latter requires a new name, - such as 'Custom Dark', but the custom theme will work with any IDLE - release, and can be modified." + To use it with IDLEs released before November 2015, hit the + 'Save as New Custom Theme' button and enter a new name, + such as 'Custom Dark'. The custom theme will work with any IDLE + release, and can be modified. - Issue #25224: README.txt is now an idlelib index for IDLE developers and - curious users. The previous user content is now in the IDLE doc and is - redundant. IDLE now means 'Integrated Development and Learning Environment'. + curious users. The previous user content is now in the IDLE doc chapter. + 'IDLE' now means 'Integrated Development and Learning Environment'. - Issue #24820: Users can now set breakpoint colors in Settings -> Custom Highlighting. Original patch by Mark Roseman. - Issue #24972: Inactive selection background now matches active selection - background, as configured by user, on all systems. Found items are now + background, as configured by users, on all systems. Found items are now always highlighted on Windows. Initial patch by Mark Roseman. - Issue #24570: Idle: make calltip and completion boxes appear on Macs @@ -42,7 +68,7 @@ * Give code snippet a very Sphinx-like light blueish-gray background. * Re-use initial width and height set by users for shell and editor. * When the Table of Contents (TOC) menu is used, put the section header - at the top of the screen. + at the top of the screen. - Issue #25225: Condense and rewrite Idle doc section on text colors. @@ -68,9 +94,6 @@ - Issue #24199: Deprecate unused idlelib.idlever with possible removal in 3.6. -- Issue #24782: In Idle extension config dialog, replace tabs with sorted list. - Patch by Mark Roseman. - - Issue #24790: Remove extraneous code (which also create 2 & 3 conflicts). -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 16:37:24 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2015 21:37:24 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_update_pydoc-t?= =?utf-8?q?opics?= Message-ID: <20151121213723.3536.77802@psf.io> https://hg.python.org/cpython/rev/ce7c607fb6bf changeset: 99272:ce7c607fb6bf branch: 2.7 parent: 99268:4d86c1e53ff4 user: Benjamin Peterson date: Sat Nov 21 13:35:41 2015 -0800 summary: update pydoc-topics files: Lib/pydoc_data/topics.py | 13395 ++++++++++++++++++++++++- 1 files changed, 13316 insertions(+), 79 deletions(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,80 +1,13317 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Sun May 10 13:12:18 2015 -topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names. In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O). The current code generator emits no code for an\nassert statement when optimization is requested at compile time. Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', - 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n\n(See section Primaries for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section The standard type\nhierarchy).\n\nAssignment of an object to a target list is recursively defined as\nfollows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The\n object must be an iterable with the same number of items as there\n are targets in the target list, and the items are assigned, from\n left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a "global" statement in the\n current code block: the name is bound to the object in the current\n local namespace.\n\n * Otherwise: the name is bound to the object in the current global\n namespace.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in\n square brackets: The object must be an iterable with the same number\n of items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, "TypeError" is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily "AttributeError").\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n "a.x" can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target "a.x" is always\n set as an instance attribute, creating it if necessary. Thus, the\n two occurrences of "a.x" do not necessarily refer to the same\n attribute: if the RHS expression refers to a class attribute, the\n LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield a plain integer. If it is negative, the\n sequence\'s length is added to it. The resulting value must be a\n nonnegative integer less than the sequence\'s length, and the\n sequence is asked to assign the assigned object to its item with\n that index. If the index is out of range, "IndexError" is raised\n (assignment to a subscripted sequence cannot add new items to a\n list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n* If the target is a slicing: The primary expression in the\n reference is evaluated. It should yield a mutable sequence object\n (such as a list). The assigned object should be a sequence object\n of the same type. Next, the lower and upper bound expressions are\n evaluated, insofar they are present; defaults are zero and the\n sequence\'s length. The bounds should evaluate to (small) integers.\n If either bound is negative, the sequence\'s length is added to it.\n The resulting bounds are clipped to lie between zero and the\n sequence\'s length, inclusive. Finally, the sequence object is asked\n to replace the slice with the items of the assigned sequence. The\n length of the slice may be different from the length of the assigned\n sequence, thus changing the length of the target sequence, if the\n object allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints "[0, 2]":\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print x\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section Primaries for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same caveat about\nclass and instance attributes applies as for regular assignments.\n', - 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section Identifiers\nand keywords for lexical definition and section Naming and binding for\ndocumentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a "NameError" exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier "__spam"\noccurring in a class named "Ham" will be transformed to "_Ham__spam".\nThis transformation is independent of the syntactical context in which\nthe identifier is used. If the transformed name is extremely long\n(longer than 255 characters), implementation defined truncation may\nhappen. If the class name consists only of underscores, no\ntransformation is done.\n', - 'atom-literals': u"\nLiterals\n********\n\nPython supports string literals and various numeric literals:\n\n literal ::= stringliteral | integer | longinteger\n | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\ninteger, long integer, floating point number, complex number) with the\ngiven value. The value may be approximated in the case of floating\npoint and imaginary (complex) literals. See section Literals for\ndetails.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", - 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should not simply execute "self.name = value" --- this would cause\n a recursive call to itself. Instead, it should insert the value in\n the dictionary of instance attributes, e.g., "self.__dict__[name] =\n value". For new-style classes, rather than accessing the instance\n dictionary, it should call the base class method with the same\n name, for example, "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n===========================================\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See Special method lookup for new-style\n classes.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass "object()" or "type()").\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to a new-style object instance, "a.x" is transformed\n into the call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a new-style class, "A.x" is transformed into the\n call: "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding "\'__dict__\'" to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding "\'__weakref__\'" to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (Implementing Descriptors) for each variable name. As a\n result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "long", "str" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n', - 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, e.g., a module, list, or an instance. This\nobject is then asked to produce the attribute whose name is the\nidentifier. If this attribute is not available, the exception\n"AttributeError" is raised. Otherwise, the type and value of the\nobject produced is determined by the object. Multiple evaluations of\nthe same attribute reference may yield different objects.\n', - 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section Primaries for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same caveat about\nclass and instance attributes applies as for regular assignments.\n', - 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | m_expr "/" u_expr\n | m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe "*" (multiplication) operator yields the product of its arguments.\nThe arguments must either both be numbers, or one argument must be an\ninteger (plain or long) and the other must be a sequence. In the\nformer case, the numbers are converted to a common type and then\nmultiplied together. In the latter case, sequence repetition is\nperformed; a negative repetition factor yields an empty sequence.\n\nThe "/" (division) and "//" (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Plain or long integer division yields an\ninteger of the same type; the result is that of mathematical division\nwith the \'floor\' function applied to the result. Division by zero\nraises the "ZeroDivisionError" exception.\n\nThe "%" (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n"ZeroDivisionError" exception. The arguments may be floating point\nnumbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +\n0.34".) The modulo operator always yields a result with the same sign\nas its second operand (or zero); the absolute value of the result is\nstrictly smaller than the absolute value of the second operand [2].\n\nThe integer division and modulo operators are connected by the\nfollowing identity: "x == (x/y)*y + (x%y)". Integer division and\nmodulo are also connected with the built-in function "divmod()":\n"divmod(x, y) == (x/y, x%y)". These identities don\'t hold for\nfloating point numbers; there similar identities hold approximately\nwhere "x/y" is replaced by "floor(x/y)" or "floor(x/y) - 1" [3].\n\nIn addition to performing the modulo operation on numbers, the "%"\noperator is also overloaded by string and unicode objects to perform\nstring formatting (also known as interpolation). The syntax for string\nformatting is described in the Python Library Reference, section\nString Formatting Operations.\n\nDeprecated since version 2.3: The floor division operator, the modulo\noperator, and the "divmod()" function are no longer defined for\ncomplex numbers. Instead, convert to a floating point number using\nthe "abs()" function if appropriate.\n\nThe "+" (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe "-" (subtraction) operator yields the difference of its arguments.\nThe numeric arguments are first converted to a common type.\n', - 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe "&" operator yields the bitwise AND of its arguments, which must\nbe plain or long integers. The arguments are converted to a common\ntype.\n\nThe "^" operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be plain or long integers. The arguments are\nconverted to a common type.\n\nThe "|" operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be plain or long integers. The arguments are converted to\na common type.\n', - 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin "compile()" function and can be extracted from function objects\nthrough their "func_code" attribute. See also the "code" module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the "exec" statement or the built-in "eval()"\nfunction.\n\nSee The standard type hierarchy for more information.\n', - 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is used by extended slice notation (see Slicings). It\nsupports no special operations. There is exactly one ellipsis object,\nnamed "Ellipsis" (a built-in name).\n\nIt is written as "Ellipsis". When in a subscript, it can also be\nwritten as "...", for example "seq[...]".\n', - 'bltin-null-object': u'\nThe Null Object\n***************\n\nThis object is returned by functions that don\'t explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named "None" (a built-in name).\n\nIt is written as "None".\n', - 'bltin-type-objects': u'\nType Objects\n************\n\nType objects represent the various object types. An object\'s type is\naccessed by the built-in function "type()". There are no special\noperations on types. The standard module "types" defines names for\nall standard built-in types.\n\nTypes are written like this: "".\n', - 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: "False", "None", numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. (See the "__nonzero__()" special method for a way to change\nthis.)\n\nThe operator "not" yields "True" if its argument is false, "False"\notherwise.\n\nThe expression "x and y" first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression "x or y" first evaluates *x*; if *x* is true, its value\nis returned; otherwise, *y* is evaluated and the resulting value is\nreturned.\n\n(Note that neither "and" nor "or" restrict the value and type they\nreturn to "False" and "True", but rather return the last evaluated\nargument. This is sometimes useful, e.g., if "s" is a string that\nshould be replaced by a default value if it is empty, the expression\n"s or \'foo\'" yields the desired value. Because "not" has to invent a\nvalue anyway, it does not bother to return a value of the same type as\nits argument, so e.g., "not \'foo\'" yields "False", not "\'\'".)\n', - 'break': u'\nThe "break" statement\n*********************\n\n break_stmt ::= "break"\n\n"break" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition within that\nloop.\n\nIt terminates the nearest enclosing loop, skipping the optional "else"\nclause if the loop has one.\n\nIf a "for" loop is terminated by "break", the loop control target\nkeeps its current value.\n\nWhen "break" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nloop.\n', - 'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n', - 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","]\n | expression genexpr_for] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and certain class instances\nthemselves are callable; extensions may define additional callable\nobject types). All argument expressions are evaluated before the call\nis attempted. Please refer to section Function definitions for the\nsyntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised. Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an iterable. Elements from this iterable are treated\nas if they were additional positional arguments; if there are\npositional arguments *x1*, ..., *xN*, and "expression" evaluates to a\nsequence *y1*, ..., *yM*, this is equivalent to a call with M+N\npositional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the "**expression" argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print a, b\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both "expression" and as an explicit keyword argument, a\n"TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames. Formal parameters using the syntax "(sublist)" cannot be used\nas keyword argument names; the outermost sublist corresponds to a\nsingle unnamed argument slot, and the argument value is assigned to\nthe sublist using the usual tuple assignment rules after all other\nparameter processing is done.\n\nA call always returns some value, possibly "None", unless it raises an\nexception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n Function definitions. When the code block executes a "return"\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see Built-in Functions for the\n descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a "__call__()" method; the effect is then the\n same as if that method was called.\n', - 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section The standard\ntype hierarchy):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section Naming and binding), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with "self.name = value". Both\nclass and instance variables are accessible through the notation\n""self.name"", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', - 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe forms "<>" and "!=" are equivalent; for consistency with C, "!="\nis preferred; where "!=" is mentioned below "<>" is also accepted.\nThe "<>" spelling is considered obsolescent.\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, objects of\ndifferent types *always* compare unequal, and are ordered consistently\nbut arbitrarily. You can control comparison behavior of objects of\nnon-built-in types by defining a "__cmp__" method or rich comparison\nmethods like "__gt__", described in section Special method names.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the "in" and "not in"\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. Unicode and 8-bit strings are fully interoperable in\n this behavior. [4]\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "cmp([1,2,x], [1,2,y])" returns\n the same as "cmp(x,y)". If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, "[1,2] <\n [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nThe operators "in" and "not in" test for collection membership. "x in\ns" evaluates to true if *x* is a member of the collection *s*, and\nfalse otherwise. "x not in s" returns the negation of "x in s". The\ncollection membership test has traditionally been bound to sequences;\nan object is a member of a collection if the collection is a sequence\nand contains an element equal to that object. However, it make sense\nfor many other object types to support membership tests without being\na sequence. In particular, dictionaries (for keys) and sets support\nmembership testing.\n\nFor the list and tuple types, "x in y" is true if and only if there\nexists an index *i* such that "x == y[i]" is true.\n\nFor the Unicode and string types, "x in y" is true if and only if *x*\nis a substring of *y*. An equivalent test is "y.find(x) != -1".\nNote, *x* and *y* need not be the same type; consequently, "u\'ab\' in\n\'abc\'" will return "True". Empty strings are always considered to be a\nsubstring of any other string, so """ in "abc"" will return "True".\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength "1".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [7]\n', - 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs. "try" specifies exception handlers and/or cleanup\ncode for a group of statements. Function and class definitions are\nalso syntactically compound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n if test1: if test2: print x\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print" statements are executed:\n\n if x < y < z: print x; print y; print z\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | decorated\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT". Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section Boolean operations\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there was no next\nitem.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function "range()" returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s "for i := a to b\ndo"; e.g., "range(3)" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n"try"..."except"..."finally" did not work. "try"..."except" had to be\nnested in "try"..."finally".\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject, or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the "sys" module:\n"sys.exc_type" receives the object identifying the exception;\n"sys.exc_value" receives the exception\'s parameter;\n"sys.exc_traceback" receives a traceback object (see section The\nstandard type hierarchy) identifying the point in the program where\nthe exception occurred. These details are also available through the\n"sys.exc_info()" function, which returns a tuple "(exc_type,\nexc_value, exc_traceback)". Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception, it is re-raised at the end of the\n"finally" clause. If the "finally" clause raises another exception or\nexecutes a "return" or "break" statement, the saved exception is\ndiscarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\nExceptions, and information on using the "raise" statement to generate\nexceptions may be found in section The raise statement.\n\n\nThe "with" statement\n====================\n\nNew in version 2.5.\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section With Statement\nContext Managers). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the "with" statement is only allowed when the\n "with_statement" feature has been enabled. It is always enabled in\n Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection The standard type hierarchy):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier ["," "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that the same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use "None" as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section Calls.\nA function call always assigns values to all parameters mentioned in\nthe parameter list, either from position arguments, from keyword\narguments, or from default values. If the form ""*identifier"" is\npresent, it is initialized to a tuple receiving any excess positional\nparameters, defaulting to the empty tuple. If the form\n""**identifier"" is present, it is initialized to a new dictionary\nreceiving any excess keyword arguments, defaulting to a new empty\ndictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section Lambdas. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section Naming and binding for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section The standard\ntype hierarchy):\n\n classdef ::= "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section Naming and binding), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by all instances. To create instance\nvariables, they can be set in a method with "self.name = value". Both\nclass and instance variables are accessible through the notation\n""self.name"", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. For *new-style class*es, descriptors can\nbe used to create instance variables with different implementation\ndetails.\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', - 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section The with\nstatement), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see Context Manager Types.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', - 'continue': u'\nThe "continue" statement\n************************\n\n continue_stmt ::= "continue"\n\n"continue" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition or "finally"\nclause within that loop. It continues with the next cycle of the\nnearest enclosing loop.\n\nWhen "continue" passes control out of a "try" statement with a\n"finally" clause, that "finally" clause is executed before really\nstarting the next loop cycle.\n', - 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," the arguments\nare coerced using the coercion rules listed at Coercion rules. If\nboth arguments are standard numeric types, the following coercions are\napplied:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the\n other is converted to floating point;\n\n* otherwise, if either argument is a long integer, the other is\n converted to long integer;\n\n* otherwise, both must be plain integers and no conversion is\n necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions can define their own\ncoercions.\n', - 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_traceback" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing "None" in\n "sys.exc_traceback" or "sys.last_traceback". Circular references\n which are garbage are detected when the option cycle detector is\n enabled (it\'s on by default), but can only be cleaned up if there\n are no Python-level "__del__()" methods involved. Refer to the\n documentation for the "gc" module for more information about how\n "__del__()" methods are handled by the cycle detector,\n particularly the description of the "garbage" value.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\n See also the "-R" command-line option.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function and by string conversions\n (reverse quotes) to compute the "official" string representation of\n an object. If at all possible, this should look like a valid\n Python expression that could be used to recreate an object with the\n same value (given an appropriate environment). If this is not\n possible, a string of the form "<...some useful description...>"\n should be returned. The return value must be a string object. If a\n class defines "__repr__()" but not "__str__()", then "__repr__()"\n is also used when an "informal" string representation of instances\n of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the "str()" built-in function and by the "print"\n statement to compute the "informal" string representation of an\n object. This differs from "__repr__()" in that it does not have to\n be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to "__cmp__()" below. The\n correspondence between operator symbols and method names is as\n follows: "xy" call "x.__ne__(y)",\n "x>y" calls "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if "self < other",\n zero if "self == other", a positive integer if "self > other". If\n no "__cmp__()", "__eq__()" or "__ne__()" operation is defined,\n class instances are compared by object identity ("address"). See\n also the description of "__hash__()" for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by "__cmp__()" has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a "__cmp__()" or "__eq__()" method it\n should not define a "__hash__()" operation either; if it defines\n "__cmp__()" or "__eq__()" but not "__hash__()", its instances will\n not be usable in hashed collections. If a class defines mutable\n objects and implements a "__cmp__()" or "__eq__()" method, it\n should not implement "__hash__()", since hashable collection\n implementations require that a object\'s hash value is immutable (if\n the object\'s hash value changes, it will be in the wrong hash\n bucket).\n\n User-defined classes have "__cmp__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns a result derived from\n "id(x)".\n\n Classes which inherit a "__hash__()" method from a parent class but\n change the meaning of "__cmp__()" or "__eq__()" such that the hash\n value returned is no longer appropriate (e.g. by switching to a\n value-based concept of equality instead of the default identity\n based equality) can explicitly flag themselves as being unhashable\n by setting "__hash__ = None" in the class definition. Doing so\n means that not only will instances of the class raise an\n appropriate "TypeError" when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable)"\n (unlike classes which define their own "__hash__()" to explicitly\n raise "TypeError").\n\n Changed in version 2.5: "__hash__()" may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: "__hash__" may now be set to "None" to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True", or their integer\n equivalents "0" or "1". When this method is not defined,\n "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__nonzero__()", all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement "unicode()" built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n', - 'debugger': u'\n"pdb" --- The Python Debugger\n*****************************\n\n**Source code:** Lib/pdb.py\n\n======================================================================\n\nThe module "pdb" defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible --- it is actually defined as the class\n"Pdb". This is currently undocumented but easily understood by reading\nthe source. The extension interface uses the modules "bdb" and "cmd".\n\nThe debugger\'s prompt is "(Pdb)". Typical usage to run a program under\ncontrol of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\n"pdb.py" can also be invoked as a script to debug other scripts. For\nexample:\n\n python -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 2.4: Restarting post-mortem behavior added.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the "c" command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print spam\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print spam\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement[, globals[, locals]])\n\n Execute the *statement* (given as a string) under debugger control.\n The debugger prompt appears before any code is executed; you can\n set breakpoints and type "continue", or you can step through the\n statement using "step" or "next" (all these commands are explained\n below). The optional *globals* and *locals* arguments specify the\n environment in which the code is executed; by default the\n dictionary of the module "__main__" is used. (See the explanation\n of the "exec" statement or the "eval()" built-in function.)\n\npdb.runeval(expression[, globals[, locals]])\n\n Evaluate the *expression* (given as a string) under debugger\n control. When "runeval()" returns, it returns the value of the\n expression. Otherwise this function is similar to "run()".\n\npdb.runcall(function[, argument, ...])\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When "runcall()" returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem([traceback])\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n "sys.last_traceback".\n\nThe "run*" functions and "set_trace()" are aliases for instantiating\nthe "Pdb" class and calling the method of the same name. If you want\nto access further features, you have to do this yourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None)\n\n "Pdb" is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying "cmd.Cmd" class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 2.7: The *skip* argument.\n\n run(statement[, globals[, locals]])\n runeval(expression[, globals[, locals]])\n runcall(function[, argument, ...])\n set_trace()\n\n See the documentation for the functions explained above.\n', - 'del': u'\nThe "del" statement\n*******************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a "global"\nstatement in the same code block. If the name is unbound, a\n"NameError" exception will be raised.\n\nIt is illegal to delete a name from the local namespace if it occurs\nas a free variable in a nested block.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n', - 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection The standard type hierarchy. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nIf "exec" is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n"SyntaxError" unless the exec explicitly specifies the local namespace\nfor the "exec". (In other words, "exec obj" would be illegal, but\n"exec obj in ns" would be legal.)\n\nThe "eval()", "execfile()", and "input()" functions and the "exec"\nstatement do not have access to the full environment for resolving\nnames. Names may be resolved in the local and global namespaces of\nthe caller. Free variables are not resolved in the nearest enclosing\nnamespace, but in the global namespace. [1] The "exec" statement and\nthe "eval()" and "execfile()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', - 'else': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section Boolean operations\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', - 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nExceptions can also be identified by strings, in which case the\n"except" clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section The try\nstatement and "raise" statement in section The raise statement.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', - 'exec': u'\nThe "exec" statement\n********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a Unicode string, a *Latin-1*\nencoded string, an open file object, a code object, or a tuple. If it\nis a string, the string is parsed as a suite of Python statements\nwhich is then executed (unless a syntax error occurs). [1] If it is an\nopen file, the file is parsed until EOF and executed. If it is a code\nobject, it is simply executed. For the interpretation of a tuple, see\nbelow. In all cases, the code that\'s executed is expected to be valid\nas file input (see section File input). Be aware that the "return"\nand "yield" statements may not be used outside of function definitions\neven within the context of code passed to the "exec" statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after "in" is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object. Remember that at module\nlevel, globals and locals are the same dictionary. If two separate\nobjects are given as *globals* and *locals*, the code will be executed\nas if it were embedded in a class definition.\n\nThe first expression may also be a tuple of length 2 or 3. In this\ncase, the optional parts must be omitted. The form "exec(expr,\nglobals)" is equivalent to "exec expr in globals", while the form\n"exec(expr, globals, locals)" is equivalent to "exec expr in globals,\nlocals". The tuple form of "exec" provides compatibility with Python\n3, where "exec" is a function rather than a statement.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module "__builtin__"\nunder the key "__builtins__" (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function "eval()". The built-in functions "globals()"\nand "locals()" return the current global and local dictionary,\nrespectively, which may be useful to pass around for use by "exec".\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use *universal newlines* mode to convert Windows or Mac-style\n newlines.\n', - 'execmodel': u'\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function "execfile()" is a code block. The string argument\npassed to the built-in function "eval()" and to the "exec" statement\nis a code block. The expression read and evaluated by the built-in\nfunction "input()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, a\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, in the\nsecond position of an "except" clause header or after "as" in a "with"\nstatement. The "import" statement of the form "from ... import *"\nbinds all names defined in the imported module, except those beginning\nwith an underscore. This form may only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a "SyntaxError".\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "__builtin__". The global namespace is searched first.\nIf the name is not found there, the builtins namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "__builtin__" (note: no\n\'s\'); when in any other module, "__builtins__" is an alias for the\ndictionary of the "__builtin__" module itself. "__builtins__" can be\nset to a user-created dictionary to create a weak form of restricted\nexecution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "__builtin__" (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nIf "exec" is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n"SyntaxError" unless the exec explicitly specifies the local namespace\nfor the "exec". (In other words, "exec obj" would be illegal, but\n"exec obj in ns" would be legal.)\n\nThe "eval()", "execfile()", and "input()" functions and the "exec"\nstatement do not have access to the full environment for resolving\nnames. Names may be resolved in the local and global namespaces of\nthe caller. Free variables are not resolved in the nearest enclosing\nnamespace, but in the global namespace. [1] The "exec" statement and\nthe "eval()" and "execfile()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nExceptions can also be identified by strings, in which case the\n"except" clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section The try\nstatement and "raise" statement in section The raise statement.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', - 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n', - 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, "077e010" is legal, and denotes the same number as "77e10".\nThe allowed range of floating point literals is implementation-\ndependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator "-" and the\nliteral "1".\n', - 'for': u'\nThe "for" statement\n*******************\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there was no next\nitem.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function "range()" returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s "for i := a to b\ndo"; e.g., "range(3)" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', - 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'". These specify a non-default format for the\nreplacement value.\n\nSee also the Format Specification Mini-Language section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself. However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting. By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nTwo conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, and "\'!r\'" which calls "repr()".\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the Format examples section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see Format String Syntax). They can also be passed directly to the\nbuilt-in "format()" function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use "{" and "}" as *fill*\nchar while using the "str.format()" method; this limitation however\ndoesn\'t affect the "format()" function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'<\'" | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | "\'>\'" | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | "\'=\'" | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | "\'^\'" | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'+\'" | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | "\'-\'" | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by "\'0b\'", "\'0o\'", or "\'0x\'", respectively.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 2.7: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero ("\'0\'") character enables sign-\naware zero-padding for numeric types. This is equivalent to a *fill*\ncharacter of "\'0\'" with an *alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'". For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'s\'" | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'s\'". |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'b\'" | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | "\'c\'" | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | "\'d\'" | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | "\'o\'" | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | "\'x\'" | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'X\'" | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'d\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'d\'". |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'e\'" | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'E\'" | Exponent notation. Same as "\'e\'" except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | "\'f\'" | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'F\'" | Fixed point. Same as "\'f\'". |\n +-----------+------------------------------------------------------------+\n | "\'g\'" | General format. For a given precision "p >= 1", this |\n | | rounds the number to "p" significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type "\'e\'" and precision "p-1" |\n | | would have exponent "exp". Then if "-4 <= exp < p", the |\n | | number is formatted with presentation type "\'f\'" and |\n | | precision "p-1-exp". Otherwise, the number is formatted |\n | | with presentation type "\'e\'" and precision "p-1". In both |\n | | cases insignificant trailing zeros are removed from the |\n | | significand, and the decimal point is also removed if |\n | | there are no remaining digits following it. Positive and |\n | | negative infinity, positive and negative zero, and nans, |\n | | are formatted as "inf", "-inf", "0", "-0" and "nan" |\n | | respectively, regardless of the precision. A precision of |\n | | "0" is treated as equivalent to a precision of "1". The |\n | | default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'G\'" | General format. Same as "\'g\'" except switches to "\'E\'" if |\n | | the number gets too large. The representations of infinity |\n | | and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'g\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | "\'%\'" | Percentage. Multiplies the number by 100 and displays in |\n | | fixed ("\'f\'") format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'g\'". |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing "%s" and "%r":\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', - 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection The standard type hierarchy):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier ["," "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters must also have a default value --- this is a syntactic\nrestriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that the same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use "None" as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section Calls.\nA function call always assigns values to all parameters mentioned in\nthe parameter list, either from position arguments, from keyword\narguments, or from default values. If the form ""*identifier"" is\npresent, it is initialized to a tuple receiving any excess positional\nparameters, defaulting to the empty tuple. If the form\n""**identifier"" is present, it is initialized to a new dictionary\nreceiving any excess keyword arguments, defaulting to a new empty\ndictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section Lambdas. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section Naming and binding for details.\n', - 'global': u'\nThe "global" statement\n**********************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe "global" statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without "global", although free variables may refer to\nglobals without being declared global.\n\nNames listed in a "global" statement must not be used in the same code\nblock textually preceding that "global" statement.\n\nNames listed in a "global" statement must not be defined as formal\nparameters or in a "for" loop control target, "class" definition,\nfunction definition, or "import" statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the "global" is a directive to the parser. It\napplies only to code parsed at the same time as the "global"\nstatement. In particular, a "global" statement contained in an "exec"\nstatement does not affect the code block *containing* the "exec"\nstatement, and code contained in an "exec" statement is unaffected by\n"global" statements in the code containing the "exec" statement. The\nsame applies to the "eval()", "execfile()" and "compile()" functions.\n', - 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "__builtin__" module. When\n not in interactive mode, "_" has no special meaning and is not\n defined. See section The import statement.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the Special method names section and\n elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section Identifiers (Names).\n', - 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions:\n\n identifier ::= (letter|"_") (letter | digit | "_")*\n letter ::= lowercase | uppercase\n lowercase ::= "a"..."z"\n uppercase ::= "A"..."Z"\n digit ::= "0"..."9"\n\nIdentifiers are unlimited in length. Case is significant.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n and del from not while\n as elif global or with\n assert else if pass yield\n break except import print\n class exec in raise\n continue finally is return\n def for lambda try\n\nChanged in version 2.4: "None" became a constant and is now recognized\nby the compiler as a name for the built-in object "None". Although it\nis not a keyword, you cannot assign a different object to it.\n\nChanged in version 2.5: Using "as" and "with" as identifiers triggers\na warning. To use them as keywords, enable the "with_statement"\nfuture feature .\n\nChanged in version 2.6: "as" and "with" are full keywords.\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "__builtin__" module. When\n not in interactive mode, "_" has no special meaning and is not\n defined. See section The import statement.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the Special method names section and\n elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section Identifiers (Names).\n', - 'if': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section Boolean operations\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', - 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., "(3+4j)". Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': u'\nThe "import" statement\n**********************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the "import" statement occurs). The\nstatement comes in two forms differing on whether it uses the "from"\nkeyword. The first form (without "from") repeats these steps for each\nidentifier in the list. The form with "from" performs step (1) once,\nand then performs step (2) repeatedly.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n"sys.modules", the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import.\n\nIf the module is not found in the cache, then "sys.meta_path" is\nsearched (the specification for "sys.meta_path" can be found in **PEP\n302**). The object is a list of *finder* objects which are queried in\norder as to whether they know how to load the module by calling their\n"find_module()" method with the name of the module. If the module\nhappens to be contained within a package (as denoted by the existence\nof a dot in the name), then a second argument to "find_module()" is\ngiven as the value of the "__path__" attribute from the parent package\n(everything up to the last dot in the name of the module being\nimported). If a finder can find the module it returns a *loader*\n(discussed later) or returns "None".\n\nIf none of the finders on "sys.meta_path" are able to find the module\nthen some implicitly defined finders are queried. Implementations of\nPython vary in what implicit meta path finders are defined. The one\nthey all do define, though, is one that handles "sys.path_hooks",\n"sys.path_importer_cache", and "sys.path".\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to "find_module()",\n"__path__" on the parent package, is used as the source of paths. If\nthe module is not contained in a package then "sys.path" is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n"sys.path_importer_cache" caches finders for paths and is checked for\na finder. If the path does not have a finder cached then\n"sys.path_hooks" is searched by calling each object in the list with a\nsingle argument of the path, returning a finder or raises\n"ImportError". If a finder is returned then it is cached in\n"sys.path_importer_cache" and then used for that path entry. If no\nfinder can be found but the path exists then a value of "None" is\nstored in "sys.path_importer_cache" to signify that an implicit, file-\nbased finder that handles modules stored as individual files should be\nused for that path. If the path does not exist then a finder which\nalways returns "None" is placed in the cache for the path.\n\nIf no finder can find the module then "ImportError" is raised.\nOtherwise some finder returned a loader whose "load_module()" method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin "sys.modules" (a possibility if the loader is called outside of the\nimport machinery) then it is to use that module for initialization and\nnot a new module. But if the module does not exist in "sys.modules"\nthen it is to be added to that dict before initialization begins. If\nan error occurs during loading of the module and it was added to\n"sys.modules" it is to be removed from the dict. If an error occurs\nbut the module was already in "sys.modules" it is left in the dict.\n\nThe loader must set several attributes on the module. "__name__" is to\nbe set to the name of the module. "__file__" is to be the "path" to\nthe file unless the module is built-in (and thus listed in\n"sys.builtin_module_names") in which case the attribute is not set. If\nwhat is being imported is a package then "__path__" is to be set to a\nlist of paths to be searched when looking for modules and packages\ncontained within the package being imported. "__package__" is optional\nbut should be set to the name of package that contains the module or\npackage (the empty string is used for module not contained in a\npackage). "__loader__" is also optional but should be set to the\nloader object that is loading the module.\n\nIf an error occurs during loading then the loader raises "ImportError"\nif some other exception is not already being propagated. Otherwise the\nloader returns the module that was loaded and initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of "import" statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by "as", the\nname following "as" is used as the local name for the module.\n\nThe "from" form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of "import", an alternate local name\ncan be supplied by specifying ""as" localname". If a name is not\nfound, "ImportError" is raised. If the list of identifiers is\nreplaced by a star ("\'*\'"), all public names defined in the module are\nbound in the local namespace of the "import" statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule. The names given in "__all__" are all considered public and\nare required to exist. If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'"). "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe "from" form with "*" may only occur in a module scope. If the\nwild card form of import --- "import *" --- is used in a function and\nthe function contains or is a nested block with free variables, the\ncompiler will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 2.6 are "unicode_literals",\n"print_function", "absolute_import", "division", "generators",\n"nested_scopes" and "with_statement". "generators", "with_statement",\n"nested_scopes" are redundant in Python version 2.6 and above because\nthey are always enabled.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by an "exec" statement or calls to the built-in\nfunctions "compile()" and "execfile()" that occur in a module "M"\ncontaining a future statement will, by default, use the new syntax or\nsemantics associated with the future statement. This can, starting\nwith Python 2.2 be controlled by optional arguments to "compile()" ---\nsee the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the "-i" option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n The original proposal for the __future__ mechanism.\n', - 'in': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\nThe forms "<>" and "!=" are equivalent; for consistency with C, "!="\nis preferred; where "!=" is mentioned below "<>" is also accepted.\nThe "<>" spelling is considered obsolescent.\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects need not have the same type. If both are\nnumbers, they are converted to a common type. Otherwise, objects of\ndifferent types *always* compare unequal, and are ordered consistently\nbut arbitrarily. You can control comparison behavior of objects of\nnon-built-in types by defining a "__cmp__" method or rich comparison\nmethods like "__gt__", described in section Special method names.\n\n(This unusual definition of comparison was used to simplify the\ndefinition of operations like sorting and the "in" and "not in"\noperators. In the future, the comparison rules for objects of\ndifferent types are likely to change.)\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* Strings are compared lexicographically using the numeric\n equivalents (the result of the built-in function "ord()") of their\n characters. Unicode and 8-bit strings are fully interoperable in\n this behavior. [4]\n\n* Tuples and lists are compared lexicographically using comparison\n of corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, "cmp([1,2,x], [1,2,y])" returns\n the same as "cmp(x,y)". If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, "[1,2] <\n [1,2,3]").\n\n* Mappings (dictionaries) compare equal if and only if their sorted\n (key, value) lists compare equal. [5] Outcomes other than equality\n are resolved consistently, but are not otherwise defined. [6]\n\n* Most other objects of built-in types compare unequal unless they\n are the same object; the choice whether one object is considered\n smaller or larger than another one is made arbitrarily but\n consistently within one execution of a program.\n\nThe operators "in" and "not in" test for collection membership. "x in\ns" evaluates to true if *x* is a member of the collection *s*, and\nfalse otherwise. "x not in s" returns the negation of "x in s". The\ncollection membership test has traditionally been bound to sequences;\nan object is a member of a collection if the collection is a sequence\nand contains an element equal to that object. However, it make sense\nfor many other object types to support membership tests without being\na sequence. In particular, dictionaries (for keys) and sets support\nmembership testing.\n\nFor the list and tuple types, "x in y" is true if and only if there\nexists an index *i* such that "x == y[i]" is true.\n\nFor the Unicode and string types, "x in y" is true if and only if *x*\nis a substring of *y*. An equivalent test is "y.find(x) != -1".\nNote, *x* and *y* need not be the same type; consequently, "u\'ab\' in\n\'abc\'" will return "True". Empty strings are always considered to be a\nsubstring of any other string, so """ in "abc"" will return "True".\n\nChanged in version 2.3: Previously, *x* was required to be a string of\nlength "1".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [7]\n', - 'integers': u'\nInteger and long integer literals\n*********************************\n\nInteger and long integer literals are described by the following\nlexical definitions:\n\n longinteger ::= integer ("l" | "L")\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"\n octinteger ::= "0" ("o" | "O") octdigit+ | "0" octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n nonzerodigit ::= "1"..."9"\n octdigit ::= "0"..."7"\n bindigit ::= "0" | "1"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n\nAlthough both lower case "\'l\'" and upper case "\'L\'" are allowed as\nsuffix for long integers, it is strongly recommended to always use\n"\'L\'", since the letter "\'l\'" looks too much like the digit "\'1\'".\n\nPlain integer literals that are above the largest representable plain\ninteger (e.g., 2147483647 when using 32-bit arithmetic) are accepted\nas if they were long integers instead. [1] There is no limit for long\ninteger literals apart from what can be stored in available memory.\n\nSome examples of plain integer literals (first row) and long integer\nliterals (second and third rows):\n\n 7 2147483647 0177\n 3L 79228162514264337593543950336L 0377L 0x100000000L\n 79228162514264337593543950336 0xdeadbeef\n', - 'lambda': u'\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n old_lambda_expr ::= "lambda" [parameter_list]: old_expression\n\nLambda expressions (sometimes called lambda forms) have the same\nsyntactic position as expressions. They are a shorthand to create\nanonymous functions; the expression "lambda arguments: expression"\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def name(arguments):\n return expression\n\nSee section Function definitions for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements.\n', - 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | list_comprehension] "]"\n list_comprehension ::= expression list_for\n list_for ::= "for" target_list "in" old_expression_list [list_iter]\n old_expression_list ::= old_expression [("," old_expression)+ [","]]\n old_expression ::= or_test | old_lambda_expr\n list_iter ::= list_for | list_if\n list_if ::= "if" old_expression [list_iter]\n\nA list display yields a new list object. Its contents are specified\nby providing either a list of expressions or a list comprehension.\nWhen a comma-separated list of expressions is supplied, its elements\nare evaluated from left to right and placed into the list object in\nthat order. When a list comprehension is supplied, it consists of a\nsingle expression followed by at least one "for" clause and zero or\nmore "for" or "if" clauses. In this case, the elements of the new\nlist are those that would be produced by considering each of the "for"\nor "if" clauses a block, nesting from left to right, and evaluating\nthe expression to produce a list element each time the innermost block\nis reached [1].\n', - 'naming': u'\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function "execfile()" is a code block. The string argument\npassed to the built-in function "eval()" and to the "exec" statement\nis a code block. The expression read and evaluated by the built-in\nfunction "input()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a "NameError" exception is raised.\nIf the name refers to a local variable that has not been bound, a\n"UnboundLocalError" exception is raised. "UnboundLocalError" is a\nsubclass of "NameError".\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, in the\nsecond position of an "except" clause header or after "as" in a "with"\nstatement. The "import" statement of the form "from ... import *"\nbinds all names defined in the imported module, except those beginning\nwith an underscore. This form may only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a "SyntaxError".\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "__builtin__". The global namespace is searched first.\nIf the name is not found there, the builtins namespace is searched.\nThe global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "__builtin__" (note: no\n\'s\'); when in any other module, "__builtins__" is an alias for the\ndictionary of the "__builtin__" module itself. "__builtins__" can be\nset to a user-created dictionary to create a weak form of restricted\nexecution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "__builtin__" (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- "import *" --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a "SyntaxError".\n\nIf "exec" is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n"SyntaxError" unless the exec explicitly specifies the local namespace\nfor the "exec". (In other words, "exec obj" would be illegal, but\n"exec obj in ns" would be legal.)\n\nThe "eval()", "execfile()", and "input()" functions and the "exec"\nstatement do not have access to the full environment for resolving\nnames. Names may be resolved in the local and global namespaces of\nthe caller. Free variables are not resolved in the nearest enclosing\nnamespace, but in the global namespace. [1] The "exec" statement and\nthe "eval()" and "execfile()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', - 'numbers': u'\nNumeric literals\n****************\n\nThere are four types of numeric literals: plain integers, long\nintegers, floating point numbers, and imaginary numbers. There are no\ncomplex literals (complex numbers can be formed by adding a real\nnumber and an imaginary number).\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator \'"-"\' and the\nliteral "1".\n', - 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "//", "%", "divmod()", "pow()", "**",\n "<<", ">>", "&", "^", "|"). For instance, to evaluate the\n expression "x + y", where *x* is an instance of a class that has an\n "__add__()" method, "x.__add__(y)" is called. The "__divmod__()"\n method should be the equivalent to using "__floordiv__()" and\n "__mod__()"; it should not be related to "__truediv__()" (described\n below). Note that "__pow__()" should be defined to accept an\n optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator ("/") is implemented by these methods. The\n "__truediv__()" method is used when "__future__.division" is in\n effect, otherwise "__div__()" is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; "TypeError" will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "/", "%", "divmod()", "pow()", "**",\n "<<", ">>", "&", "^", "|") with reflected (swapped) operands.\n These functions are only called if the left operand does not\n support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "/=", "//=", "%=", "**=", "<<=",\n ">>=", "&=", "^=", "|="). These methods should attempt to do the\n operation in-place (modifying *self*) and return the result (which\n could be, but does not have to be, *self*). If a specific method\n is not defined, the augmented assignment falls back to the normal\n methods. For instance, to execute the statement "x += y", where\n *x* is an instance of a class that has an "__iadd__()" method,\n "x.__iadd__(y)" is called. If *x* is an instance of a class that\n does not define a "__iadd__()" method, "x.__add__(y)" and\n "y.__radd__(x)" are considered, as with the evaluation of "x + y".\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions "complex()", "int()",\n "long()", and "float()". Should return a value of the appropriate\n type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions "oct()" and "hex()".\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement "operator.index()". Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or "None" if conversion is impossible. When\n the common type would be the type of "other", it is sufficient to\n return "None", since the interpreter will also ask the other object\n to attempt a coercion (but sometimes, if the implementation of the\n other type cannot be changed, it is useful to do the conversion to\n the other type here). A return value of "NotImplemented" is\n equivalent to returning "None".\n', - 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'"is"\' operator compares the\nidentity of two objects; the "id()" function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The "type()" function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the "gc" module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (ex:\nalways close files).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'"try"..."except"\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a "close()" method. Programs\nare strongly recommended to explicitly close such objects. The\n\'"try"..."finally"\' statement provides a convenient way to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after "a = 1; b = 1",\n"a" and "b" may or may not refer to the same object with the value\none, depending on the implementation, but after "c = []; d = []", "c"\nand "d" are guaranteed to refer to two different, unique, newly\ncreated empty lists. (Note that "c = d = []" assigns the same object\nto both "c" and "d".)\n', - 'operator-summary': u'\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section Comparisons --- and exponentiation, which groups from\nright to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| "lambda" | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| "if" -- "else" | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| "or" | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| "and" | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| "not" "x" | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| "in", "not in", "is", "is not", "<", "<=", ">", | Comparisons, including membership |\n| ">=", "<>", "!=", "==" | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| "|" | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| "^" | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| "&" | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| "<<", ">>" | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| "+", "-" | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| "*", "/", "//", "%" | Multiplication, division, remainder |\n| | [8] |\n+-------------------------------------------------+---------------------------------------+\n| "+x", "-x", "~x" | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| "**" | Exponentiation [9] |\n+-------------------------------------------------+---------------------------------------+\n| "x[index]", "x[index:index]", | Subscription, slicing, call, |\n| "x(arguments...)", "x.attribute" | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| "(expressions...)", "[expressions...]", "{key: | Binding or tuple display, list |\n| value...}", "`expressions...`" | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks"\n the control variables of each "for" it contains into the\n containing scope. However, this behavior is deprecated, and\n relying on it will not work in Python 3.\n\n[2] While "abs(x%y) < abs(y)" is true mathematically, for floats\n it may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that "-1e-100 % 1e100" have the same\n sign as "1e100", the computed result is "-1e-100 + 1e100", which\n is numerically exactly equal to "1e100". The function\n "math.fmod()" returns a result whose sign matches the sign of the\n first argument instead, and so returns "-1e-100" in this case.\n Which approach is more appropriate depends on the application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for "floor(x/y)" to be one larger than "(x-x%y)/y" due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that "divmod(x,y)[0] * y + x % y" be very close\n to "x".\n\n[4] While comparisons between unicode strings make sense at the\n byte level, they may be counter-intuitive to users. For example,\n the strings "u"\\u00C7"" and "u"\\u0043\\u0327"" compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using "unicodedata.normalize()".\n\n[5] The implementation computes this efficiently, without\n constructing lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of\n the sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to "{}".\n\n[7] Due to automatic garbage-collection, free lists, and the\n dynamic nature of descriptors, you may notice seemingly unusual\n behaviour in certain uses of the "is" operator, like those\n involving comparisons between instance methods, or constants.\n Check their documentation for more info.\n\n[8] The "%" operator is also used for string formatting; the same\n precedence applies.\n\n[9] The power operator "**" binds less tightly than an arithmetic\n or bitwise unary operator on its right, that is, "2**-1" is "0.5".\n', - 'pass': u'\nThe "pass" statement\n********************\n\n pass_stmt ::= "pass"\n\n"pass" is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', - 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, "10**2" returns "100", but\n"10**-2" returns "0.01". (This last feature was added in Python 2.2.\nIn Python 2.1 and before, if both arguments were of integer types and\nthe second argument was negative, an exception was raised).\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a\n"ValueError".\n', - 'print': u'\nThe "print" statement\n*********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n"print" evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is a whitespace character except "\' \'", or (3) when the last\nwrite operation on standard output was not a "print" statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\n\nNote: Objects which act like file objects but which are not the\n built-in file objects often do not properly emulate this aspect of\n the file object\'s behavior, so it is best not to rely on this.\n\nA "\'\\n\'" character is written at the end, unless the "print" statement\nends with a comma. This is the only action if the statement contains\njust the keyword "print".\n\nStandard output is defined as the file object named "stdout" in the\nbuilt-in module "sys". If no such object exists, or if it does not\nhave a "write()" method, a "RuntimeError" exception is raised.\n\n"print" also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n""print" chevron." In this form, the first expression after the ">>"\nmust evaluate to a "file-like" object, specifically an object that has\na "write()" method as described above. With this extended form, the\nsubsequent expressions are printed to this file object. If the first\nexpression evaluates to "None", then "sys.stdout" is used as the file\nfor output.\n', - 'raise': u'\nThe "raise" statement\n*********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," expression]]]\n\nIf no expressions are present, "raise" re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a "TypeError" exception is raised indicating that\nthis is an error (if running under IDLE, a "Queue.Empty" exception is\nraised instead).\n\nOtherwise, "raise" evaluates the expressions to get three objects,\nusing "None" as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be "None".\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is "None", an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not "None", it must be a traceback\nobject (see section The standard type hierarchy), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or "None", a "TypeError" exception is raised. The\nthree-expression form of "raise" is useful to re-raise an exception\ntransparently in an except clause, but "raise" with no expressions\nshould be preferred if the exception to be re-raised was the most\nrecently active exception in the current scope.\n\nAdditional information on exceptions can be found in section\nExceptions, and information about handling exceptions is in section\nThe try statement.\n', - 'return': u'\nThe "return" statement\n**********************\n\n return_stmt ::= "return" [expression_list]\n\n"return" may only occur syntactically nested in a function definition,\nnot within a nested class definition.\n\nIf an expression list is present, it is evaluated, else "None" is\nsubstituted.\n\n"return" leaves the current function call with the expression list (or\n"None") as return value.\n\nWhen "return" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nfunction.\n\nIn a generator function, the "return" statement is not allowed to\ninclude an "expression_list". In that context, a bare "return"\nindicates that the generator is done and will cause "StopIteration" to\nbe raised.\n', - 'sequence-types': u'\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. (For backwards compatibility, the method\n"__getslice__()" (see below) can also be defined to handle simple, but\nnot extended slices.) It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "has_key()", "get()",\n"clear()", "setdefault()", "iterkeys()", "itervalues()",\n"iteritems()", "pop()", "popitem()", "copy()", and "update()" behaving\nsimilar to those for Python\'s standard dictionary objects. The\n"UserDict" module provides a "DictMixin" class to help create those\nmethods from a base set of "__getitem__()", "__setitem__()",\n"__delitem__()", and "keys()". Mutable sequences should provide\nmethods "append()", "count()", "index()", "extend()", "insert()",\n"pop()", "remove()", "reverse()" and "sort()", like Python standard\nlist objects. Finally, sequence types should implement addition\n(meaning concatenation) and multiplication (meaning repetition) by\ndefining the methods "__add__()", "__radd__()", "__iadd__()",\n"__mul__()", "__rmul__()" and "__imul__()" described below; they\nshould not define "__coerce__()" or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should be equivalent of "has_key()"; for sequences,\nit should search through the values. It is further recommended that\nboth mappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "iterkeys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__nonzero__()" method and whose "__len__()"\n method returns zero is considered to be false in a Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method "iterkeys()".\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see Iterator Types.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\n New in version 2.6.\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see this section in the\n language reference.\n', - 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept plain or long integers as arguments. The\narguments are converted to a common type. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as division by "pow(2, n)". A\nleft shift by *n* bits is defined as multiplication with "pow(2, n)".\nNegative shift counts raise a "ValueError" exception.\n\nNote: In the current implementation, the right-hand operand is\n required to be at most "sys.maxsize". If the right-hand operand is\n larger than "sys.maxsize" an "OverflowError" exception is raised.\n', - 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or "del" statements. The syntax for a slicing:\n\n slicing ::= simple_slicing | extended_slicing\n simple_slicing ::= primary "[" short_slice "]"\n extended_slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice | ellipsis\n proper_slice ::= short_slice | long_slice\n short_slice ::= [lower_bound] ":" [upper_bound]\n long_slice ::= short_slice ":" [stride]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n ellipsis ::= "..."\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice nor ellipses). Similarly, when the slice\nlist has exactly one short slice and no trailing comma, the\ninterpretation as a simple slicing takes priority over that as an\nextended slicing.\n\nThe semantics for a simple slicing are as follows. The primary must\nevaluate to a sequence object. The lower and upper bound expressions,\nif present, must evaluate to plain integers; defaults are zero and the\n"sys.maxint", respectively. If either bound is negative, the\nsequence\'s length is added to it. The slicing now selects all items\nwith index *k* such that "i <= k < j" where *i* and *j* are the\nspecified lower and upper bounds. This may be an empty sequence. It\nis not an error if *i* or *j* lie outside the range of valid indexes\n(such items don\'t exist so they aren\'t selected).\n\nThe semantics for an extended slicing are as follows. The primary\nmust evaluate to a mapping object, and it is indexed with a key that\nis constructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of an ellipsis slice\nitem is the built-in "Ellipsis" object. The conversion of a proper\nslice is a slice object (see section The standard type hierarchy)\nwhose "start", "stop" and "step" attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting "None" for missing expressions.\n', - 'specialattrs': u'\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the "dir()" built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\nobject.__methods__\n\n Deprecated since version 2.2: Use the built-in function "dir()" to\n get a list of an object\'s attributes. This attribute is no longer\n available.\n\nobject.__members__\n\n Deprecated since version 2.2: Use the built-in function "dir()" to\n get a list of an object\'s attributes. This attribute is no longer\n available.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nThe following attributes are only supported by *new-style class*es.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in "__mro__".\n\nclass.__subclasses__()\n\n Each new-style class keeps a list of weak references to its\n immediate subclasses. This method returns a list of all those\n references still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found\n in the Python Reference Manual (Basic customization).\n\n[2] As a consequence, the list "[1, 2]" is considered equal to\n "[1.0, 2.0]", and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property\n being one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase),\n or "Lt" (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a\n singleton tuple whose only element is the tuple to be formatted.\n\n[6] The advantage of leaving the newline on is that returning an\n empty string is then an unambiguous EOF indication. It is also\n possible (in cases where it might matter, for example, if you want\n to make an exact copy of a file while scanning its lines) to tell\n whether the last line of a file ended in a newline or not (yes\n this happens!).\n', - 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "x.__getitem__(i)" for old-style\nclasses and "type(x).__getitem__(x, i)" for new-style classes. Except\nwhere mentioned, attempts to execute an operation raise an exception\nwhen no appropriate method is defined (typically "AttributeError" or\n"TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_traceback" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing "None" in\n "sys.exc_traceback" or "sys.last_traceback". Circular references\n which are garbage are detected when the option cycle detector is\n enabled (it\'s on by default), but can only be cleaned up if there\n are no Python-level "__del__()" methods involved. Refer to the\n documentation for the "gc" module for more information about how\n "__del__()" methods are handled by the cycle detector,\n particularly the description of the "garbage" value.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\n See also the "-R" command-line option.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function and by string conversions\n (reverse quotes) to compute the "official" string representation of\n an object. If at all possible, this should look like a valid\n Python expression that could be used to recreate an object with the\n same value (given an appropriate environment). If this is not\n possible, a string of the form "<...some useful description...>"\n should be returned. The return value must be a string object. If a\n class defines "__repr__()" but not "__str__()", then "__repr__()"\n is also used when an "informal" string representation of instances\n of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the "str()" built-in function and by the "print"\n statement to compute the "informal" string representation of an\n object. This differs from "__repr__()" in that it does not have to\n be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n New in version 2.1.\n\n These are the so-called "rich comparison" methods, and are called\n for comparison operators in preference to "__cmp__()" below. The\n correspondence between operator symbols and method names is as\n follows: "xy" call "x.__ne__(y)",\n "x>y" calls "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of "x==y" does not imply that "x!=y" is false.\n Accordingly, when defining "__eq__()", one should also define\n "__ne__()" so that the operators will behave as expected. See the\n paragraph on "__hash__()" for some important notes on creating\n *hashable* objects which support custom comparison operations and\n are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, "__lt__()" and "__gt__()" are each other\'s\n reflection, "__le__()" and "__ge__()" are each other\'s reflection,\n and "__eq__()" and "__ne__()" are their own reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see "functools.total_ordering()".\n\nobject.__cmp__(self, other)\n\n Called by comparison operations if rich comparison (see above) is\n not defined. Should return a negative integer if "self < other",\n zero if "self == other", a positive integer if "self > other". If\n no "__cmp__()", "__eq__()" or "__ne__()" operation is defined,\n class instances are compared by object identity ("address"). See\n also the description of "__hash__()" for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys. (Note: the\n restriction that exceptions are not propagated by "__cmp__()" has\n been removed since Python 1.5.)\n\nobject.__rcmp__(self, other)\n\n Changed in version 2.1: No longer supported.\n\nobject.__hash__(self)\n\n Called by built-in function "hash()" and for operations on members\n of hashed collections including "set", "frozenset", and "dict".\n "__hash__()" should return an integer. The only required property\n is that objects which compare equal have the same hash value; it is\n advised to somehow mix together (e.g. using exclusive or) the hash\n values for the components of the object that also play a part in\n comparison of objects.\n\n If a class does not define a "__cmp__()" or "__eq__()" method it\n should not define a "__hash__()" operation either; if it defines\n "__cmp__()" or "__eq__()" but not "__hash__()", its instances will\n not be usable in hashed collections. If a class defines mutable\n objects and implements a "__cmp__()" or "__eq__()" method, it\n should not implement "__hash__()", since hashable collection\n implementations require that a object\'s hash value is immutable (if\n the object\'s hash value changes, it will be in the wrong hash\n bucket).\n\n User-defined classes have "__cmp__()" and "__hash__()" methods by\n default; with them, all objects compare unequal (except with\n themselves) and "x.__hash__()" returns a result derived from\n "id(x)".\n\n Classes which inherit a "__hash__()" method from a parent class but\n change the meaning of "__cmp__()" or "__eq__()" such that the hash\n value returned is no longer appropriate (e.g. by switching to a\n value-based concept of equality instead of the default identity\n based equality) can explicitly flag themselves as being unhashable\n by setting "__hash__ = None" in the class definition. Doing so\n means that not only will instances of the class raise an\n appropriate "TypeError" when a program attempts to retrieve their\n hash value, but they will also be correctly identified as\n unhashable when checking "isinstance(obj, collections.Hashable)"\n (unlike classes which define their own "__hash__()" to explicitly\n raise "TypeError").\n\n Changed in version 2.5: "__hash__()" may now also return a long\n integer object; the 32-bit integer is then derived from the hash of\n that object.\n\n Changed in version 2.6: "__hash__" may now be set to "None" to\n explicitly flag instances of a class as unhashable.\n\nobject.__nonzero__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True", or their integer\n equivalents "0" or "1". When this method is not defined,\n "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__nonzero__()", all its instances are\n considered true.\n\nobject.__unicode__(self)\n\n Called to implement "unicode()" built-in; should return a Unicode\n object. When this method is not defined, string conversion is\n attempted, and the result of string conversion is converted to\n Unicode using the system default encoding.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control in new-style classes.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should not simply execute "self.name = value" --- this would cause\n a recursive call to itself. Instead, it should insert the value in\n the dictionary of instance attributes, e.g., "self.__dict__[name] =\n value". For new-style classes, rather than accessing the instance\n dictionary, it should call the base class method with the same\n name, for example, "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\n\nMore attribute access for new-style classes\n-------------------------------------------\n\nThe following methods only apply to new-style classes.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See Special method lookup for new-style\n classes.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called. Note that descriptors are only invoked for new\nstyle objects or classes (ones that subclass "object()" or "type()").\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to a new-style object instance, "a.x" is transformed\n into the call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a new-style class, "A.x" is transformed into the\n call: "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of both old and new-style classes have a\ndictionary for attribute storage. This wastes space for objects\nhaving very few instance variables. The space consumption can become\nacute when creating large numbers of instances.\n\nThe default can be overridden by defining *__slots__* in a new-style\nclass definition. The *__slots__* declaration takes a sequence of\ninstance variables and reserves just enough space in each instance to\nhold a value for each variable. Space is saved because *__dict__* is\nnot created for each instance.\n\n__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n new-style class, *__slots__* reserves space for the declared\n variables and prevents the automatic creation of *__dict__* and\n *__weakref__* for each instance.\n\n New in version 2.2.\n\nNotes on using *__slots__*\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding "\'__dict__\'" to the\n *__slots__* declaration would not enable the assignment of new\n attributes not specifically listed in the sequence of instance\n variable names.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n Changed in version 2.3: Previously, adding "\'__weakref__\'" to the\n *__slots__* declaration would not enable support for weak\n references.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (Implementing Descriptors) for each variable name. As a\n result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "long", "str" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n Changed in version 2.6: Previously, *__class__* assignment raised an\n error if either new or old class had *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, new-style classes are constructed using "type()". A class\ndefinition is read into a separate namespace and the value of class\nname is bound to the result of "type(name, bases, dict)".\n\nWhen the class definition is read, if *__metaclass__* is defined then\nthe callable assigned to it will be called instead of "type()". This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing\n the role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s "__new__()"\nmethod -- "type.__new__()" can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom "__call__()" method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\n__metaclass__\n\n This variable can be any callable accepting arguments for "name",\n "bases", and "dict". Upon class creation, the callable is used\n instead of the built-in "type()".\n\n New in version 2.2.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If "dict[\'__metaclass__\']" exists, it is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used (this looks for a *__class__* attribute first and if not found,\n uses its type).\n\n* Otherwise, if a global variable named __metaclass__ exists, it is\n used.\n\n* Otherwise, the old-style, classic metaclass (types.ClassType) is\n used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\n\nCustomizing instance and subclass checks\n========================================\n\nNew in version 2.6.\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n Includes the specification for customizing "isinstance()" and\n "issubclass()" behavior through "__instancecheck__()" and\n "__subclasscheck__()", with motivation for this functionality in\n the context of adding Abstract Base Classes (see the "abc"\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. (For backwards compatibility, the method\n"__getslice__()" (see below) can also be defined to handle simple, but\nnot extended slices.) It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "has_key()", "get()",\n"clear()", "setdefault()", "iterkeys()", "itervalues()",\n"iteritems()", "pop()", "popitem()", "copy()", and "update()" behaving\nsimilar to those for Python\'s standard dictionary objects. The\n"UserDict" module provides a "DictMixin" class to help create those\nmethods from a base set of "__getitem__()", "__setitem__()",\n"__delitem__()", and "keys()". Mutable sequences should provide\nmethods "append()", "count()", "index()", "extend()", "insert()",\n"pop()", "remove()", "reverse()" and "sort()", like Python standard\nlist objects. Finally, sequence types should implement addition\n(meaning concatenation) and multiplication (meaning repetition) by\ndefining the methods "__add__()", "__radd__()", "__iadd__()",\n"__mul__()", "__rmul__()" and "__imul__()" described below; they\nshould not define "__coerce__()" or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should be equivalent of "has_key()"; for sequences,\nit should search through the values. It is further recommended that\nboth mappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "iterkeys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__nonzero__()" method and whose "__len__()"\n method returns zero is considered to be false in a Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method "iterkeys()".\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see Iterator Types.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\n New in version 2.6.\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see this section in the\n language reference.\n\n\nAdditional methods for emulation of sequence types\n==================================================\n\nThe following optional methods can be defined to further emulate\nsequence objects. Immutable sequences methods should at most only\ndefine "__getslice__()"; mutable sequences might define all three\nmethods.\n\nobject.__getslice__(self, i, j)\n\n Deprecated since version 2.0: Support slice objects as parameters\n to the "__getitem__()" method. (However, built-in types in CPython\n currently still implement "__getslice__()". Therefore, you have to\n override it in derived classes when implementing slicing.)\n\n Called to implement evaluation of "self[i:j]". The returned object\n should be of the same type as *self*. Note that missing *i* or *j*\n in the slice expression are replaced by zero or "sys.maxsize",\n respectively. If negative indexes are used in the slice, the\n length of the sequence is added to that index. If the instance does\n not implement the "__len__()" method, an "AttributeError" is\n raised. No guarantee is made that indexes adjusted this way are not\n still negative. Indexes which are greater than the length of the\n sequence are not modified. If no "__getslice__()" is found, a slice\n object is created instead, and passed to "__getitem__()" instead.\n\nobject.__setslice__(self, i, j, sequence)\n\n Called to implement assignment to "self[i:j]". Same notes for *i*\n and *j* as for "__getslice__()".\n\n This method is deprecated. If no "__setslice__()" is found, or for\n extended slicing of the form "self[i:j:k]", a slice object is\n created, and passed to "__setitem__()", instead of "__setslice__()"\n being called.\n\nobject.__delslice__(self, i, j)\n\n Called to implement deletion of "self[i:j]". Same notes for *i* and\n *j* as for "__getslice__()". This method is deprecated. If no\n "__delslice__()" is found, or for extended slicing of the form\n "self[i:j:k]", a slice object is created, and passed to\n "__delitem__()", instead of "__delslice__()" being called.\n\nNotice that these methods are only invoked when a single slice with a\nsingle colon is used, and the slice method is available. For slice\noperations involving extended slice notation, or in absence of the\nslice methods, "__getitem__()", "__setitem__()" or "__delitem__()" is\ncalled with a slice object as argument.\n\nThe following example demonstrate how to make your program or module\ncompatible with earlier versions of Python (assuming that methods\n"__getitem__()", "__setitem__()" and "__delitem__()" support slice\nobjects as arguments):\n\n class MyClass:\n ...\n def __getitem__(self, index):\n ...\n def __setitem__(self, index, value):\n ...\n def __delitem__(self, index):\n ...\n\n if sys.version_info < (2, 0):\n # They won\'t be defined if version is at least 2.0 final\n\n def __getslice__(self, i, j):\n return self[max(0, i):max(0, j):]\n def __setslice__(self, i, j, seq):\n self[max(0, i):max(0, j):] = seq\n def __delslice__(self, i, j):\n del self[max(0, i):max(0, j):]\n ...\n\nNote the calls to "max()"; these are necessary because of the handling\nof negative indices before the "__*slice__()" methods are called.\nWhen negative indexes are used, the "__*item__()" methods receive them\nas provided, but the "__*slice__()" methods get a "cooked" form of the\nindex values. For each negative index value, the length of the\nsequence is added to the index before calling the method (which may\nstill result in a negative index); this is the customary handling of\nnegative indexes by the built-in sequence types, and the "__*item__()"\nmethods are expected to do this as well. However, since they should\nalready be doing that, negative indexes cannot be passed in; they must\nbe constrained to the bounds of the sequence before being passed to\nthe "__*item__()" methods. Calling "max(0, i)" conveniently returns\nthe proper value.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "//", "%", "divmod()", "pow()", "**",\n "<<", ">>", "&", "^", "|"). For instance, to evaluate the\n expression "x + y", where *x* is an instance of a class that has an\n "__add__()" method, "x.__add__(y)" is called. The "__divmod__()"\n method should be the equivalent to using "__floordiv__()" and\n "__mod__()"; it should not be related to "__truediv__()" (described\n below). Note that "__pow__()" should be defined to accept an\n optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__div__(self, other)\nobject.__truediv__(self, other)\n\n The division operator ("/") is implemented by these methods. The\n "__truediv__()" method is used when "__future__.division" is in\n effect, otherwise "__div__()" is used. If only one of these two\n methods is defined, the object will not support division in the\n alternate context; "TypeError" will be raised instead.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rdiv__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "/", "%", "divmod()", "pow()", "**",\n "<<", ">>", "&", "^", "|") with reflected (swapped) operands.\n These functions are only called if the left operand does not\n support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__idiv__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "/=", "//=", "%=", "**=", "<<=",\n ">>=", "&=", "^=", "|="). These methods should attempt to do the\n operation in-place (modifying *self*) and return the result (which\n could be, but does not have to be, *self*). If a specific method\n is not defined, the augmented assignment falls back to the normal\n methods. For instance, to execute the statement "x += y", where\n *x* is an instance of a class that has an "__iadd__()" method,\n "x.__iadd__(y)" is called. If *x* is an instance of a class that\n does not define a "__iadd__()" method, "x.__add__(y)" and\n "y.__radd__(x)" are considered, as with the evaluation of "x + y".\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__long__(self)\nobject.__float__(self)\n\n Called to implement the built-in functions "complex()", "int()",\n "long()", and "float()". Should return a value of the appropriate\n type.\n\nobject.__oct__(self)\nobject.__hex__(self)\n\n Called to implement the built-in functions "oct()" and "hex()".\n Should return a string value.\n\nobject.__index__(self)\n\n Called to implement "operator.index()". Also called whenever\n Python needs an integer object (such as in slicing). Must return\n an integer (int or long).\n\n New in version 2.5.\n\nobject.__coerce__(self, other)\n\n Called to implement "mixed-mode" numeric arithmetic. Should either\n return a 2-tuple containing *self* and *other* converted to a\n common numeric type, or "None" if conversion is impossible. When\n the common type would be the type of "other", it is sufficient to\n return "None", since the interpreter will also ask the other object\n to attempt a coercion (but sometimes, if the implementation of the\n other type cannot be changed, it is useful to do the conversion to\n the other type here). A return value of "NotImplemented" is\n equivalent to returning "None".\n\n\nCoercion rules\n==============\n\nThis section used to document the rules for coercion. As the language\nhas evolved, the coercion rules have become hard to document\nprecisely; documenting what one version of one particular\nimplementation does is undesirable. Instead, here are some informal\nguidelines regarding coercion. In Python 3, coercion will not be\nsupported.\n\n* If the left operand of a % operator is a string or Unicode object,\n no coercion takes place and the string formatting operation is\n invoked instead.\n\n* It is no longer recommended to define a coercion operation. Mixed-\n mode operations on types that don\'t define coercion pass the\n original arguments to the operation.\n\n* New-style classes (those derived from "object") never invoke the\n "__coerce__()" method in response to a binary operator; the only\n time "__coerce__()" is invoked is when the built-in function\n "coerce()" is called.\n\n* For most intents and purposes, an operator that returns\n "NotImplemented" is treated the same as one that is not implemented\n at all.\n\n* Below, "__op__()" and "__rop__()" are used to signify the generic\n method names corresponding to an operator; "__iop__()" is used for\n the corresponding in-place operator. For example, for the operator\n \'"+"\', "__add__()" and "__radd__()" are used for the left and right\n variant of the binary operator, and "__iadd__()" for the in-place\n variant.\n\n* For objects *x* and *y*, first "x.__op__(y)" is tried. If this is\n not implemented or returns "NotImplemented", "y.__rop__(x)" is\n tried. If this is also not implemented or returns "NotImplemented",\n a "TypeError" exception is raised. But see the following exception:\n\n* Exception to the previous item: if the left operand is an instance\n of a built-in type or a new-style class, and the right operand is an\n instance of a proper subclass of that type or class and overrides\n the base\'s "__rop__()" method, the right operand\'s "__rop__()"\n method is tried *before* the left operand\'s "__op__()" method.\n\n This is done so that a subclass can completely override binary\n operators. Otherwise, the left operand\'s "__op__()" method would\n always accept the right operand: when an instance of a given class\n is expected, an instance of a subclass of that class is always\n acceptable.\n\n* When either operand type defines a coercion, this coercion is\n called before that type\'s "__op__()" or "__rop__()" method is\n called, but no sooner. If the coercion returns an object of a\n different type for the operand whose coercion is invoked, part of\n the process is redone using the new object.\n\n* When an in-place operator (like \'"+="\') is used, if the left\n operand implements "__iop__()", it is invoked without any coercion.\n When the operation falls back to "__op__()" and/or "__rop__()", the\n normal coercion rules apply.\n\n* In "x + y", if *x* is a sequence that implements sequence\n concatenation, sequence concatenation is invoked.\n\n* In "x * y", if one operand is a sequence that implements sequence\n repetition, and the other is an integer ("int" or "long"), sequence\n repetition is invoked.\n\n* Rich comparisons (implemented by methods "__eq__()" and so on)\n never use coercion. Three-way comparison (implemented by\n "__cmp__()") does use coercion under the same conditions as other\n binary operations use it.\n\n* In the current implementation, the built-in numeric types "int",\n "long", "float", and "complex" do not use coercion. All these types\n implement a "__coerce__()" method, for use by the built-in\n "coerce()" function.\n\n Changed in version 2.7: The complex type no longer makes implicit\n calls to the "__coerce__()" method for mixed-type binary arithmetic\n operations.\n\n\nWith Statement Context Managers\n===============================\n\nNew in version 2.5.\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section The with\nstatement), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see Context Manager Types.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nSpecial method lookup for old-style classes\n===========================================\n\nFor old-style classes, special methods are always looked up in exactly\nthe same way as any other method or attribute. This is the case\nregardless of whether the method is being looked up explicitly as in\n"x.__getitem__(i)" or implicitly as in "x[i]".\n\nThis behaviour means that special methods may exhibit different\nbehaviour for different instances of a single old-style class if the\nappropriate special attributes are set differently:\n\n >>> class C:\n ... pass\n ...\n >>> c1 = C()\n >>> c2 = C()\n >>> c1.__len__ = lambda: 5\n >>> c2.__len__ = lambda: 9\n >>> len(c1)\n 5\n >>> len(c2)\n 9\n\n\nSpecial method lookup for new-style classes\n===========================================\n\nFor new-style classes, implicit invocations of special methods are\nonly guaranteed to work correctly if defined on an object\'s type, not\nin the object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception (unlike the equivalent example\nwith old-style classes):\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print "Metaclass getattribute invoked"\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object):\n ... __metaclass__ = Meta\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print "Class getattribute invoked"\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type,\n under certain controlled conditions. It generally isn\'t a good\n idea though, since it can lead to some very strange behaviour if\n it is handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as "__add__()") fails the operation is not\n supported, which is why the reflected method is not called.\n', - 'string-methods': u'\nString Methods\n**************\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n"bytearray" objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange section. To output formatted strings use\ntemplate strings or the "%" operator described in the String\nFormatting Operations section. Also, see the "re" module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n "\'strict\'", meaning that encoding errors raise "UnicodeError".\n Other possible values are "\'ignore\'", "\'replace\'" and any other\n name registered via "codecs.register_error()", see section Codec\n Base Classes.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n "\'strict\'", meaning that encoding errors raise a "UnicodeError".\n Other possible values are "\'ignore\'", "\'replace\'",\n "\'xmlcharrefreplace\'", "\'backslashreplace\'" and any other name\n registered via "codecs.register_error()", see section Codec Base\n Classes. For a list of possible encodings, see section Standard\n Encodings.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for "\'xmlcharrefreplace\'" and\n "\'backslashreplace\'" and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return "True" if the string ends with the specified *suffix*,\n otherwise return "False". *suffix* can also be a tuple of suffixes\n to look for. With optional *start*, test beginning at that\n position. With optional *end*, stop comparing at that position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab ("\\t"), one or more space characters are inserted in the result\n until the current column is equal to the next tab position. (The\n tab character itself is not copied.) If the character is a newline\n ("\\n") or return ("\\r"), it is copied and the current column is\n reset to zero. Any other character is copied unchanged and the\n current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" if *sub* is not found.\n\n Note: The "find()" method should be used only if you need to know\n the position of *sub*. To check if *sub* is a substring or not,\n use the "in" operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces "{}". Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See Format String Syntax for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3,\n and should be preferred to the "%" formatting described in String\n Formatting Operations in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like "find()", but raise "ValueError" when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like "rfind()" but raises "ValueError" when the substring *sub* is\n not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n "None", any whitespace string is a separator. Except for splitting\n from the right, "rsplit()" behaves like "split()" which is\n described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most "maxsplit+1"\n elements). If *maxsplit* is not specified or "-1", then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). The *sep* argument\n may consist of multiple characters (for example,\n "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n empty string with a specified separator returns "[\'\']".\n\n If *sep* is not specified or is "None", a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a "None" separator returns "[]".\n\n For example, "\' 1 2 3 \'.split()" returns "[\'1\', \'2\', \'3\']", and\n "\' 1 2 3 \'.split(None, 1)" returns "[\'1\', \'2 3 \']".\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, "\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()" returns "[\'ab\n c\', \'\', \'de fg\', \'kl\']", while the same call with\n "splitlines(True)" returns "[\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']".\n\n Unlike "split()" when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return "True" if string starts with the *prefix*, otherwise return\n "False". *prefix* can also be a tuple of prefixes to look for.\n With optional *start*, test string beginning at that position.\n With optional *end*, stop comparing string at that position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or "None", the *chars*\n argument defaults to removing whitespace. The *chars* argument is\n not a prefix or suffix; rather, all combinations of its values are\n stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the "maketrans()" helper function in the "string"\n module to create a translation table. For string objects, set the\n *table* argument to "None" for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a "None" *table* argument.\n\n For Unicode objects, the "translate()" method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or "None". Unmapped characters\n are left untouched. Characters mapped to "None" are deleted. Note,\n a more flexible approach is to create a custom character mapping\n codec using the "codecs" module (see "encodings.cp1251" for an\n example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that "str.upper().isupper()" might be\n "False" if "s" contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to "len(s)".\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return "True" if there are only numeric characters in S, "False"\n otherwise. Numeric characters include digit characters, and all\n characters that have the Unicode numeric value property, e.g.\n U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return "True" if there are only decimal characters in S, "False"\n otherwise. Decimal characters include digit characters, and all\n characters that can be used to form decimal-radix numbers, e.g.\n U+0660, ARABIC-INDIC DIGIT ZERO.\n', - 'strings': u'\nString literals\n***************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | "Ur" | "uR"\n | "b" | "B" | "br" | "Br" | "bR" | "BR"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | escapeseq\n longstringitem ::= longstringchar | escapeseq\n shortstringchar ::= \n longstringchar ::= \n escapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" and the rest of\nthe string literal. The source character set is defined by the\nencoding declaration; it is ASCII if no encoding declaration is given\nin the source file; see section Encoding declarations.\n\nIn plain English: String literals can be enclosed in matching single\nquotes ("\'") or double quotes ("""). They can also be enclosed in\nmatching groups of three single or double quotes (these are generally\nreferred to as *triple-quoted strings*). The backslash ("\\")\ncharacter is used to escape characters that otherwise have a special\nmeaning, such as newline, backslash itself, or the quote character.\nString literals may optionally be prefixed with a letter "\'r\'" or\n"\'R\'"; such strings are called *raw strings* and use different rules\nfor interpreting backslash escape sequences. A prefix of "\'u\'" or\n"\'U\'" makes the string a Unicode string. Unicode strings use the\nUnicode character set as defined by the Unicode Consortium and ISO\n10646. Some additional escape sequences, described below, are\navailable in Unicode strings. A prefix of "\'b\'" or "\'B\'" is ignored in\nPython 2; it indicates that the literal should become a bytes literal\nin Python 3 (e.g. when code is automatically converted with 2to3). A\n"\'u\'" or "\'b\'" prefix may be followed by an "\'r\'" prefix.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\newline" | Ignored | |\n+-------------------+-----------------------------------+---------+\n| "\\\\" | Backslash ("\\") | |\n+-------------------+-----------------------------------+---------+\n| "\\\'" | Single quote ("\'") | |\n+-------------------+-----------------------------------+---------+\n| "\\"" | Double quote (""") | |\n+-------------------+-----------------------------------+---------+\n| "\\a" | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| "\\b" | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| "\\f" | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| "\\n" | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| "\\N{name}" | Character named *name* in the | |\n| | Unicode database (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| "\\r" | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| "\\t" | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx" | Character with 16-bit hex value | (1) |\n| | *xxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx" | Character with 32-bit hex value | (2) |\n| | *xxxxxxxx* (Unicode only) | |\n+-------------------+-----------------------------------+---------+\n| "\\v" | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| "\\ooo" | Character with octal value *ooo* | (3,5) |\n+-------------------+-----------------------------------+---------+\n| "\\xhh" | Character with hex value *hh* | (4,5) |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. Individual code units which form parts of a surrogate pair can\n be encoded using this escape sequence.\n\n2. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default).\n\n3. As in Standard C, up to three octal digits are accepted.\n\n4. Unlike in Standard C, exactly two hex digits are required.\n\n5. In a string literal, hexadecimal and octal escapes denote the\n byte with the given value; it is not necessary that the byte\n encodes a character in the source character set. In a Unicode\n literal, these escapes denote a Unicode character with the given\n value.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences marked as "(Unicode only)"\nin the table above fall into the category of unrecognized escapes for\nnon-Unicode string literals.\n\nWhen an "\'r\'" or "\'R\'" prefix is present, a character following a\nbackslash is included in the string without change, and *all\nbackslashes are left in the string*. For example, the string literal\n"r"\\n"" consists of two characters: a backslash and a lowercase "\'n\'".\nString quotes can be escaped with a backslash, but the backslash\nremains in the string; for example, "r"\\""" is a valid string literal\nconsisting of two characters: a backslash and a double quote; "r"\\""\nis not a valid string literal (even a raw string cannot end in an odd\nnumber of backslashes). Specifically, *a raw string cannot end in a\nsingle backslash* (since the backslash would escape the following\nquote character). Note also that a single backslash followed by a\nnewline is interpreted as those two characters as part of the string,\n*not* as a line continuation.\n\nWhen an "\'r\'" or "\'R\'" prefix is used in conjunction with a "\'u\'" or\n"\'U\'" prefix, then the "\\uXXXX" and "\\UXXXXXXXX" escape sequences are\nprocessed while *all other backslashes are left in the string*. For\nexample, the string literal "ur"\\u0062\\n"" consists of three Unicode\ncharacters: \'LATIN SMALL LETTER B\', \'REVERSE SOLIDUS\', and \'LATIN\nSMALL LETTER N\'. Backslashes can be escaped with a preceding\nbackslash; however, both remain in the string. As a result, "\\uXXXX"\nescape sequences are only recognized when there are an odd number of\nbackslashes.\n', - 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object of a sequence or mapping type.\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to a\nplain integer. If this value is negative, the length of the sequence\nis added to it (so that, e.g., "x[-1]" selects the last item of "x".)\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', - 'truth': u'\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an "if" or\n"while" condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* "None"\n\n* "False"\n\n* zero of any numeric type, for example, "0", "0L", "0.0", "0j".\n\n* any empty sequence, for example, "\'\'", "()", "[]".\n\n* any empty mapping, for example, "{}".\n\n* instances of user-defined classes, if the class defines a\n "__nonzero__()" or "__len__()" method, when that method returns the\n integer zero or "bool" value "False". [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn "0" or "False" for false and "1" or "True" for true, unless\notherwise stated. (Important exception: the Boolean operations "or"\nand "and" always return one of their operands.)\n', - 'try': u'\nThe "try" statement\n*******************\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression [("as" | ",") identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nChanged in version 2.5: In previous versions of Python,\n"try"..."except"..."finally" did not work. "try"..."except" had to be\nnested in "try"..."finally".\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject, or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified in that except clause, if present, and the except\nclause\'s suite is executed. All except clauses must have an\nexecutable block. When the end of this block is reached, execution\ncontinues normally after the entire try statement. (This means that\nif two nested handlers exist for the same exception, and the exception\noccurs in the try clause of the inner handler, the outer handler will\nnot handle the exception.)\n\nBefore an except clause\'s suite is executed, details about the\nexception are assigned to three variables in the "sys" module:\n"sys.exc_type" receives the object identifying the exception;\n"sys.exc_value" receives the exception\'s parameter;\n"sys.exc_traceback" receives a traceback object (see section The\nstandard type hierarchy) identifying the point in the program where\nthe exception occurred. These details are also available through the\n"sys.exc_info()" function, which returns a tuple "(exc_type,\nexc_value, exc_traceback)". Use of the corresponding variables is\ndeprecated in favor of this function, since their use is unsafe in a\nthreaded program. As of Python 1.5, the variables are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception, it is re-raised at the end of the\n"finally" clause. If the "finally" clause raises another exception or\nexecutes a "return" or "break" statement, the saved exception is\ndiscarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\nExceptions, and information on using the "raise" statement to generate\nexceptions may be found in section The raise statement.\n', - 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.).\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name "None". It\n is used to signify the absence of a value in many situations, e.g.,\n it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n "NotImplemented". Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n "Ellipsis". It is used to indicate the presence of the "..." syntax\n in a slice. Its truth value is true.\n\n"numbers.Number"\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n "numbers.Integral"\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are three types of integers:\n\n Plain integers\n These represent numbers in the range -2147483648 through\n 2147483647. (The range may be larger on machines with a\n larger natural word size, but not smaller.) When the result\n of an operation would fall outside this range, the result is\n normally returned as a long integer (in some cases, the\n exception "OverflowError" is raised instead). For the\n purpose of shift and mask operations, integers are assumed to\n have a binary, 2\'s complement notation using 32 or more bits,\n and hiding no bits from the user (i.e., all 4294967296\n different bit patterns correspond to different values).\n\n Long integers\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans\n These represent the truth values False and True. The two\n objects representing the values "False" and "True" are the\n only Boolean objects. The Boolean type is a subtype of plain\n integers, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ""False"" or\n ""True"" are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers and the least surprises when\n switching between the plain and long integer domains. Any\n operation, if it yields a result in the plain integer domain,\n will yield the same result in the long integer domain or when\n using mixed operands. The switch between domains is transparent\n to the programmer.\n\n "numbers.Real" ("float")\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these are\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n "numbers.Complex"\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number "z" can be retrieved through the read-only\n attributes "z.real" and "z.imag".\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function "len()" returns the number of items\n of a sequence. When the length of a sequence is *n*, the index set\n contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence *a* is\n selected by "a[i]".\n\n Sequences also support slicing: "a[i:j]" selects all items with\n index *k* such that *i* "<=" *k* "<" *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: "a[i:j:k]" selects all items of *a* with index *x* where\n "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string are characters. There is no separate\n character type; a character is represented by a string of one\n item. Characters represent (at least) 8-bit bytes. The\n built-in functions "chr()" and "ord()" convert between\n characters and nonnegative integers representing the byte\n values. Bytes with the values 0-127 usually represent the\n corresponding ASCII values, but the interpretation of values\n is up to the program. The string data type is also used to\n represent arrays of bytes, e.g., to hold data read from a\n file.\n\n (On systems whose native character set is not ASCII, strings\n may use EBCDIC in their internal representation, provided the\n functions "chr()" and "ord()" implement a mapping between\n ASCII and EBCDIC, and string comparison preserves the ASCII\n order. Or perhaps someone can propose a better rule?)\n\n Unicode\n The items of a Unicode object are Unicode code units. A\n Unicode code unit is represented by a Unicode object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in "sys.maxunicode", and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions "unichr()" and\n "ord()" convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the Unicode method "encode()" and the built-\n in function "unicode()".\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and "del" (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in "bytearray()" constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module "array" provides an additional example of a\n mutable sequence type.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function "len()"\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., "1" and\n "1.0"), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n "set()" constructor and can be modified afterwards by several\n methods, such as "add()".\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in "frozenset()" constructor. As a frozenset is immutable\n and *hashable*, it can be used again as an element of another\n set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation "a[k]" selects the item indexed by "k"\n from the mapping "a"; this can be used in expressions and as the\n target of assignments or "del" statements. The built-in function\n "len()" returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., "1" and "1.0")\n then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the "{...}"\n notation (see section Dictionary displays).\n\n The extension modules "dbm", "gdbm", and "bsddb" provide\n additional examples of mapping types.\n\nCallable types\n These are the types to which the function call operation (see\n section Calls) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section Function definitions). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +-------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +=========================+=================================+=============+\n | "__doc__" "func_doc" | The function\'s documentation | Writable |\n | | string, or "None" if | |\n | | unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | "__name__" "func_name" | The function\'s name. | Writable |\n +-------------------------+---------------------------------+-------------+\n | "__module__" | The name of the module the | Writable |\n | | function was defined in, or | |\n | | "None" if unavailable. | |\n +-------------------------+---------------------------------+-------------+\n | "__defaults__" | A tuple containing default | Writable |\n | "func_defaults" | argument values for those | |\n | | arguments that have defaults, | |\n | | or "None" if no arguments have | |\n | | a default value. | |\n +-------------------------+---------------------------------+-------------+\n | "__code__" "func_code" | The code object representing | Writable |\n | | the compiled function body. | |\n +-------------------------+---------------------------------+-------------+\n | "__globals__" | A reference to the dictionary | Read-only |\n | "func_globals" | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +-------------------------+---------------------------------+-------------+\n | "__dict__" "func_dict" | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +-------------------------+---------------------------------+-------------+\n | "__closure__" | "None" or a tuple of cells that | Read-only |\n | "func_closure" | contain bindings for the | |\n | | function\'s free variables. | |\n +-------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Changed in version 2.4: "func_name" is now writable.\n\n Changed in version 2.6: The double-underscore attributes\n "__closure__", "__code__", "__defaults__", and "__globals__"\n were introduced as aliases for the corresponding "func_*"\n attributes for forwards compatibility with Python 3.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n User-defined methods\n A user-defined method object combines a class, a class instance\n (or "None") and any callable object (normally a user-defined\n function).\n\n Special read-only attributes: "im_self" is the class instance\n object, "im_func" is the function object; "im_class" is the\n class of "im_self" for bound methods or the class that asked for\n the method for unbound methods; "__doc__" is the method\'s\n documentation (same as "im_func.__doc__"); "__name__" is the\n method name (same as "im_func.__name__"); "__module__" is the\n name of the module the method was defined in, or "None" if\n unavailable.\n\n Changed in version 2.2: "im_self" used to refer to the class\n that defined the method.\n\n Changed in version 2.6: For Python 3 forward-compatibility,\n "im_func" is also available as "__func__", and "im_self" as\n "__self__".\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object, an unbound\n user-defined method object, or a class method object. When the\n attribute is a user-defined method object, a new method object\n is only created if the class from which it is being retrieved is\n the same as, or a derived class of, the class stored in the\n original method object; otherwise, the original method object is\n used as it is.\n\n When a user-defined method object is created by retrieving a\n user-defined function object from a class, its "im_self"\n attribute is "None" and the method object is said to be unbound.\n When one is created by retrieving a user-defined function object\n from a class via one of its instances, its "im_self" attribute\n is the instance, and the method object is said to be bound. In\n either case, the new method\'s "im_class" attribute is the class\n from which the retrieval takes place, and its "im_func"\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the "im_func"\n attribute of the new instance is not the original method object\n but its "im_func" attribute.\n\n When a user-defined method object is created by retrieving a\n class method object from a class or instance, its "im_self"\n attribute is the class itself, and its "im_func" attribute is\n the function object underlying the class method.\n\n When an unbound user-defined method object is called, the\n underlying function ("im_func") is called, with the restriction\n that the first argument must be an instance of the proper class\n ("im_class") or of a derived class thereof.\n\n When a bound user-defined method object is called, the\n underlying function ("im_func") is called, inserting the class\n instance ("im_self") in front of the argument list. For\n instance, when "C" is a class which contains a definition for a\n function "f()", and "x" is an instance of "C", calling "x.f(1)"\n is equivalent to calling "C.f(x, 1)".\n\n When a user-defined method object is derived from a class method\n object, the "class instance" stored in "im_self" will actually\n be the class itself, so that calling either "x.f(1)" or "C.f(1)"\n is equivalent to calling "f(C,1)" where "f" is the underlying\n function.\n\n Note that the transformation from function object to (unbound or\n bound) method object happens each time the attribute is\n retrieved from the class or instance. In some cases, a fruitful\n optimization is to assign the attribute to a local variable and\n call that local variable. Also notice that this transformation\n only happens for user-defined functions; other callable objects\n (and all non-callable objects) are retrieved without\n transformation. It is also important to note that user-defined\n functions which are attributes of a class instance are not\n converted to bound methods; this *only* happens when the\n function is an attribute of the class.\n\n Generator functions\n A function or method which uses the "yield" statement (see\n section The yield statement) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s "next()" method will cause the function to\n execute until it provides a value using the "yield" statement.\n When the function executes a "return" statement or falls off the\n end, a "StopIteration" exception is raised and the iterator will\n have reached the end of the set of values to be returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are "len()" and "math.sin()"\n ("math" is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: "__doc__" is the function\'s documentation\n string, or "None" if unavailable; "__name__" is the function\'s\n name; "__self__" is set to "None" (but see the next item);\n "__module__" is the name of the module the function was defined\n in or "None" if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n "alist.append()", assuming *alist* is a list object. In this\n case, the special read-only attribute "__self__" is set to the\n object denoted by *alist*.\n\n Class Types\n Class types, or "new-style classes," are callable. These\n objects normally act as factories for new instances of\n themselves, but variations are possible for class types that\n override "__new__()". The arguments of the call are passed to\n "__new__()" and, in the typical case, to "__init__()" to\n initialize the new instance.\n\n Classic Classes\n Class objects are described below. When a class object is\n called, a new class instance (also described below) is created\n and returned. This implies a call to the class\'s "__init__()"\n method if it has one. Any arguments are passed on to the\n "__init__()" method. If there is no "__init__()" method, the\n class must be called without arguments.\n\n Class instances\n Class instances are described below. Class instances are\n callable only when the class has a "__call__()" method;\n "x(arguments)" is a shorthand for "x.__call__(arguments)".\n\nModules\n Modules are imported by the "import" statement (see section The\n import statement). A module object has a namespace implemented by a\n dictionary object (this is the dictionary referenced by the\n func_globals attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., "m.x" is equivalent to "m.__dict__["x"]". A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n\n Special read-only attribute: "__dict__" is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: "__name__" is the module\'s name;\n "__doc__" is the module\'s documentation string, or "None" if\n unavailable; "__file__" is the pathname of the file from which the\n module was loaded, if it was loaded from a file. The "__file__"\n attribute is not present for C modules that are statically linked\n into the interpreter; for extension modules loaded dynamically from\n a shared library, it is the pathname of the shared library file.\n\nClasses\n Both class types (new-style classes) and class objects (old-\n style/classic classes) are typically created by class definitions\n (see section Class definitions). A class has a namespace\n implemented by a dictionary object. Class attribute references are\n translated to lookups in this dictionary, e.g., "C.x" is translated\n to "C.__dict__["x"]" (although for new-style classes in particular\n there are a number of hooks which allow for other means of locating\n attributes). When the attribute name is not found there, the\n attribute search continues in the base classes. For old-style\n classes, the search is depth-first, left-to-right in the order of\n occurrence in the base class list. New-style classes use the more\n complex C3 method resolution order which behaves correctly even in\n the presence of \'diamond\' inheritance structures where there are\n multiple inheritance paths leading back to a common ancestor.\n Additional details on the C3 MRO used by new-style classes can be\n found in the documentation accompanying the 2.3 release at\n https://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class "C", say) would yield a\n user-defined function object or an unbound user-defined method\n object whose associated class is either "C" or one of its base\n classes, it is transformed into an unbound user-defined method\n object whose "im_class" attribute is "C". When it would yield a\n class method object, it is transformed into a bound user-defined\n method object whose "im_self" attribute is "C". When it would\n yield a static method object, it is transformed into the object\n wrapped by the static method object. See section Implementing\n Descriptors for another way in which attributes retrieved from a\n class may differ from those actually contained in its "__dict__"\n (note that only new-style classes support descriptors).\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: "__name__" is the class name; "__module__" is\n the module name in which the class was defined; "__dict__" is the\n dictionary containing the class\'s namespace; "__bases__" is a tuple\n (possibly empty or a singleton) containing the base classes, in the\n order of their occurrence in the base class list; "__doc__" is the\n class\'s documentation string, or None if undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object or an unbound user-defined method object whose\n associated class is the class (call it "C") of the instance for\n which the attribute reference was initiated or one of its bases, it\n is transformed into a bound user-defined method object whose\n "im_class" attribute is "C" and whose "im_self" attribute is the\n instance. Static method and class method objects are also\n transformed, as if they had been retrieved from class "C"; see\n above under "Classes". See section Implementing Descriptors for\n another way in which attributes of a class retrieved via its\n instances may differ from the objects actually stored in the\n class\'s "__dict__". If no class attribute is found, and the\n object\'s class has a "__getattr__()" method, that is called to\n satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n "__setattr__()" or "__delattr__()" method, this is called instead\n of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n Special method names.\n\n Special attributes: "__dict__" is the attribute dictionary;\n "__class__" is the instance\'s class.\n\nFiles\n A file object represents an open file. File objects are created by\n the "open()" built-in function, and also by "os.popen()",\n "os.fdopen()", and the "makefile()" method of socket objects (and\n perhaps by other functions or methods provided by extension\n modules). The objects "sys.stdin", "sys.stdout" and "sys.stderr"\n are initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams. See File Objects for\n complete documentation of file objects.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: "co_name" gives the function name;\n "co_argcount" is the number of positional arguments (including\n arguments with default values); "co_nlocals" is the number of\n local variables used by the function (including arguments);\n "co_varnames" is a tuple containing the names of the local\n variables (starting with the argument names); "co_cellvars" is a\n tuple containing the names of local variables that are\n referenced by nested functions; "co_freevars" is a tuple\n containing the names of free variables; "co_code" is a string\n representing the sequence of bytecode instructions; "co_consts"\n is a tuple containing the literals used by the bytecode;\n "co_names" is a tuple containing the names used by the bytecode;\n "co_filename" is the filename from which the code was compiled;\n "co_firstlineno" is the first line number of the function;\n "co_lnotab" is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); "co_stacksize" is the required stack size\n (including local variables); "co_flags" is an integer encoding a\n number of flags for the interpreter.\n\n The following flag bits are defined for "co_flags": bit "0x04"\n is set if the function uses the "*arguments" syntax to accept an\n arbitrary number of positional arguments; bit "0x08" is set if\n the function uses the "**keywords" syntax to accept arbitrary\n keyword arguments; bit "0x20" is set if the function is a\n generator.\n\n Future feature declarations ("from __future__ import division")\n also use bits in "co_flags" to indicate whether a code object\n was compiled with a particular feature enabled: bit "0x2000" is\n set if the function was compiled with future division enabled;\n bits "0x10" and "0x1000" were used in earlier versions of\n Python.\n\n Other bits in "co_flags" are reserved for internal use.\n\n If a code object represents a function, the first item in\n "co_consts" is the documentation string of the function, or\n "None" if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: "f_back" is to the previous stack\n frame (towards the caller), or "None" if this is the bottom\n stack frame; "f_code" is the code object being executed in this\n frame; "f_locals" is the dictionary used to look up local\n variables; "f_globals" is used for global variables;\n "f_builtins" is used for built-in (intrinsic) names;\n "f_restricted" is a flag indicating whether the function is\n executing in restricted execution mode; "f_lasti" gives the\n precise instruction (this is an index into the bytecode string\n of the code object).\n\n Special writable attributes: "f_trace", if not "None", is a\n function called at the start of each source code line (this is\n used by the debugger); "f_exc_type", "f_exc_value",\n "f_exc_traceback" represent the last exception raised in the\n parent frame provided another exception was ever raised in the\n current frame (in all other cases they are None); "f_lineno" is\n the current line number of the frame --- writing to this from\n within a trace function jumps to the given line (only for the\n bottom-most frame). A debugger can implement a Jump command\n (aka Set Next Statement) by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n The try statement.) It is accessible as "sys.exc_traceback", and\n also as the third item of the tuple returned by\n "sys.exc_info()". The latter is the preferred interface, since\n it works correctly when the program is using multiple threads.\n When the program contains no suitable handler, the stack trace\n is written (nicely formatted) to the standard error stream; if\n the interpreter is interactive, it is also made available to the\n user as "sys.last_traceback".\n\n Special read-only attributes: "tb_next" is the next level in the\n stack trace (towards the frame where the exception occurred), or\n "None" if there is no next level; "tb_frame" points to the\n execution frame of the current level; "tb_lineno" gives the line\n number where the exception occurred; "tb_lasti" indicates the\n precise instruction. The line number and last instruction in\n the traceback may differ from the line number of its frame\n object if the exception occurred in a "try" statement with no\n matching except clause or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices when *extended slice\n syntax* is used. This is a slice using two colons, or multiple\n slices or ellipses separated by commas, e.g., "a[i:j:step]",\n "a[i:j, k:l]", or "a[..., i:j]". They are also created by the\n built-in "slice()" function.\n\n Special read-only attributes: "start" is the lower bound; "stop"\n is the upper bound; "step" is the step value; each is "None" if\n omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the extended slice that the slice\n object would describe if applied to a sequence of *length*\n items. It returns a tuple of three integers; respectively\n these are the *start* and *stop* indices and the *step* or\n stride length of the slice. Missing or out-of-bounds indices\n are handled in a manner consistent with regular slices.\n\n New in version 2.3.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n "staticmethod()" constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in "classmethod()" constructor.\n', - 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: "func(argument-list)".\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee Function definitions for more information.\n', - 'typesmapping': u'\nMapping Types --- "dict"\n************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin "list", "set", and "tuple" classes, and the "collections" module.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as "1" and "1.0") then they can be used interchangeably to index\nthe same dictionary entry. (Note however, that since computers store\nfloating-point numbers as approximations it is usually unwise to use\nthem as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of "key:\nvalue" pairs within braces, for example: "{\'jack\': 4098, \'sjoerd\':\n4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the "dict"\nconstructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterable*\n object. Each item in the iterable must itself be an iterable with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to "{"one": 1, "two": 2, "three": 3}":\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for building a dictionary from\n keyword arguments added.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a "KeyError" if\n *key* is not in the map.\n\n If a subclass of dict defines a method "__missing__()" and *key*\n is not present, the "d[key]" operation calls that method with\n the key *key* as argument. The "d[key]" operation then returns\n or raises whatever is returned or raised by the\n "__missing__(key)" call. No other operations or methods invoke\n "__missing__()". If "__missing__()" is not defined, "KeyError"\n is raised. "__missing__()" must be a method; it cannot be an\n instance variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n The example above shows part of the implementation of\n "collections.Counter". A different "__missing__" method is used\n by "collections.defaultdict".\n\n New in version 2.5: Recognition of __missing__ methods of dict\n subclasses.\n\n d[key] = value\n\n Set "d[key]" to *value*.\n\n del d[key]\n\n Remove "d[key]" from *d*. Raises a "KeyError" if *key* is not\n in the map.\n\n key in d\n\n Return "True" if *d* has a key *key*, else "False".\n\n New in version 2.2.\n\n key not in d\n\n Equivalent to "not key in d".\n\n New in version 2.2.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for "iterkeys()".\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n "fromkeys()" is a class method that returns a new dictionary.\n *value* defaults to "None".\n\n New in version 2.3.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to "None", so\n that this method never raises a "KeyError".\n\n has_key(key)\n\n Test for the presence of *key* in the dictionary. "has_key()"\n is deprecated in favor of "key in d".\n\n items()\n\n Return a copy of the dictionary\'s list of "(key, value)" pairs.\n\n **CPython implementation detail:** Keys and values are listed in\n an arbitrary order which is non-random, varies across Python\n implementations, and depends on the dictionary\'s history of\n insertions and deletions.\n\n If "items()", "keys()", "values()", "iteritems()", "iterkeys()",\n and "itervalues()" are called with no intervening modifications\n to the dictionary, the lists will directly correspond. This\n allows the creation of "(value, key)" pairs using "zip()":\n "pairs = zip(d.values(), d.keys())". The same relationship\n holds for the "iterkeys()" and "itervalues()" methods: "pairs =\n zip(d.itervalues(), d.iterkeys())" provides the same value for\n "pairs". Another way to create the same list is "pairs = [(v, k)\n for (k, v) in d.iteritems()]".\n\n iteritems()\n\n Return an iterator over the dictionary\'s "(key, value)" pairs.\n See the note for "dict.items()".\n\n Using "iteritems()" while adding or deleting entries in the\n dictionary may raise a "RuntimeError" or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n iterkeys()\n\n Return an iterator over the dictionary\'s keys. See the note for\n "dict.items()".\n\n Using "iterkeys()" while adding or deleting entries in the\n dictionary may raise a "RuntimeError" or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n itervalues()\n\n Return an iterator over the dictionary\'s values. See the note\n for "dict.items()".\n\n Using "itervalues()" while adding or deleting entries in the\n dictionary may raise a "RuntimeError" or fail to iterate over\n all entries.\n\n New in version 2.2.\n\n keys()\n\n Return a copy of the dictionary\'s list of keys. See the note\n for "dict.items()".\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a "KeyError" is raised.\n\n New in version 2.3.\n\n popitem()\n\n Remove and return an arbitrary "(key, value)" pair from the\n dictionary.\n\n "popitem()" is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling "popitem()" raises a "KeyError".\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to "None".\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return "None".\n\n "update()" accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: "d.update(red=1,\n blue=2)".\n\n Changed in version 2.4: Allowed the argument to be an iterable\n of key/value pairs and allowed keyword arguments.\n\n values()\n\n Return a copy of the dictionary\'s list of values. See the note\n for "dict.items()".\n\n viewitems()\n\n Return a new view of the dictionary\'s items ("(key, value)"\n pairs). See below for documentation of view objects.\n\n New in version 2.7.\n\n viewkeys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n viewvalues()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n New in version 2.7.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by "dict.viewkeys()", "dict.viewvalues()" and\n"dict.viewitems()" are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of "(key, value)") in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of "(value, key)" pairs using\n "zip()": "pairs = zip(d.values(), d.keys())". Another way to\n create the same list is "pairs = [(v, k) for (k, v) in d.items()]".\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a "RuntimeError" or fail to iterate over all entries.\n\nx in dictview\n\n Return "True" if *x* is in the underlying dictionary\'s keys, values\n or items (in the latter case, *x* should be a "(key, value)"\n tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.viewkeys()\n >>> values = dishes.viewvalues()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n', - 'typesmethods': u'\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as "append()" on lists)\nand class instance methods. Built-in methods are described with the\ntypes that support them.\n\nThe implementation adds two special read-only attributes to class\ninstance methods: "m.im_self" is the object on which the method\noperates, and "m.im_func" is the function implementing the method.\nCalling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to\ncalling "m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)".\n\nClass instance methods are either *bound* or *unbound*, referring to\nwhether the method was accessed through an instance or a class,\nrespectively. When a method is unbound, its "im_self" attribute will\nbe "None" and if called, an explicit "self" object must be passed as\nthe first argument. In this case, "self" must be an instance of the\nunbound method\'s class (or a subclass of that class), otherwise a\n"TypeError" is raised.\n\nLike function objects, methods objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object ("meth.im_func"), setting method\nattributes on either bound or unbound methods is disallowed.\nAttempting to set an attribute on a method results in an\n"AttributeError" being raised. In order to set a method attribute,\nyou need to explicitly set it on the underlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "", line 1, in \n AttributeError: \'instancemethod\' object has no attribute \'whoami\'\n >>> c.method.im_func.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee The standard type hierarchy for more information.\n', - 'typesmodules': u'\nModules\n*******\n\nThe only special operation on a module is attribute access: "m.name",\nwhere *m* is a module and *name* accesses a name defined in *m*\'s\nsymbol table. Module attributes can be assigned to. (Note that the\n"import" statement is not, strictly speaking, an operation on a module\nobject; "import foo" does not require a module object named *foo* to\nexist, rather it requires an (external) *definition* for a module\nnamed *foo* somewhere.)\n\nA special attribute of every module is "__dict__". This is the\ndictionary containing the module\'s symbol table. Modifying this\ndictionary will actually change the module\'s symbol table, but direct\nassignment to the "__dict__" attribute is not possible (you can write\n"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but you can\'t\nwrite "m.__dict__ = {}"). Modifying "__dict__" directly is not\nrecommended.\n\nModules built into the interpreter are written like this: "". If loaded from a file, they are written as\n"".\n', - 'typesseq': u'\nSequence Types --- "str", "unicode", "list", "tuple", "bytearray", "buffer", "xrange"\n*************************************************************************************\n\nThere are seven sequence types: strings, Unicode strings, lists,\ntuples, bytearrays, buffers, and xrange objects.\n\nFor other containers see the built in "dict" and "set" classes, and\nthe "collections" module.\n\nString literals are written in single or double quotes: "\'xyzzy\'",\n""frobozz"". See String literals for more about string literals.\nUnicode strings are much like strings, but are specified in the syntax\nusing a preceding "\'u\'" character: "u\'abc\'", "u"def"". In addition to\nthe functionality described here, there are also string-specific\nmethods described in the String Methods section. Lists are constructed\nwith square brackets, separating items with commas: "[a, b, c]".\nTuples are constructed by the comma operator (not within square\nbrackets), with or without enclosing parentheses, but an empty tuple\nmust have the enclosing parentheses, such as "a, b, c" or "()". A\nsingle item tuple must have a trailing comma, such as "(d,)".\n\nBytearray objects are created with the built-in function\n"bytearray()".\n\nBuffer objects are not directly supported by Python syntax, but can be\ncreated by calling the built-in function "buffer()". They don\'t\nsupport concatenation or repetition.\n\nObjects of type xrange are similar to buffers in that there is no\nspecific syntax to create them, but they are created using the\n"xrange()" function. They don\'t support slicing, concatenation or\nrepetition, and using "in", "not in", "min()" or "max()" on them is\ninefficient.\n\nMost sequence types support the following operations. The "in" and\n"not in" operations have the same priorities as the comparison\noperations. The "+" and "*" operations have the same priority as the\ncorresponding numeric operations. [3] Additional methods are provided\nfor Mutable Sequence Types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type; *n*, *i* and\n*j* are integers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| "x in s" | "True" if an item of *s* is | (1) |\n| | equal to *x*, else "False" | |\n+--------------------+----------------------------------+------------+\n| "x not in s" | "False" if an item of *s* is | (1) |\n| | equal to *x*, else "True" | |\n+--------------------+----------------------------------+------------+\n| "s + t" | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| "s * n, n * s" | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| "s[i]" | *i*th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| "s[i:j]" | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| "s[i:j:k]" | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| "len(s)" | length of *s* | |\n+--------------------+----------------------------------+------------+\n| "min(s)" | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| "max(s)" | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n| "s.index(x)" | index of the first occurrence of | |\n| | *x* in *s* | |\n+--------------------+----------------------------------+------------+\n| "s.count(x)" | total number of occurrences of | |\n| | *x* in *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must compare\nequal and the two sequences must be of the same type and have the same\nlength. (For full details see Comparisons in the language reference.)\n\nNotes:\n\n1. When *s* is a string or Unicode string object the "in" and "not\n in" operations act like a substring test. In Python versions\n before 2.3, *x* had to be a string of length 1. In Python 2.3 and\n beyond, *x* may be a string of any length.\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that "[[]]" is a one-element list containing\n an empty list, so all three elements of "[[]] * 3" are (pointers\n to) this single empty list. Modifying any of the elements of\n "lists" modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of\n the string: "len(s) + i" or "len(s) + j" is substituted. But note\n that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that "i <= k < j". If *i* or *j* is\n greater than "len(s)", use "len(s)". If *i* is omitted or "None",\n use "0". If *j* is omitted or "None", use "len(s)". If *i* is\n greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index "x = i + n*k" such that "0 <= n <\n (j-i)/k". In other words, the indices are "i", "i+k", "i+2*k",\n "i+3*k" and so on, stopping when *j* is reached (but never\n including *j*). If *i* or *j* is greater than "len(s)", use\n "len(s)". If *i* or *j* are omitted or "None", they become "end"\n values (which end depends on the sign of *k*). Note, *k* cannot be\n zero. If *k* is "None", it is treated like "1".\n\n6. **CPython implementation detail:** If *s* and *t* are both\n strings, some Python implementations such as CPython can usually\n perform an in-place optimization for assignments of the form "s = s\n + t" or "s += t". When applicable, this optimization makes\n quadratic run-time much less likely. This optimization is both\n version and implementation dependent. For performance sensitive\n code, it is preferable to use the "str.join()" method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n Changed in version 2.4: Formerly, string concatenation never\n occurred in-place.\n\n\nString Methods\n==============\n\nBelow are listed the string methods which both 8-bit strings and\nUnicode objects support. Some of them are also available on\n"bytearray" objects.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the Sequence Types --- str, unicode, list, tuple,\nbytearray, buffer, xrange section. To output formatted strings use\ntemplate strings or the "%" operator described in the String\nFormatting Operations section. Also, see the "re" module for string\nfunctions based on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.decode([encoding[, errors]])\n\n Decodes the string using the codec registered for *encoding*.\n *encoding* defaults to the default string encoding. *errors* may\n be given to set a different error handling scheme. The default is\n "\'strict\'", meaning that encoding errors raise "UnicodeError".\n Other possible values are "\'ignore\'", "\'replace\'" and any other\n name registered via "codecs.register_error()", see section Codec\n Base Classes.\n\n New in version 2.2.\n\n Changed in version 2.3: Support for other error handling schemes\n added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.encode([encoding[, errors]])\n\n Return an encoded version of the string. Default encoding is the\n current default string encoding. *errors* may be given to set a\n different error handling scheme. The default for *errors* is\n "\'strict\'", meaning that encoding errors raise a "UnicodeError".\n Other possible values are "\'ignore\'", "\'replace\'",\n "\'xmlcharrefreplace\'", "\'backslashreplace\'" and any other name\n registered via "codecs.register_error()", see section Codec Base\n Classes. For a list of possible encodings, see section Standard\n Encodings.\n\n New in version 2.0.\n\n Changed in version 2.3: Support for "\'xmlcharrefreplace\'" and\n "\'backslashreplace\'" and other error handling schemes added.\n\n Changed in version 2.7: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return "True" if the string ends with the specified *suffix*,\n otherwise return "False". *suffix* can also be a tuple of suffixes\n to look for. With optional *start*, test beginning at that\n position. With optional *end*, stop comparing at that position.\n\n Changed in version 2.5: Accept tuples as *suffix*.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab ("\\t"), one or more space characters are inserted in the result\n until the current column is equal to the next tab position. (The\n tab character itself is not copied.) If the character is a newline\n ("\\n") or return ("\\r"), it is copied and the current column is\n reset to zero. Any other character is copied unchanged and the\n current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" if *sub* is not found.\n\n Note: The "find()" method should be used only if you need to know\n the position of *sub*. To check if *sub* is a substring or not,\n use the "in" operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces "{}". Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See Format String Syntax for a description of the various\n formatting options that can be specified in format strings.\n\n This method of string formatting is the new standard in Python 3,\n and should be preferred to the "%" formatting described in String\n Formatting Operations in new code.\n\n New in version 2.6.\n\nstr.index(sub[, start[, end]])\n\n Like "find()", but raise "ValueError" when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. The separator between elements is the\n string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\n New in version 2.5.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like "rfind()" but raises "ValueError" when the substring *sub* is\n not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\n Changed in version 2.4: Support for the *fillchar* argument.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\n New in version 2.5.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n "None", any whitespace string is a separator. Except for splitting\n from the right, "rsplit()" behaves like "split()" which is\n described in detail below.\n\n New in version 2.4.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most "maxsplit+1"\n elements). If *maxsplit* is not specified or "-1", then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). The *sep* argument\n may consist of multiple characters (for example,\n "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n empty string with a specified separator returns "[\'\']".\n\n If *sep* is not specified or is "None", a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a "None" separator returns "[]".\n\n For example, "\' 1 2 3 \'.split()" returns "[\'1\', \'2\', \'3\']", and\n "\' 1 2 3 \'.split(None, 1)" returns "[\'1\', \'2 3 \']".\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. This method uses the *universal newlines* approach to\n splitting lines. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n For example, "\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()" returns "[\'ab\n c\', \'\', \'de fg\', \'kl\']", while the same call with\n "splitlines(True)" returns "[\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']".\n\n Unlike "split()" when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line.\n\nstr.startswith(prefix[, start[, end]])\n\n Return "True" if string starts with the *prefix*, otherwise return\n "False". *prefix* can also be a tuple of prefixes to look for.\n With optional *start*, test string beginning at that position.\n With optional *end*, stop comparing string at that position.\n\n Changed in version 2.5: Accept tuples as *prefix*.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or "None", the *chars*\n argument defaults to removing whitespace. The *chars* argument is\n not a prefix or suffix; rather, all combinations of its values are\n stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n Changed in version 2.2.2: Support for the *chars* argument.\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.translate(table[, deletechars])\n\n Return a copy of the string where all characters occurring in the\n optional argument *deletechars* are removed, and the remaining\n characters have been mapped through the given translation table,\n which must be a string of length 256.\n\n You can use the "maketrans()" helper function in the "string"\n module to create a translation table. For string objects, set the\n *table* argument to "None" for translations that only delete\n characters:\n\n >>> \'read this short text\'.translate(None, \'aeiou\')\n \'rd ths shrt txt\'\n\n New in version 2.6: Support for a "None" *table* argument.\n\n For Unicode objects, the "translate()" method does not accept the\n optional *deletechars* argument. Instead, it returns a copy of the\n *s* where all characters have been mapped through the given\n translation table which must be a mapping of Unicode ordinals to\n Unicode ordinals, Unicode strings or "None". Unmapped characters\n are left untouched. Characters mapped to "None" are deleted. Note,\n a more flexible approach is to create a custom character mapping\n codec using the "codecs" module (see "encodings.cp1251" for an\n example).\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that "str.upper().isupper()" might be\n "False" if "s" contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n For 8-bit strings, this method is locale-dependent.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than or equal to "len(s)".\n\n New in version 2.2.2.\n\nThe following methods are present only on unicode objects:\n\nunicode.isnumeric()\n\n Return "True" if there are only numeric characters in S, "False"\n otherwise. Numeric characters include digit characters, and all\n characters that have the Unicode numeric value property, e.g.\n U+2155, VULGAR FRACTION ONE FIFTH.\n\nunicode.isdecimal()\n\n Return "True" if there are only decimal characters in S, "False"\n otherwise. Decimal characters include digit characters, and all\n characters that can be used to form decimal-radix numbers, e.g.\n U+0660, ARABIC-INDIC DIGIT ZERO.\n\n\nString Formatting Operations\n============================\n\nString and Unicode objects have one unique built-in operation: the "%"\noperator (modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given "format % values" (where *format* is\na string or Unicode object), "%" conversion specifications in *format*\nare replaced with zero or more elements of *values*. The effect is\nsimilar to the using "sprintf()" in the C language. If *format* is a\nUnicode object, or if any of the objects being converted using the\n"%s" conversion are Unicode objects, the result will also be a Unicode\nobject.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [5] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The "\'%\'" character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence\n of characters (for example, "(somename)").\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an "\'*\'"\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a "\'.\'" (dot) followed by the\n precision. If specified as "\'*\'" (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the "\'%\'" character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print \'%(language)s has %(number)03d quote types.\' % \\\n... {"language": "Python", "number": 2}\nPython has 002 quote types.\n\nIn this case no "*" specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| "\'#\'" | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| "\'0\'" | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| "\'-\'" | The converted value is left adjusted (overrides the "\'0\'" conversion |\n| | if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| "\' \'" | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| "\'+\'" | A sign character ("\'+\'" or "\'-\'") will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier ("h", "l", or "L") may be present, but is ignored as\nit is not necessary for Python -- so e.g. "%ld" is identical to "%d".\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| "\'d\'" | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| "\'i\'" | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| "\'o\'" | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| "\'u\'" | Obsolete type -- it is identical to "\'d\'". | (7) |\n+--------------+-------------------------------------------------------+---------+\n| "\'x\'" | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| "\'X\'" | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| "\'e\'" | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| "\'E\'" | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| "\'f\'" | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| "\'F\'" | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| "\'g\'" | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| "\'G\'" | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| "\'c\'" | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| "\'r\'" | String (converts any Python object using repr()). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| "\'s\'" | String (converts any Python object using "str()"). | (6) |\n+--------------+-------------------------------------------------------+---------+\n| "\'%\'" | No argument is converted, results in a "\'%\'" | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero ("\'0\'") to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading "\'0x\'" or "\'0X\'" (depending\n on whether the "\'x\'" or "\'X\'" format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The "%r" conversion was added in Python 2.0.\n\n The precision determines the maximal number of characters used.\n\n6. If the object or format provided is a "unicode" string, the\n resulting string will also be "unicode".\n\n The precision determines the maximal number of characters used.\n\n7. See **PEP 237**.\n\nSince Python strings have an explicit length, "%s" conversions do not\nassume that "\'\\0\'" is the end of the string.\n\nChanged in version 2.7: "%f" conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by "%g" conversions.\n\nAdditional string operations are defined in standard modules "string"\nand "re".\n\n\nXRange Type\n===========\n\nThe "xrange" type is an immutable sequence which is commonly used for\nlooping. The advantage of the "xrange" type is that an "xrange"\nobject will always take the same amount of memory, no matter the size\nof the range it represents. There are no consistent performance\nadvantages.\n\nXRange objects have very little behavior: they only support indexing,\niteration, and the "len()" function.\n\n\nMutable Sequence Types\n======================\n\nList and "bytearray" objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | same as "s[len(s):len(s)] = [x]" | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(x)" | same as "s[len(s):len(s)] = x" | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.count(x)" | return number of *i*\'s for which | |\n| | "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.index(x[, i[, j]])" | return smallest *k* such that | (4) |\n| | "s[k] == x" and "i <= k < j" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | same as "s[i:i] = [x]" | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | same as "x = s[i]; del s[i]; | (6) |\n| | return x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | same as "del s[s.index(x)]" | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])" | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted\n multiple parameters and implicitly joined them into a tuple; this\n no longer works in Python 2.0. Use of this misfeature has been\n deprecated since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises "ValueError" when *x* is not found in *s*. When a\n negative index is passed as the second or third parameter to the\n "index()" method, the list length is added, as for slice indices.\n If it is still negative, it is truncated to zero, as for slice\n indices.\n\n Changed in version 2.3: Previously, "index()" didn\'t have arguments\n for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n "insert()" method, the list length is added, as for slice indices.\n If it is still negative, it is truncated to zero, as for slice\n indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The "pop()" method\'s optional argument *i* defaults to "-1", so\n that by default the last item is removed and returned.\n\n7. The "sort()" and "reverse()" methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The "sort()" method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: "cmp=lambda x,y:\n cmp(x.lower(), y.lower())". The default value is "None".\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: "key=str.lower". The\n default value is "None".\n\n *reverse* is a boolean value. If set to "True", then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n "functools.cmp_to_key()" to convert an old-style *cmp* function to\n a *key* function.\n\n Changed in version 2.3: Support for "None" as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the "sort()" method is guaranteed to\n be stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being\n sorted, the effect of attempting to mutate, or even inspect, the\n list is undefined. The C implementation of Python 2.3 and newer\n makes the list appear empty for the duration, and raises\n "ValueError" if it can detect that the list has been mutated\n during a sort.\n', - 'typesseq-mutable': u'\nMutable Sequence Types\n**********************\n\nList and "bytearray" objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object):\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | same as "s[len(s):len(s)] = [x]" | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(x)" | same as "s[len(s):len(s)] = x" | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.count(x)" | return number of *i*\'s for which | |\n| | "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.index(x[, i[, j]])" | return smallest *k* such that | (4) |\n| | "s[k] == x" and "i <= k < j" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | same as "s[i:i] = [x]" | (5) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | same as "x = s[i]; del s[i]; | (6) |\n| | return x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | same as "del s[s.index(x)]" | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (7) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.sort([cmp[, key[, | sort the items of *s* in place | (7)(8)(9)(10) |\n| reverse]]])" | | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The C implementation of Python has historically accepted\n multiple parameters and implicitly joined them into a tuple; this\n no longer works in Python 2.0. Use of this misfeature has been\n deprecated since Python 1.4.\n\n3. *x* can be any iterable object.\n\n4. Raises "ValueError" when *x* is not found in *s*. When a\n negative index is passed as the second or third parameter to the\n "index()" method, the list length is added, as for slice indices.\n If it is still negative, it is truncated to zero, as for slice\n indices.\n\n Changed in version 2.3: Previously, "index()" didn\'t have arguments\n for specifying start and stop positions.\n\n5. When a negative index is passed as the first parameter to the\n "insert()" method, the list length is added, as for slice indices.\n If it is still negative, it is truncated to zero, as for slice\n indices.\n\n Changed in version 2.3: Previously, all negative indices were\n truncated to zero.\n\n6. The "pop()" method\'s optional argument *i* defaults to "-1", so\n that by default the last item is removed and returned.\n\n7. The "sort()" and "reverse()" methods modify the list in place\n for economy of space when sorting or reversing a large list. To\n remind you that they operate by side effect, they don\'t return the\n sorted or reversed list.\n\n8. The "sort()" method takes optional arguments for controlling the\n comparisons.\n\n *cmp* specifies a custom comparison function of two arguments (list\n items) which should return a negative, zero or positive number\n depending on whether the first argument is considered smaller than,\n equal to, or larger than the second argument: "cmp=lambda x,y:\n cmp(x.lower(), y.lower())". The default value is "None".\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: "key=str.lower". The\n default value is "None".\n\n *reverse* is a boolean value. If set to "True", then the list\n elements are sorted as if each comparison were reversed.\n\n In general, the *key* and *reverse* conversion processes are much\n faster than specifying an equivalent *cmp* function. This is\n because *cmp* is called multiple times for each list element while\n *key* and *reverse* touch each element only once. Use\n "functools.cmp_to_key()" to convert an old-style *cmp* function to\n a *key* function.\n\n Changed in version 2.3: Support for "None" as an equivalent to\n omitting *cmp* was added.\n\n Changed in version 2.4: Support for *key* and *reverse* was added.\n\n9. Starting with Python 2.3, the "sort()" method is guaranteed to\n be stable. A sort is stable if it guarantees not to change the\n relative order of elements that compare equal --- this is helpful\n for sorting in multiple passes (for example, sort by department,\n then by salary grade).\n\n10. **CPython implementation detail:** While a list is being\n sorted, the effect of attempting to mutate, or even inspect, the\n list is undefined. The C implementation of Python 2.3 and newer\n makes the list appear empty for the duration, and raises\n "ValueError" if it can detect that the list has been mutated\n during a sort.\n', - 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary "-" (minus) operator yields the negation of its numeric\nargument.\n\nThe unary "+" (plus) operator yields its numeric argument unchanged.\n\nThe unary "~" (invert) operator yields the bitwise inversion of its\nplain or long integer argument. The bitwise inversion of "x" is\ndefined as "-(x+1)". It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n"TypeError" exception is raised.\n', - 'while': u'\nThe "while" statement\n*********************\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n', - 'with': u'\nThe "with" statement\n********************\n\nNew in version 2.5.\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section With Statement\nContext Managers). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nNote: In Python 2.5, the "with" statement is only allowed when the\n "with_statement" feature has been enabled. It is always enabled in\n Python 2.6.\n\nChanged in version 2.7: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', - 'yield': u'\nThe "yield" statement\n*********************\n\n yield_stmt ::= yield_expression\n\nThe "yield" statement is only used when defining a generator function,\nand is only used in the body of the generator function. Using a\n"yield" statement in a function definition is sufficient to cause that\ndefinition to create a generator function instead of a normal\nfunction.\n\nWhen a generator function is called, it returns an iterator known as a\ngenerator iterator, or more commonly, a generator. The body of the\ngenerator function is executed by calling the generator\'s "next()"\nmethod repeatedly until it raises an exception.\n\nWhen a "yield" statement is executed, the state of the generator is\nfrozen and the value of "expression_list" is returned to "next()"\'s\ncaller. By "frozen" we mean that all local state is retained,\nincluding the current bindings of local variables, the instruction\npointer, and the internal evaluation stack: enough information is\nsaved so that the next time "next()" is invoked, the function can\nproceed exactly as if the "yield" statement were just another external\ncall.\n\nAs of Python version 2.5, the "yield" statement is now allowed in the\n"try" clause of a "try" ... "finally" construct. If the generator is\nnot resumed before it is finalized (by reaching a zero reference count\nor by being garbage collected), the generator-iterator\'s "close()"\nmethod will be called, allowing any pending "finally" clauses to\nexecute.\n\nFor full details of "yield" semantics, refer to the Yield expressions\nsection.\n\nNote: In Python 2.2, the "yield" statement was only allowed when the\n "generators" feature has been enabled. This "__future__" import\n statement was used to enable the feature:\n\n from __future__ import generators\n\nSee also: **PEP 0255** - Simple Generators\n\n The proposal for adding generators and the "yield" statement to\n Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing "yield" to appear inside a "try" ... "finally" block.\n'} +# Autogenerated by Sphinx on Sat Nov 21 13:35:13 2015 +topics = {'assert': '\n' + 'The "assert" statement\n' + '**********************\n' + '\n' + 'Assert statements are a convenient way to insert debugging ' + 'assertions\n' + 'into a program:\n' + '\n' + ' assert_stmt ::= "assert" expression ["," expression]\n' + '\n' + 'The simple form, "assert expression", is equivalent to\n' + '\n' + ' if __debug__:\n' + ' if not expression: raise AssertionError\n' + '\n' + 'The extended form, "assert expression1, expression2", is ' + 'equivalent to\n' + '\n' + ' if __debug__:\n' + ' if not expression1: raise AssertionError(expression2)\n' + '\n' + 'These equivalences assume that "__debug__" and "AssertionError" ' + 'refer\n' + 'to the built-in variables with those names. In the current\n' + 'implementation, the built-in variable "__debug__" is "True" ' + 'under\n' + 'normal circumstances, "False" when optimization is requested ' + '(command\n' + 'line option -O). The current code generator emits no code for ' + 'an\n' + 'assert statement when optimization is requested at compile ' + 'time. Note\n' + 'that it is unnecessary to include the source code for the ' + 'expression\n' + 'that failed in the error message; it will be displayed as part ' + 'of the\n' + 'stack trace.\n' + '\n' + 'Assignments to "__debug__" are illegal. The value for the ' + 'built-in\n' + 'variable is determined when the interpreter starts.\n', + 'assignment': '\n' + 'Assignment statements\n' + '*********************\n' + '\n' + 'Assignment statements are used to (re)bind names to values ' + 'and to\n' + 'modify attributes or items of mutable objects:\n' + '\n' + ' assignment_stmt ::= (target_list "=")+ (expression_list | ' + 'yield_expression)\n' + ' target_list ::= target ("," target)* [","]\n' + ' target ::= identifier\n' + ' | "(" target_list ")"\n' + ' | "[" target_list "]"\n' + ' | attributeref\n' + ' | subscription\n' + ' | slicing\n' + '\n' + '(See section Primaries for the syntax definitions for the ' + 'last three\n' + 'symbols.)\n' + '\n' + 'An assignment statement evaluates the expression list ' + '(remember that\n' + 'this can be a single expression or a comma-separated list, ' + 'the latter\n' + 'yielding a tuple) and assigns the single resulting object to ' + 'each of\n' + 'the target lists, from left to right.\n' + '\n' + 'Assignment is defined recursively depending on the form of ' + 'the target\n' + '(list). When a target is part of a mutable object (an ' + 'attribute\n' + 'reference, subscription or slicing), the mutable object ' + 'must\n' + 'ultimately perform the assignment and decide about its ' + 'validity, and\n' + 'may raise an exception if the assignment is unacceptable. ' + 'The rules\n' + 'observed by various types and the exceptions raised are ' + 'given with the\n' + 'definition of the object types (see section The standard ' + 'type\n' + 'hierarchy).\n' + '\n' + 'Assignment of an object to a target list is recursively ' + 'defined as\n' + 'follows.\n' + '\n' + '* If the target list is a single target: The object is ' + 'assigned to\n' + ' that target.\n' + '\n' + '* If the target list is a comma-separated list of targets: ' + 'The\n' + ' object must be an iterable with the same number of items ' + 'as there\n' + ' are targets in the target list, and the items are ' + 'assigned, from\n' + ' left to right, to the corresponding targets.\n' + '\n' + 'Assignment of an object to a single target is recursively ' + 'defined as\n' + 'follows.\n' + '\n' + '* If the target is an identifier (name):\n' + '\n' + ' * If the name does not occur in a "global" statement in ' + 'the\n' + ' current code block: the name is bound to the object in ' + 'the current\n' + ' local namespace.\n' + '\n' + ' * Otherwise: the name is bound to the object in the ' + 'current global\n' + ' namespace.\n' + '\n' + ' The name is rebound if it was already bound. This may ' + 'cause the\n' + ' reference count for the object previously bound to the ' + 'name to reach\n' + ' zero, causing the object to be deallocated and its ' + 'destructor (if it\n' + ' has one) to be called.\n' + '\n' + '* If the target is a target list enclosed in parentheses or ' + 'in\n' + ' square brackets: The object must be an iterable with the ' + 'same number\n' + ' of items as there are targets in the target list, and its ' + 'items are\n' + ' assigned, from left to right, to the corresponding ' + 'targets.\n' + '\n' + '* If the target is an attribute reference: The primary ' + 'expression in\n' + ' the reference is evaluated. It should yield an object ' + 'with\n' + ' assignable attributes; if this is not the case, ' + '"TypeError" is\n' + ' raised. That object is then asked to assign the assigned ' + 'object to\n' + ' the given attribute; if it cannot perform the assignment, ' + 'it raises\n' + ' an exception (usually but not necessarily ' + '"AttributeError").\n' + '\n' + ' Note: If the object is a class instance and the attribute ' + 'reference\n' + ' occurs on both sides of the assignment operator, the RHS ' + 'expression,\n' + ' "a.x" can access either an instance attribute or (if no ' + 'instance\n' + ' attribute exists) a class attribute. The LHS target "a.x" ' + 'is always\n' + ' set as an instance attribute, creating it if necessary. ' + 'Thus, the\n' + ' two occurrences of "a.x" do not necessarily refer to the ' + 'same\n' + ' attribute: if the RHS expression refers to a class ' + 'attribute, the\n' + ' LHS creates a new instance attribute as the target of the\n' + ' assignment:\n' + '\n' + ' class Cls:\n' + ' x = 3 # class variable\n' + ' inst = Cls()\n' + ' inst.x = inst.x + 1 # writes inst.x as 4 leaving ' + 'Cls.x as 3\n' + '\n' + ' This description does not necessarily apply to descriptor\n' + ' attributes, such as properties created with "property()".\n' + '\n' + '* If the target is a subscription: The primary expression in ' + 'the\n' + ' reference is evaluated. It should yield either a mutable ' + 'sequence\n' + ' object (such as a list) or a mapping object (such as a ' + 'dictionary).\n' + ' Next, the subscript expression is evaluated.\n' + '\n' + ' If the primary is a mutable sequence object (such as a ' + 'list), the\n' + ' subscript must yield a plain integer. If it is negative, ' + 'the\n' + " sequence's length is added to it. The resulting value must " + 'be a\n' + " nonnegative integer less than the sequence's length, and " + 'the\n' + ' sequence is asked to assign the assigned object to its ' + 'item with\n' + ' that index. If the index is out of range, "IndexError" is ' + 'raised\n' + ' (assignment to a subscripted sequence cannot add new items ' + 'to a\n' + ' list).\n' + '\n' + ' If the primary is a mapping object (such as a dictionary), ' + 'the\n' + " subscript must have a type compatible with the mapping's " + 'key type,\n' + ' and the mapping is then asked to create a key/datum pair ' + 'which maps\n' + ' the subscript to the assigned object. This can either ' + 'replace an\n' + ' existing key/value pair with the same key value, or insert ' + 'a new\n' + ' key/value pair (if no key with the same value existed).\n' + '\n' + '* If the target is a slicing: The primary expression in the\n' + ' reference is evaluated. It should yield a mutable ' + 'sequence object\n' + ' (such as a list). The assigned object should be a ' + 'sequence object\n' + ' of the same type. Next, the lower and upper bound ' + 'expressions are\n' + ' evaluated, insofar they are present; defaults are zero and ' + 'the\n' + " sequence's length. The bounds should evaluate to (small) " + 'integers.\n' + " If either bound is negative, the sequence's length is " + 'added to it.\n' + ' The resulting bounds are clipped to lie between zero and ' + 'the\n' + " sequence's length, inclusive. Finally, the sequence " + 'object is asked\n' + ' to replace the slice with the items of the assigned ' + 'sequence. The\n' + ' length of the slice may be different from the length of ' + 'the assigned\n' + ' sequence, thus changing the length of the target sequence, ' + 'if the\n' + ' object allows it.\n' + '\n' + '**CPython implementation detail:** In the current ' + 'implementation, the\n' + 'syntax for targets is taken to be the same as for ' + 'expressions, and\n' + 'invalid syntax is rejected during the code generation phase, ' + 'causing\n' + 'less detailed error messages.\n' + '\n' + 'WARNING: Although the definition of assignment implies that ' + 'overlaps\n' + 'between the left-hand side and the right-hand side are ' + "'safe' (for\n" + 'example "a, b = b, a" swaps two variables), overlaps ' + '*within* the\n' + 'collection of assigned-to variables are not safe! For ' + 'instance, the\n' + 'following program prints "[0, 2]":\n' + '\n' + ' x = [0, 1]\n' + ' i = 0\n' + ' i, x[i] = 1, 2\n' + ' print x\n' + '\n' + '\n' + 'Augmented assignment statements\n' + '===============================\n' + '\n' + 'Augmented assignment is the combination, in a single ' + 'statement, of a\n' + 'binary operation and an assignment statement:\n' + '\n' + ' augmented_assignment_stmt ::= augtarget augop ' + '(expression_list | yield_expression)\n' + ' augtarget ::= identifier | attributeref | ' + 'subscription | slicing\n' + ' augop ::= "+=" | "-=" | "*=" | "/=" | ' + '"//=" | "%=" | "**="\n' + ' | ">>=" | "<<=" | "&=" | "^=" | "|="\n' + '\n' + '(See section Primaries for the syntax definitions for the ' + 'last three\n' + 'symbols.)\n' + '\n' + 'An augmented assignment evaluates the target (which, unlike ' + 'normal\n' + 'assignment statements, cannot be an unpacking) and the ' + 'expression\n' + 'list, performs the binary operation specific to the type of ' + 'assignment\n' + 'on the two operands, and assigns the result to the original ' + 'target.\n' + 'The target is only evaluated once.\n' + '\n' + 'An augmented assignment expression like "x += 1" can be ' + 'rewritten as\n' + '"x = x + 1" to achieve a similar, but not exactly equal ' + 'effect. In the\n' + 'augmented version, "x" is only evaluated once. Also, when ' + 'possible,\n' + 'the actual operation is performed *in-place*, meaning that ' + 'rather than\n' + 'creating a new object and assigning that to the target, the ' + 'old object\n' + 'is modified instead.\n' + '\n' + 'With the exception of assigning to tuples and multiple ' + 'targets in a\n' + 'single statement, the assignment done by augmented ' + 'assignment\n' + 'statements is handled the same way as normal assignments. ' + 'Similarly,\n' + 'with the exception of the possible *in-place* behavior, the ' + 'binary\n' + 'operation performed by augmented assignment is the same as ' + 'the normal\n' + 'binary operations.\n' + '\n' + 'For targets which are attribute references, the same caveat ' + 'about\n' + 'class and instance attributes applies as for regular ' + 'assignments.\n', + 'atom-identifiers': '\n' + 'Identifiers (Names)\n' + '*******************\n' + '\n' + 'An identifier occurring as an atom is a name. See ' + 'section Identifiers\n' + 'and keywords for lexical definition and section Naming ' + 'and binding for\n' + 'documentation of naming and binding.\n' + '\n' + 'When the name is bound to an object, evaluation of the ' + 'atom yields\n' + 'that object. When a name is not bound, an attempt to ' + 'evaluate it\n' + 'raises a "NameError" exception.\n' + '\n' + '**Private name mangling:** When an identifier that ' + 'textually occurs in\n' + 'a class definition begins with two or more underscore ' + 'characters and\n' + 'does not end in two or more underscores, it is ' + 'considered a *private\n' + 'name* of that class. Private names are transformed to ' + 'a longer form\n' + 'before code is generated for them. The transformation ' + 'inserts the\n' + 'class name, with leading underscores removed and a ' + 'single underscore\n' + 'inserted, in front of the name. For example, the ' + 'identifier "__spam"\n' + 'occurring in a class named "Ham" will be transformed ' + 'to "_Ham__spam".\n' + 'This transformation is independent of the syntactical ' + 'context in which\n' + 'the identifier is used. If the transformed name is ' + 'extremely long\n' + '(longer than 255 characters), implementation defined ' + 'truncation may\n' + 'happen. If the class name consists only of ' + 'underscores, no\n' + 'transformation is done.\n', + 'atom-literals': '\n' + 'Literals\n' + '********\n' + '\n' + 'Python supports string literals and various numeric ' + 'literals:\n' + '\n' + ' literal ::= stringliteral | integer | longinteger\n' + ' | floatnumber | imagnumber\n' + '\n' + 'Evaluation of a literal yields an object of the given ' + 'type (string,\n' + 'integer, long integer, floating point number, complex ' + 'number) with the\n' + 'given value. The value may be approximated in the case ' + 'of floating\n' + 'point and imaginary (complex) literals. See section ' + 'Literals for\n' + 'details.\n' + '\n' + 'All literals correspond to immutable data types, and ' + 'hence the\n' + "object's identity is less important than its value. " + 'Multiple\n' + 'evaluations of literals with the same value (either the ' + 'same\n' + 'occurrence in the program text or a different occurrence) ' + 'may obtain\n' + 'the same object or a different object with the same ' + 'value.\n', + 'attribute-access': '\n' + 'Customizing attribute access\n' + '****************************\n' + '\n' + 'The following methods can be defined to customize the ' + 'meaning of\n' + 'attribute access (use of, assignment to, or deletion ' + 'of "x.name") for\n' + 'class instances.\n' + '\n' + 'object.__getattr__(self, name)\n' + '\n' + ' Called when an attribute lookup has not found the ' + 'attribute in the\n' + ' usual places (i.e. it is not an instance attribute ' + 'nor is it found\n' + ' in the class tree for "self"). "name" is the ' + 'attribute name. This\n' + ' method should return the (computed) attribute value ' + 'or raise an\n' + ' "AttributeError" exception.\n' + '\n' + ' Note that if the attribute is found through the ' + 'normal mechanism,\n' + ' "__getattr__()" is not called. (This is an ' + 'intentional asymmetry\n' + ' between "__getattr__()" and "__setattr__()".) This ' + 'is done both for\n' + ' efficiency reasons and because otherwise ' + '"__getattr__()" would have\n' + ' no way to access other attributes of the instance. ' + 'Note that at\n' + ' least for instance variables, you can fake total ' + 'control by not\n' + ' inserting any values in the instance attribute ' + 'dictionary (but\n' + ' instead inserting them in another object). See ' + 'the\n' + ' "__getattribute__()" method below for a way to ' + 'actually get total\n' + ' control in new-style classes.\n' + '\n' + 'object.__setattr__(self, name, value)\n' + '\n' + ' Called when an attribute assignment is attempted. ' + 'This is called\n' + ' instead of the normal mechanism (i.e. store the ' + 'value in the\n' + ' instance dictionary). *name* is the attribute ' + 'name, *value* is the\n' + ' value to be assigned to it.\n' + '\n' + ' If "__setattr__()" wants to assign to an instance ' + 'attribute, it\n' + ' should not simply execute "self.name = value" --- ' + 'this would cause\n' + ' a recursive call to itself. Instead, it should ' + 'insert the value in\n' + ' the dictionary of instance attributes, e.g., ' + '"self.__dict__[name] =\n' + ' value". For new-style classes, rather than ' + 'accessing the instance\n' + ' dictionary, it should call the base class method ' + 'with the same\n' + ' name, for example, "object.__setattr__(self, name, ' + 'value)".\n' + '\n' + 'object.__delattr__(self, name)\n' + '\n' + ' Like "__setattr__()" but for attribute deletion ' + 'instead of\n' + ' assignment. This should only be implemented if ' + '"del obj.name" is\n' + ' meaningful for the object.\n' + '\n' + '\n' + 'More attribute access for new-style classes\n' + '===========================================\n' + '\n' + 'The following methods only apply to new-style ' + 'classes.\n' + '\n' + 'object.__getattribute__(self, name)\n' + '\n' + ' Called unconditionally to implement attribute ' + 'accesses for\n' + ' instances of the class. If the class also defines ' + '"__getattr__()",\n' + ' the latter will not be called unless ' + '"__getattribute__()" either\n' + ' calls it explicitly or raises an "AttributeError". ' + 'This method\n' + ' should return the (computed) attribute value or ' + 'raise an\n' + ' "AttributeError" exception. In order to avoid ' + 'infinite recursion in\n' + ' this method, its implementation should always call ' + 'the base class\n' + ' method with the same name to access any attributes ' + 'it needs, for\n' + ' example, "object.__getattribute__(self, name)".\n' + '\n' + ' Note: This method may still be bypassed when ' + 'looking up special\n' + ' methods as the result of implicit invocation via ' + 'language syntax\n' + ' or built-in functions. See Special method lookup ' + 'for new-style\n' + ' classes.\n' + '\n' + '\n' + 'Implementing Descriptors\n' + '========================\n' + '\n' + 'The following methods only apply when an instance of ' + 'the class\n' + 'containing the method (a so-called *descriptor* class) ' + 'appears in an\n' + '*owner* class (the descriptor must be in either the ' + "owner's class\n" + 'dictionary or in the class dictionary for one of its ' + 'parents). In the\n' + 'examples below, "the attribute" refers to the ' + 'attribute whose name is\n' + "the key of the property in the owner class' " + '"__dict__".\n' + '\n' + 'object.__get__(self, instance, owner)\n' + '\n' + ' Called to get the attribute of the owner class ' + '(class attribute\n' + ' access) or of an instance of that class (instance ' + 'attribute\n' + ' access). *owner* is always the owner class, while ' + '*instance* is the\n' + ' instance that the attribute was accessed through, ' + 'or "None" when\n' + ' the attribute is accessed through the *owner*. ' + 'This method should\n' + ' return the (computed) attribute value or raise an ' + '"AttributeError"\n' + ' exception.\n' + '\n' + 'object.__set__(self, instance, value)\n' + '\n' + ' Called to set the attribute on an instance ' + '*instance* of the owner\n' + ' class to a new value, *value*.\n' + '\n' + 'object.__delete__(self, instance)\n' + '\n' + ' Called to delete the attribute on an instance ' + '*instance* of the\n' + ' owner class.\n' + '\n' + '\n' + 'Invoking Descriptors\n' + '====================\n' + '\n' + 'In general, a descriptor is an object attribute with ' + '"binding\n' + 'behavior", one whose attribute access has been ' + 'overridden by methods\n' + 'in the descriptor protocol: "__get__()", "__set__()", ' + 'and\n' + '"__delete__()". If any of those methods are defined ' + 'for an object, it\n' + 'is said to be a descriptor.\n' + '\n' + 'The default behavior for attribute access is to get, ' + 'set, or delete\n' + "the attribute from an object's dictionary. For " + 'instance, "a.x" has a\n' + 'lookup chain starting with "a.__dict__[\'x\']", then\n' + '"type(a).__dict__[\'x\']", and continuing through the ' + 'base classes of\n' + '"type(a)" excluding metaclasses.\n' + '\n' + 'However, if the looked-up value is an object defining ' + 'one of the\n' + 'descriptor methods, then Python may override the ' + 'default behavior and\n' + 'invoke the descriptor method instead. Where this ' + 'occurs in the\n' + 'precedence chain depends on which descriptor methods ' + 'were defined and\n' + 'how they were called. Note that descriptors are only ' + 'invoked for new\n' + 'style objects or classes (ones that subclass ' + '"object()" or "type()").\n' + '\n' + 'The starting point for descriptor invocation is a ' + 'binding, "a.x". How\n' + 'the arguments are assembled depends on "a":\n' + '\n' + 'Direct Call\n' + ' The simplest and least common call is when user ' + 'code directly\n' + ' invokes a descriptor method: "x.__get__(a)".\n' + '\n' + 'Instance Binding\n' + ' If binding to a new-style object instance, "a.x" is ' + 'transformed\n' + ' into the call: "type(a).__dict__[\'x\'].__get__(a, ' + 'type(a))".\n' + '\n' + 'Class Binding\n' + ' If binding to a new-style class, "A.x" is ' + 'transformed into the\n' + ' call: "A.__dict__[\'x\'].__get__(None, A)".\n' + '\n' + 'Super Binding\n' + ' If "a" is an instance of "super", then the binding ' + '"super(B,\n' + ' obj).m()" searches "obj.__class__.__mro__" for the ' + 'base class "A"\n' + ' immediately preceding "B" and then invokes the ' + 'descriptor with the\n' + ' call: "A.__dict__[\'m\'].__get__(obj, ' + 'obj.__class__)".\n' + '\n' + 'For instance bindings, the precedence of descriptor ' + 'invocation depends\n' + 'on the which descriptor methods are defined. A ' + 'descriptor can define\n' + 'any combination of "__get__()", "__set__()" and ' + '"__delete__()". If it\n' + 'does not define "__get__()", then accessing the ' + 'attribute will return\n' + 'the descriptor object itself unless there is a value ' + "in the object's\n" + 'instance dictionary. If the descriptor defines ' + '"__set__()" and/or\n' + '"__delete__()", it is a data descriptor; if it defines ' + 'neither, it is\n' + 'a non-data descriptor. Normally, data descriptors ' + 'define both\n' + '"__get__()" and "__set__()", while non-data ' + 'descriptors have just the\n' + '"__get__()" method. Data descriptors with "__set__()" ' + 'and "__get__()"\n' + 'defined always override a redefinition in an instance ' + 'dictionary. In\n' + 'contrast, non-data descriptors can be overridden by ' + 'instances.\n' + '\n' + 'Python methods (including "staticmethod()" and ' + '"classmethod()") are\n' + 'implemented as non-data descriptors. Accordingly, ' + 'instances can\n' + 'redefine and override methods. This allows individual ' + 'instances to\n' + 'acquire behaviors that differ from other instances of ' + 'the same class.\n' + '\n' + 'The "property()" function is implemented as a data ' + 'descriptor.\n' + 'Accordingly, instances cannot override the behavior of ' + 'a property.\n' + '\n' + '\n' + '__slots__\n' + '=========\n' + '\n' + 'By default, instances of both old and new-style ' + 'classes have a\n' + 'dictionary for attribute storage. This wastes space ' + 'for objects\n' + 'having very few instance variables. The space ' + 'consumption can become\n' + 'acute when creating large numbers of instances.\n' + '\n' + 'The default can be overridden by defining *__slots__* ' + 'in a new-style\n' + 'class definition. The *__slots__* declaration takes a ' + 'sequence of\n' + 'instance variables and reserves just enough space in ' + 'each instance to\n' + 'hold a value for each variable. Space is saved ' + 'because *__dict__* is\n' + 'not created for each instance.\n' + '\n' + '__slots__\n' + '\n' + ' This class variable can be assigned a string, ' + 'iterable, or sequence\n' + ' of strings with variable names used by instances. ' + 'If defined in a\n' + ' new-style class, *__slots__* reserves space for the ' + 'declared\n' + ' variables and prevents the automatic creation of ' + '*__dict__* and\n' + ' *__weakref__* for each instance.\n' + '\n' + ' New in version 2.2.\n' + '\n' + 'Notes on using *__slots__*\n' + '\n' + '* When inheriting from a class without *__slots__*, ' + 'the *__dict__*\n' + ' attribute of that class will always be accessible, ' + 'so a *__slots__*\n' + ' definition in the subclass is meaningless.\n' + '\n' + '* Without a *__dict__* variable, instances cannot be ' + 'assigned new\n' + ' variables not listed in the *__slots__* definition. ' + 'Attempts to\n' + ' assign to an unlisted variable name raises ' + '"AttributeError". If\n' + ' dynamic assignment of new variables is desired, then ' + 'add\n' + ' "\'__dict__\'" to the sequence of strings in the ' + '*__slots__*\n' + ' declaration.\n' + '\n' + ' Changed in version 2.3: Previously, adding ' + '"\'__dict__\'" to the\n' + ' *__slots__* declaration would not enable the ' + 'assignment of new\n' + ' attributes not specifically listed in the sequence ' + 'of instance\n' + ' variable names.\n' + '\n' + '* Without a *__weakref__* variable for each instance, ' + 'classes\n' + ' defining *__slots__* do not support weak references ' + 'to its\n' + ' instances. If weak reference support is needed, then ' + 'add\n' + ' "\'__weakref__\'" to the sequence of strings in the ' + '*__slots__*\n' + ' declaration.\n' + '\n' + ' Changed in version 2.3: Previously, adding ' + '"\'__weakref__\'" to the\n' + ' *__slots__* declaration would not enable support for ' + 'weak\n' + ' references.\n' + '\n' + '* *__slots__* are implemented at the class level by ' + 'creating\n' + ' descriptors (Implementing Descriptors) for each ' + 'variable name. As a\n' + ' result, class attributes cannot be used to set ' + 'default values for\n' + ' instance variables defined by *__slots__*; ' + 'otherwise, the class\n' + ' attribute would overwrite the descriptor ' + 'assignment.\n' + '\n' + '* The action of a *__slots__* declaration is limited ' + 'to the class\n' + ' where it is defined. As a result, subclasses will ' + 'have a *__dict__*\n' + ' unless they also define *__slots__* (which must only ' + 'contain names\n' + ' of any *additional* slots).\n' + '\n' + '* If a class defines a slot also defined in a base ' + 'class, the\n' + ' instance variable defined by the base class slot is ' + 'inaccessible\n' + ' (except by retrieving its descriptor directly from ' + 'the base class).\n' + ' This renders the meaning of the program undefined. ' + 'In the future, a\n' + ' check may be added to prevent this.\n' + '\n' + '* Nonempty *__slots__* does not work for classes ' + 'derived from\n' + ' "variable-length" built-in types such as "long", ' + '"str" and "tuple".\n' + '\n' + '* Any non-string iterable may be assigned to ' + '*__slots__*. Mappings\n' + ' may also be used; however, in the future, special ' + 'meaning may be\n' + ' assigned to the values corresponding to each key.\n' + '\n' + '* *__class__* assignment works only if both classes ' + 'have the same\n' + ' *__slots__*.\n' + '\n' + ' Changed in version 2.6: Previously, *__class__* ' + 'assignment raised an\n' + ' error if either new or old class had *__slots__*.\n', + 'attribute-references': '\n' + 'Attribute references\n' + '********************\n' + '\n' + 'An attribute reference is a primary followed by a ' + 'period and a name:\n' + '\n' + ' attributeref ::= primary "." identifier\n' + '\n' + 'The primary must evaluate to an object of a type ' + 'that supports\n' + 'attribute references, e.g., a module, list, or an ' + 'instance. This\n' + 'object is then asked to produce the attribute ' + 'whose name is the\n' + 'identifier. If this attribute is not available, ' + 'the exception\n' + '"AttributeError" is raised. Otherwise, the type ' + 'and value of the\n' + 'object produced is determined by the object. ' + 'Multiple evaluations of\n' + 'the same attribute reference may yield different ' + 'objects.\n', + 'augassign': '\n' + 'Augmented assignment statements\n' + '*******************************\n' + '\n' + 'Augmented assignment is the combination, in a single ' + 'statement, of a\n' + 'binary operation and an assignment statement:\n' + '\n' + ' augmented_assignment_stmt ::= augtarget augop ' + '(expression_list | yield_expression)\n' + ' augtarget ::= identifier | attributeref | ' + 'subscription | slicing\n' + ' augop ::= "+=" | "-=" | "*=" | "/=" | ' + '"//=" | "%=" | "**="\n' + ' | ">>=" | "<<=" | "&=" | "^=" | "|="\n' + '\n' + '(See section Primaries for the syntax definitions for the ' + 'last three\n' + 'symbols.)\n' + '\n' + 'An augmented assignment evaluates the target (which, unlike ' + 'normal\n' + 'assignment statements, cannot be an unpacking) and the ' + 'expression\n' + 'list, performs the binary operation specific to the type of ' + 'assignment\n' + 'on the two operands, and assigns the result to the original ' + 'target.\n' + 'The target is only evaluated once.\n' + '\n' + 'An augmented assignment expression like "x += 1" can be ' + 'rewritten as\n' + '"x = x + 1" to achieve a similar, but not exactly equal ' + 'effect. In the\n' + 'augmented version, "x" is only evaluated once. Also, when ' + 'possible,\n' + 'the actual operation is performed *in-place*, meaning that ' + 'rather than\n' + 'creating a new object and assigning that to the target, the ' + 'old object\n' + 'is modified instead.\n' + '\n' + 'With the exception of assigning to tuples and multiple ' + 'targets in a\n' + 'single statement, the assignment done by augmented ' + 'assignment\n' + 'statements is handled the same way as normal assignments. ' + 'Similarly,\n' + 'with the exception of the possible *in-place* behavior, the ' + 'binary\n' + 'operation performed by augmented assignment is the same as ' + 'the normal\n' + 'binary operations.\n' + '\n' + 'For targets which are attribute references, the same caveat ' + 'about\n' + 'class and instance attributes applies as for regular ' + 'assignments.\n', + 'binary': '\n' + 'Binary arithmetic operations\n' + '****************************\n' + '\n' + 'The binary arithmetic operations have the conventional priority\n' + 'levels. Note that some of these operations also apply to ' + 'certain non-\n' + 'numeric types. Apart from the power operator, there are only ' + 'two\n' + 'levels, one for multiplicative operators and one for additive\n' + 'operators:\n' + '\n' + ' m_expr ::= u_expr | m_expr "*" u_expr | m_expr "//" u_expr | ' + 'm_expr "/" u_expr\n' + ' | m_expr "%" u_expr\n' + ' a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n' + '\n' + 'The "*" (multiplication) operator yields the product of its ' + 'arguments.\n' + 'The arguments must either both be numbers, or one argument must ' + 'be an\n' + 'integer (plain or long) and the other must be a sequence. In ' + 'the\n' + 'former case, the numbers are converted to a common type and ' + 'then\n' + 'multiplied together. In the latter case, sequence repetition ' + 'is\n' + 'performed; a negative repetition factor yields an empty ' + 'sequence.\n' + '\n' + 'The "/" (division) and "//" (floor division) operators yield ' + 'the\n' + 'quotient of their arguments. The numeric arguments are first\n' + 'converted to a common type. Plain or long integer division ' + 'yields an\n' + 'integer of the same type; the result is that of mathematical ' + 'division\n' + "with the 'floor' function applied to the result. Division by " + 'zero\n' + 'raises the "ZeroDivisionError" exception.\n' + '\n' + 'The "%" (modulo) operator yields the remainder from the division ' + 'of\n' + 'the first argument by the second. The numeric arguments are ' + 'first\n' + 'converted to a common type. A zero right argument raises the\n' + '"ZeroDivisionError" exception. The arguments may be floating ' + 'point\n' + 'numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals ' + '"4*0.7 +\n' + '0.34".) The modulo operator always yields a result with the ' + 'same sign\n' + 'as its second operand (or zero); the absolute value of the ' + 'result is\n' + 'strictly smaller than the absolute value of the second operand ' + '[2].\n' + '\n' + 'The integer division and modulo operators are connected by the\n' + 'following identity: "x == (x/y)*y + (x%y)". Integer division ' + 'and\n' + 'modulo are also connected with the built-in function ' + '"divmod()":\n' + '"divmod(x, y) == (x/y, x%y)". These identities don\'t hold for\n' + 'floating point numbers; there similar identities hold ' + 'approximately\n' + 'where "x/y" is replaced by "floor(x/y)" or "floor(x/y) - 1" ' + '[3].\n' + '\n' + 'In addition to performing the modulo operation on numbers, the ' + '"%"\n' + 'operator is also overloaded by string and unicode objects to ' + 'perform\n' + 'string formatting (also known as interpolation). The syntax for ' + 'string\n' + 'formatting is described in the Python Library Reference, ' + 'section\n' + 'String Formatting Operations.\n' + '\n' + 'Deprecated since version 2.3: The floor division operator, the ' + 'modulo\n' + 'operator, and the "divmod()" function are no longer defined for\n' + 'complex numbers. Instead, convert to a floating point number ' + 'using\n' + 'the "abs()" function if appropriate.\n' + '\n' + 'The "+" (addition) operator yields the sum of its arguments. ' + 'The\n' + 'arguments must either both be numbers or both sequences of the ' + 'same\n' + 'type. In the former case, the numbers are converted to a common ' + 'type\n' + 'and then added together. In the latter case, the sequences are\n' + 'concatenated.\n' + '\n' + 'The "-" (subtraction) operator yields the difference of its ' + 'arguments.\n' + 'The numeric arguments are first converted to a common type.\n', + 'bitwise': '\n' + 'Binary bitwise operations\n' + '*************************\n' + '\n' + 'Each of the three bitwise operations has a different priority ' + 'level:\n' + '\n' + ' and_expr ::= shift_expr | and_expr "&" shift_expr\n' + ' xor_expr ::= and_expr | xor_expr "^" and_expr\n' + ' or_expr ::= xor_expr | or_expr "|" xor_expr\n' + '\n' + 'The "&" operator yields the bitwise AND of its arguments, which ' + 'must\n' + 'be plain or long integers. The arguments are converted to a ' + 'common\n' + 'type.\n' + '\n' + 'The "^" operator yields the bitwise XOR (exclusive OR) of its\n' + 'arguments, which must be plain or long integers. The arguments ' + 'are\n' + 'converted to a common type.\n' + '\n' + 'The "|" operator yields the bitwise (inclusive) OR of its ' + 'arguments,\n' + 'which must be plain or long integers. The arguments are ' + 'converted to\n' + 'a common type.\n', + 'bltin-code-objects': '\n' + 'Code Objects\n' + '************\n' + '\n' + 'Code objects are used by the implementation to ' + 'represent "pseudo-\n' + 'compiled" executable Python code such as a function ' + 'body. They differ\n' + "from function objects because they don't contain a " + 'reference to their\n' + 'global execution environment. Code objects are ' + 'returned by the built-\n' + 'in "compile()" function and can be extracted from ' + 'function objects\n' + 'through their "func_code" attribute. See also the ' + '"code" module.\n' + '\n' + 'A code object can be executed or evaluated by ' + 'passing it (instead of a\n' + 'source string) to the "exec" statement or the ' + 'built-in "eval()"\n' + 'function.\n' + '\n' + 'See The standard type hierarchy for more ' + 'information.\n', + 'bltin-ellipsis-object': '\n' + 'The Ellipsis Object\n' + '*******************\n' + '\n' + 'This object is used by extended slice notation ' + '(see Slicings). It\n' + 'supports no special operations. There is exactly ' + 'one ellipsis object,\n' + 'named "Ellipsis" (a built-in name).\n' + '\n' + 'It is written as "Ellipsis". When in a ' + 'subscript, it can also be\n' + 'written as "...", for example "seq[...]".\n', + 'bltin-null-object': '\n' + 'The Null Object\n' + '***************\n' + '\n' + "This object is returned by functions that don't " + 'explicitly return a\n' + 'value. It supports no special operations. There is ' + 'exactly one null\n' + 'object, named "None" (a built-in name).\n' + '\n' + 'It is written as "None".\n', + 'bltin-type-objects': '\n' + 'Type Objects\n' + '************\n' + '\n' + 'Type objects represent the various object types. An ' + "object's type is\n" + 'accessed by the built-in function "type()". There ' + 'are no special\n' + 'operations on types. The standard module "types" ' + 'defines names for\n' + 'all standard built-in types.\n' + '\n' + 'Types are written like this: "".\n', + 'booleans': '\n' + 'Boolean operations\n' + '******************\n' + '\n' + ' or_test ::= and_test | or_test "or" and_test\n' + ' and_test ::= not_test | and_test "and" not_test\n' + ' not_test ::= comparison | "not" not_test\n' + '\n' + 'In the context of Boolean operations, and also when ' + 'expressions are\n' + 'used by control flow statements, the following values are ' + 'interpreted\n' + 'as false: "False", "None", numeric zero of all types, and ' + 'empty\n' + 'strings and containers (including strings, tuples, lists,\n' + 'dictionaries, sets and frozensets). All other values are ' + 'interpreted\n' + 'as true. (See the "__nonzero__()" special method for a way to ' + 'change\n' + 'this.)\n' + '\n' + 'The operator "not" yields "True" if its argument is false, ' + '"False"\n' + 'otherwise.\n' + '\n' + 'The expression "x and y" first evaluates *x*; if *x* is false, ' + 'its\n' + 'value is returned; otherwise, *y* is evaluated and the ' + 'resulting value\n' + 'is returned.\n' + '\n' + 'The expression "x or y" first evaluates *x*; if *x* is true, ' + 'its value\n' + 'is returned; otherwise, *y* is evaluated and the resulting ' + 'value is\n' + 'returned.\n' + '\n' + '(Note that neither "and" nor "or" restrict the value and type ' + 'they\n' + 'return to "False" and "True", but rather return the last ' + 'evaluated\n' + 'argument. This is sometimes useful, e.g., if "s" is a string ' + 'that\n' + 'should be replaced by a default value if it is empty, the ' + 'expression\n' + '"s or \'foo\'" yields the desired value. Because "not" has to ' + 'invent a\n' + 'value anyway, it does not bother to return a value of the same ' + 'type as\n' + 'its argument, so e.g., "not \'foo\'" yields "False", not ' + '"\'\'".)\n', + 'break': '\n' + 'The "break" statement\n' + '*********************\n' + '\n' + ' break_stmt ::= "break"\n' + '\n' + '"break" may only occur syntactically nested in a "for" or ' + '"while"\n' + 'loop, but not nested in a function or class definition within ' + 'that\n' + 'loop.\n' + '\n' + 'It terminates the nearest enclosing loop, skipping the optional ' + '"else"\n' + 'clause if the loop has one.\n' + '\n' + 'If a "for" loop is terminated by "break", the loop control ' + 'target\n' + 'keeps its current value.\n' + '\n' + 'When "break" passes control out of a "try" statement with a ' + '"finally"\n' + 'clause, that "finally" clause is executed before really leaving ' + 'the\n' + 'loop.\n', + 'callable-types': '\n' + 'Emulating callable objects\n' + '**************************\n' + '\n' + 'object.__call__(self[, args...])\n' + '\n' + ' Called when the instance is "called" as a function; ' + 'if this method\n' + ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' + ' "x.__call__(arg1, arg2, ...)".\n', + 'calls': '\n' + 'Calls\n' + '*****\n' + '\n' + 'A call calls a callable object (e.g., a *function*) with a ' + 'possibly\n' + 'empty series of *arguments*:\n' + '\n' + ' call ::= primary "(" [argument_list [","]\n' + ' | expression genexpr_for] ")"\n' + ' argument_list ::= positional_arguments ["," ' + 'keyword_arguments]\n' + ' ["," "*" expression] ["," ' + 'keyword_arguments]\n' + ' ["," "**" expression]\n' + ' | keyword_arguments ["," "*" expression]\n' + ' ["," "**" expression]\n' + ' | "*" expression ["," keyword_arguments] ' + '["," "**" expression]\n' + ' | "**" expression\n' + ' positional_arguments ::= expression ("," expression)*\n' + ' keyword_arguments ::= keyword_item ("," keyword_item)*\n' + ' keyword_item ::= identifier "=" expression\n' + '\n' + 'A trailing comma may be present after the positional and keyword\n' + 'arguments but does not affect the semantics.\n' + '\n' + 'The primary must evaluate to a callable object (user-defined\n' + 'functions, built-in functions, methods of built-in objects, ' + 'class\n' + 'objects, methods of class instances, and certain class instances\n' + 'themselves are callable; extensions may define additional ' + 'callable\n' + 'object types). All argument expressions are evaluated before the ' + 'call\n' + 'is attempted. Please refer to section Function definitions for ' + 'the\n' + 'syntax of formal *parameter* lists.\n' + '\n' + 'If keyword arguments are present, they are first converted to\n' + 'positional arguments, as follows. First, a list of unfilled ' + 'slots is\n' + 'created for the formal parameters. If there are N positional\n' + 'arguments, they are placed in the first N slots. Next, for each\n' + 'keyword argument, the identifier is used to determine the\n' + 'corresponding slot (if the identifier is the same as the first ' + 'formal\n' + 'parameter name, the first slot is used, and so on). If the slot ' + 'is\n' + 'already filled, a "TypeError" exception is raised. Otherwise, ' + 'the\n' + 'value of the argument is placed in the slot, filling it (even if ' + 'the\n' + 'expression is "None", it fills the slot). When all arguments ' + 'have\n' + 'been processed, the slots that are still unfilled are filled with ' + 'the\n' + 'corresponding default value from the function definition. ' + '(Default\n' + 'values are calculated, once, when the function is defined; thus, ' + 'a\n' + 'mutable object such as a list or dictionary used as default value ' + 'will\n' + "be shared by all calls that don't specify an argument value for " + 'the\n' + 'corresponding slot; this should usually be avoided.) If there ' + 'are any\n' + 'unfilled slots for which no default value is specified, a ' + '"TypeError"\n' + 'exception is raised. Otherwise, the list of filled slots is used ' + 'as\n' + 'the argument list for the call.\n' + '\n' + '**CPython implementation detail:** An implementation may provide\n' + 'built-in functions whose positional parameters do not have names, ' + 'even\n' + "if they are 'named' for the purpose of documentation, and which\n" + 'therefore cannot be supplied by keyword. In CPython, this is the ' + 'case\n' + 'for functions implemented in C that use "PyArg_ParseTuple()" to ' + 'parse\n' + 'their arguments.\n' + '\n' + 'If there are more positional arguments than there are formal ' + 'parameter\n' + 'slots, a "TypeError" exception is raised, unless a formal ' + 'parameter\n' + 'using the syntax "*identifier" is present; in this case, that ' + 'formal\n' + 'parameter receives a tuple containing the excess positional ' + 'arguments\n' + '(or an empty tuple if there were no excess positional ' + 'arguments).\n' + '\n' + 'If any keyword argument does not correspond to a formal ' + 'parameter\n' + 'name, a "TypeError" exception is raised, unless a formal ' + 'parameter\n' + 'using the syntax "**identifier" is present; in this case, that ' + 'formal\n' + 'parameter receives a dictionary containing the excess keyword\n' + 'arguments (using the keywords as keys and the argument values as\n' + 'corresponding values), or a (new) empty dictionary if there were ' + 'no\n' + 'excess keyword arguments.\n' + '\n' + 'If the syntax "*expression" appears in the function call, ' + '"expression"\n' + 'must evaluate to an iterable. Elements from this iterable are ' + 'treated\n' + 'as if they were additional positional arguments; if there are\n' + 'positional arguments *x1*, ..., *xN*, and "expression" evaluates ' + 'to a\n' + 'sequence *y1*, ..., *yM*, this is equivalent to a call with M+N\n' + 'positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n' + '\n' + 'A consequence of this is that although the "*expression" syntax ' + 'may\n' + 'appear *after* some keyword arguments, it is processed *before* ' + 'the\n' + 'keyword arguments (and the "**expression" argument, if any -- ' + 'see\n' + 'below). So:\n' + '\n' + ' >>> def f(a, b):\n' + ' ... print a, b\n' + ' ...\n' + ' >>> f(b=1, *(2,))\n' + ' 2 1\n' + ' >>> f(a=1, *(2,))\n' + ' Traceback (most recent call last):\n' + ' File "", line 1, in ?\n' + " TypeError: f() got multiple values for keyword argument 'a'\n" + ' >>> f(1, *(2,))\n' + ' 1 2\n' + '\n' + 'It is unusual for both keyword arguments and the "*expression" ' + 'syntax\n' + 'to be used in the same call, so in practice this confusion does ' + 'not\n' + 'arise.\n' + '\n' + 'If the syntax "**expression" appears in the function call,\n' + '"expression" must evaluate to a mapping, the contents of which ' + 'are\n' + 'treated as additional keyword arguments. In the case of a ' + 'keyword\n' + 'appearing in both "expression" and as an explicit keyword ' + 'argument, a\n' + '"TypeError" exception is raised.\n' + '\n' + 'Formal parameters using the syntax "*identifier" or ' + '"**identifier"\n' + 'cannot be used as positional argument slots or as keyword ' + 'argument\n' + 'names. Formal parameters using the syntax "(sublist)" cannot be ' + 'used\n' + 'as keyword argument names; the outermost sublist corresponds to ' + 'a\n' + 'single unnamed argument slot, and the argument value is assigned ' + 'to\n' + 'the sublist using the usual tuple assignment rules after all ' + 'other\n' + 'parameter processing is done.\n' + '\n' + 'A call always returns some value, possibly "None", unless it ' + 'raises an\n' + 'exception. How this value is computed depends on the type of ' + 'the\n' + 'callable object.\n' + '\n' + 'If it is---\n' + '\n' + 'a user-defined function:\n' + ' The code block for the function is executed, passing it the\n' + ' argument list. The first thing the code block will do is bind ' + 'the\n' + ' formal parameters to the arguments; this is described in ' + 'section\n' + ' Function definitions. When the code block executes a ' + '"return"\n' + ' statement, this specifies the return value of the function ' + 'call.\n' + '\n' + 'a built-in function or method:\n' + ' The result is up to the interpreter; see Built-in Functions ' + 'for the\n' + ' descriptions of built-in functions and methods.\n' + '\n' + 'a class object:\n' + ' A new instance of that class is returned.\n' + '\n' + 'a class instance method:\n' + ' The corresponding user-defined function is called, with an ' + 'argument\n' + ' list that is one longer than the argument list of the call: ' + 'the\n' + ' instance becomes the first argument.\n' + '\n' + 'a class instance:\n' + ' The class must define a "__call__()" method; the effect is ' + 'then the\n' + ' same as if that method was called.\n', + 'class': '\n' + 'Class definitions\n' + '*****************\n' + '\n' + 'A class definition defines a class object (see section The ' + 'standard\n' + 'type hierarchy):\n' + '\n' + ' classdef ::= "class" classname [inheritance] ":" suite\n' + ' inheritance ::= "(" [expression_list] ")"\n' + ' classname ::= identifier\n' + '\n' + 'A class definition is an executable statement. It first ' + 'evaluates the\n' + 'inheritance list, if present. Each item in the inheritance list\n' + 'should evaluate to a class object or class type which allows\n' + "subclassing. The class's suite is then executed in a new " + 'execution\n' + 'frame (see section Naming and binding), using a newly created ' + 'local\n' + 'namespace and the original global namespace. (Usually, the suite\n' + "contains only function definitions.) When the class's suite " + 'finishes\n' + 'execution, its execution frame is discarded but its local ' + 'namespace is\n' + 'saved. [4] A class object is then created using the inheritance ' + 'list\n' + 'for the base classes and the saved local namespace for the ' + 'attribute\n' + 'dictionary. The class name is bound to this class object in the\n' + 'original local namespace.\n' + '\n' + "**Programmer's note:** Variables defined in the class definition " + 'are\n' + 'class variables; they are shared by all instances. To create ' + 'instance\n' + 'variables, they can be set in a method with "self.name = value". ' + 'Both\n' + 'class and instance variables are accessible through the notation\n' + '""self.name"", and an instance variable hides a class variable ' + 'with\n' + 'the same name when accessed in this way. Class variables can be ' + 'used\n' + 'as defaults for instance variables, but using mutable values ' + 'there can\n' + 'lead to unexpected results. For *new-style class*es, descriptors ' + 'can\n' + 'be used to create instance variables with different ' + 'implementation\n' + 'details.\n' + '\n' + 'Class definitions, like function definitions, may be wrapped by ' + 'one or\n' + 'more *decorator* expressions. The evaluation rules for the ' + 'decorator\n' + 'expressions are the same as for functions. The result must be a ' + 'class\n' + 'object, which is then bound to the class name.\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] The exception is propagated to the invocation stack unless\n' + ' there is a "finally" clause which happens to raise another\n' + ' exception. That new exception causes the old one to be lost.\n' + '\n' + '[2] Currently, control "flows off the end" except in the case of\n' + ' an exception or the execution of a "return", "continue", or\n' + ' "break" statement.\n' + '\n' + '[3] A string literal appearing as the first statement in the\n' + ' function body is transformed into the function\'s "__doc__"\n' + " attribute and therefore the function's *docstring*.\n" + '\n' + '[4] A string literal appearing as the first statement in the ' + 'class\n' + ' body is transformed into the namespace\'s "__doc__" item and\n' + " therefore the class's *docstring*.\n", + 'comparisons': '\n' + 'Comparisons\n' + '***********\n' + '\n' + 'Unlike C, all comparison operations in Python have the same ' + 'priority,\n' + 'which is lower than that of any arithmetic, shifting or ' + 'bitwise\n' + 'operation. Also unlike C, expressions like "a < b < c" ' + 'have the\n' + 'interpretation that is conventional in mathematics:\n' + '\n' + ' comparison ::= or_expr ( comp_operator or_expr )*\n' + ' comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" ' + '| "!="\n' + ' | "is" ["not"] | ["not"] "in"\n' + '\n' + 'Comparisons yield boolean values: "True" or "False".\n' + '\n' + 'Comparisons can be chained arbitrarily, e.g., "x < y <= z" ' + 'is\n' + 'equivalent to "x < y and y <= z", except that "y" is ' + 'evaluated only\n' + 'once (but in both cases "z" is not evaluated at all when "x ' + '< y" is\n' + 'found to be false).\n' + '\n' + 'Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions ' + 'and *op1*,\n' + '*op2*, ..., *opN* are comparison operators, then "a op1 b ' + 'op2 c ... y\n' + 'opN z" is equivalent to "a op1 b and b op2 c and ... y opN ' + 'z", except\n' + 'that each expression is evaluated at most once.\n' + '\n' + 'Note that "a op1 b op2 c" doesn\'t imply any kind of ' + 'comparison between\n' + '*a* and *c*, so that, e.g., "x < y > z" is perfectly legal ' + '(though\n' + 'perhaps not pretty).\n' + '\n' + 'The forms "<>" and "!=" are equivalent; for consistency ' + 'with C, "!="\n' + 'is preferred; where "!=" is mentioned below "<>" is also ' + 'accepted.\n' + 'The "<>" spelling is considered obsolescent.\n' + '\n' + 'The operators "<", ">", "==", ">=", "<=", and "!=" compare ' + 'the values\n' + 'of two objects. The objects need not have the same type. ' + 'If both are\n' + 'numbers, they are converted to a common type. Otherwise, ' + 'objects of\n' + 'different types *always* compare unequal, and are ordered ' + 'consistently\n' + 'but arbitrarily. You can control comparison behavior of ' + 'objects of\n' + 'non-built-in types by defining a "__cmp__" method or rich ' + 'comparison\n' + 'methods like "__gt__", described in section Special method ' + 'names.\n' + '\n' + '(This unusual definition of comparison was used to simplify ' + 'the\n' + 'definition of operations like sorting and the "in" and "not ' + 'in"\n' + 'operators. In the future, the comparison rules for objects ' + 'of\n' + 'different types are likely to change.)\n' + '\n' + 'Comparison of objects of the same type depends on the ' + 'type:\n' + '\n' + '* Numbers are compared arithmetically.\n' + '\n' + '* Strings are compared lexicographically using the numeric\n' + ' equivalents (the result of the built-in function "ord()") ' + 'of their\n' + ' characters. Unicode and 8-bit strings are fully ' + 'interoperable in\n' + ' this behavior. [4]\n' + '\n' + '* Tuples and lists are compared lexicographically using ' + 'comparison\n' + ' of corresponding elements. This means that to compare ' + 'equal, each\n' + ' element must compare equal and the two sequences must be ' + 'of the same\n' + ' type and have the same length.\n' + '\n' + ' If not equal, the sequences are ordered the same as their ' + 'first\n' + ' differing elements. For example, "cmp([1,2,x], [1,2,y])" ' + 'returns\n' + ' the same as "cmp(x,y)". If the corresponding element ' + 'does not\n' + ' exist, the shorter sequence is ordered first (for ' + 'example, "[1,2] <\n' + ' [1,2,3]").\n' + '\n' + '* Mappings (dictionaries) compare equal if and only if ' + 'their sorted\n' + ' (key, value) lists compare equal. [5] Outcomes other than ' + 'equality\n' + ' are resolved consistently, but are not otherwise defined. ' + '[6]\n' + '\n' + '* Most other objects of built-in types compare unequal ' + 'unless they\n' + ' are the same object; the choice whether one object is ' + 'considered\n' + ' smaller or larger than another one is made arbitrarily ' + 'but\n' + ' consistently within one execution of a program.\n' + '\n' + 'The operators "in" and "not in" test for collection ' + 'membership. "x in\n' + 's" evaluates to true if *x* is a member of the collection ' + '*s*, and\n' + 'false otherwise. "x not in s" returns the negation of "x ' + 'in s". The\n' + 'collection membership test has traditionally been bound to ' + 'sequences;\n' + 'an object is a member of a collection if the collection is ' + 'a sequence\n' + 'and contains an element equal to that object. However, it ' + 'make sense\n' + 'for many other object types to support membership tests ' + 'without being\n' + 'a sequence. In particular, dictionaries (for keys) and ' + 'sets support\n' + 'membership testing.\n' + '\n' + 'For the list and tuple types, "x in y" is true if and only ' + 'if there\n' + 'exists an index *i* such that "x == y[i]" is true.\n' + '\n' + 'For the Unicode and string types, "x in y" is true if and ' + 'only if *x*\n' + 'is a substring of *y*. An equivalent test is "y.find(x) != ' + '-1".\n' + 'Note, *x* and *y* need not be the same type; consequently, ' + '"u\'ab\' in\n' + '\'abc\'" will return "True". Empty strings are always ' + 'considered to be a\n' + 'substring of any other string, so """ in "abc"" will return ' + '"True".\n' + '\n' + 'Changed in version 2.3: Previously, *x* was required to be ' + 'a string of\n' + 'length "1".\n' + '\n' + 'For user-defined classes which define the "__contains__()" ' + 'method, "x\n' + 'in y" is true if and only if "y.__contains__(x)" is true.\n' + '\n' + 'For user-defined classes which do not define ' + '"__contains__()" but do\n' + 'define "__iter__()", "x in y" is true if some value "z" ' + 'with "x == z"\n' + 'is produced while iterating over "y". If an exception is ' + 'raised\n' + 'during the iteration, it is as if "in" raised that ' + 'exception.\n' + '\n' + 'Lastly, the old-style iteration protocol is tried: if a ' + 'class defines\n' + '"__getitem__()", "x in y" is true if and only if there is a ' + 'non-\n' + 'negative integer index *i* such that "x == y[i]", and all ' + 'lower\n' + 'integer indices do not raise "IndexError" exception. (If ' + 'any other\n' + 'exception is raised, it is as if "in" raised that ' + 'exception).\n' + '\n' + 'The operator "not in" is defined to have the inverse true ' + 'value of\n' + '"in".\n' + '\n' + 'The operators "is" and "is not" test for object identity: ' + '"x is y" is\n' + 'true if and only if *x* and *y* are the same object. "x is ' + 'not y"\n' + 'yields the inverse truth value. [7]\n', + 'compound': '\n' + 'Compound statements\n' + '*******************\n' + '\n' + 'Compound statements contain (groups of) other statements; they ' + 'affect\n' + 'or control the execution of those other statements in some ' + 'way. In\n' + 'general, compound statements span multiple lines, although in ' + 'simple\n' + 'incarnations a whole compound statement may be contained in ' + 'one line.\n' + '\n' + 'The "if", "while" and "for" statements implement traditional ' + 'control\n' + 'flow constructs. "try" specifies exception handlers and/or ' + 'cleanup\n' + 'code for a group of statements. Function and class ' + 'definitions are\n' + 'also syntactically compound statements.\n' + '\n' + "Compound statements consist of one or more 'clauses.' A " + 'clause\n' + "consists of a header and a 'suite.' The clause headers of a\n" + 'particular compound statement are all at the same indentation ' + 'level.\n' + 'Each clause header begins with a uniquely identifying keyword ' + 'and ends\n' + 'with a colon. A suite is a group of statements controlled by ' + 'a\n' + 'clause. A suite can be one or more semicolon-separated ' + 'simple\n' + 'statements on the same line as the header, following the ' + "header's\n" + 'colon, or it can be one or more indented statements on ' + 'subsequent\n' + 'lines. Only the latter form of suite can contain nested ' + 'compound\n' + 'statements; the following is illegal, mostly because it ' + "wouldn't be\n" + 'clear to which "if" clause a following "else" clause would ' + 'belong:\n' + '\n' + ' if test1: if test2: print x\n' + '\n' + 'Also note that the semicolon binds tighter than the colon in ' + 'this\n' + 'context, so that in the following example, either all or none ' + 'of the\n' + '"print" statements are executed:\n' + '\n' + ' if x < y < z: print x; print y; print z\n' + '\n' + 'Summarizing:\n' + '\n' + ' compound_stmt ::= if_stmt\n' + ' | while_stmt\n' + ' | for_stmt\n' + ' | try_stmt\n' + ' | with_stmt\n' + ' | funcdef\n' + ' | classdef\n' + ' | decorated\n' + ' suite ::= stmt_list NEWLINE | NEWLINE INDENT ' + 'statement+ DEDENT\n' + ' statement ::= stmt_list NEWLINE | compound_stmt\n' + ' stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n' + '\n' + 'Note that statements always end in a "NEWLINE" possibly ' + 'followed by a\n' + '"DEDENT". Also note that optional continuation clauses always ' + 'begin\n' + 'with a keyword that cannot start a statement, thus there are ' + 'no\n' + 'ambiguities (the \'dangling "else"\' problem is solved in ' + 'Python by\n' + 'requiring nested "if" statements to be indented).\n' + '\n' + 'The formatting of the grammar rules in the following sections ' + 'places\n' + 'each clause on a separate line for clarity.\n' + '\n' + '\n' + 'The "if" statement\n' + '==================\n' + '\n' + 'The "if" statement is used for conditional execution:\n' + '\n' + ' if_stmt ::= "if" expression ":" suite\n' + ' ( "elif" expression ":" suite )*\n' + ' ["else" ":" suite]\n' + '\n' + 'It selects exactly one of the suites by evaluating the ' + 'expressions one\n' + 'by one until one is found to be true (see section Boolean ' + 'operations\n' + 'for the definition of true and false); then that suite is ' + 'executed\n' + '(and no other part of the "if" statement is executed or ' + 'evaluated).\n' + 'If all expressions are false, the suite of the "else" clause, ' + 'if\n' + 'present, is executed.\n' + '\n' + '\n' + 'The "while" statement\n' + '=====================\n' + '\n' + 'The "while" statement is used for repeated execution as long ' + 'as an\n' + 'expression is true:\n' + '\n' + ' while_stmt ::= "while" expression ":" suite\n' + ' ["else" ":" suite]\n' + '\n' + 'This repeatedly tests the expression and, if it is true, ' + 'executes the\n' + 'first suite; if the expression is false (which may be the ' + 'first time\n' + 'it is tested) the suite of the "else" clause, if present, is ' + 'executed\n' + 'and the loop terminates.\n' + '\n' + 'A "break" statement executed in the first suite terminates the ' + 'loop\n' + 'without executing the "else" clause\'s suite. A "continue" ' + 'statement\n' + 'executed in the first suite skips the rest of the suite and ' + 'goes back\n' + 'to testing the expression.\n' + '\n' + '\n' + 'The "for" statement\n' + '===================\n' + '\n' + 'The "for" statement is used to iterate over the elements of a ' + 'sequence\n' + '(such as a string, tuple or list) or other iterable object:\n' + '\n' + ' for_stmt ::= "for" target_list "in" expression_list ":" ' + 'suite\n' + ' ["else" ":" suite]\n' + '\n' + 'The expression list is evaluated once; it should yield an ' + 'iterable\n' + 'object. An iterator is created for the result of the\n' + '"expression_list". The suite is then executed once for each ' + 'item\n' + 'provided by the iterator, in the order of ascending indices. ' + 'Each\n' + 'item in turn is assigned to the target list using the standard ' + 'rules\n' + 'for assignments, and then the suite is executed. When the ' + 'items are\n' + 'exhausted (which is immediately when the sequence is empty), ' + 'the suite\n' + 'in the "else" clause, if present, is executed, and the loop\n' + 'terminates.\n' + '\n' + 'A "break" statement executed in the first suite terminates the ' + 'loop\n' + 'without executing the "else" clause\'s suite. A "continue" ' + 'statement\n' + 'executed in the first suite skips the rest of the suite and ' + 'continues\n' + 'with the next item, or with the "else" clause if there was no ' + 'next\n' + 'item.\n' + '\n' + 'The suite may assign to the variable(s) in the target list; ' + 'this does\n' + 'not affect the next item assigned to it.\n' + '\n' + 'The target list is not deleted when the loop is finished, but ' + 'if the\n' + 'sequence is empty, it will not have been assigned to at all by ' + 'the\n' + 'loop. Hint: the built-in function "range()" returns a ' + 'sequence of\n' + 'integers suitable to emulate the effect of Pascal\'s "for i := ' + 'a to b\n' + 'do"; e.g., "range(3)" returns the list "[0, 1, 2]".\n' + '\n' + 'Note: There is a subtlety when the sequence is being modified ' + 'by the\n' + ' loop (this can only occur for mutable sequences, i.e. ' + 'lists). An\n' + ' internal counter is used to keep track of which item is used ' + 'next,\n' + ' and this is incremented on each iteration. When this ' + 'counter has\n' + ' reached the length of the sequence the loop terminates. ' + 'This means\n' + ' that if the suite deletes the current (or a previous) item ' + 'from the\n' + ' sequence, the next item will be skipped (since it gets the ' + 'index of\n' + ' the current item which has already been treated). Likewise, ' + 'if the\n' + ' suite inserts an item in the sequence before the current ' + 'item, the\n' + ' current item will be treated again the next time through the ' + 'loop.\n' + ' This can lead to nasty bugs that can be avoided by making a\n' + ' temporary copy using a slice of the whole sequence, e.g.,\n' + '\n' + ' for x in a[:]:\n' + ' if x < 0: a.remove(x)\n' + '\n' + '\n' + 'The "try" statement\n' + '===================\n' + '\n' + 'The "try" statement specifies exception handlers and/or ' + 'cleanup code\n' + 'for a group of statements:\n' + '\n' + ' try_stmt ::= try1_stmt | try2_stmt\n' + ' try1_stmt ::= "try" ":" suite\n' + ' ("except" [expression [("as" | ",") ' + 'identifier]] ":" suite)+\n' + ' ["else" ":" suite]\n' + ' ["finally" ":" suite]\n' + ' try2_stmt ::= "try" ":" suite\n' + ' "finally" ":" suite\n' + '\n' + 'Changed in version 2.5: In previous versions of Python,\n' + '"try"..."except"..."finally" did not work. "try"..."except" ' + 'had to be\n' + 'nested in "try"..."finally".\n' + '\n' + 'The "except" clause(s) specify one or more exception handlers. ' + 'When no\n' + 'exception occurs in the "try" clause, no exception handler is\n' + 'executed. When an exception occurs in the "try" suite, a ' + 'search for an\n' + 'exception handler is started. This search inspects the except ' + 'clauses\n' + 'in turn until one is found that matches the exception. An ' + 'expression-\n' + 'less except clause, if present, must be last; it matches any\n' + 'exception. For an except clause with an expression, that ' + 'expression\n' + 'is evaluated, and the clause matches the exception if the ' + 'resulting\n' + 'object is "compatible" with the exception. An object is ' + 'compatible\n' + 'with an exception if it is the class or a base class of the ' + 'exception\n' + 'object, or a tuple containing an item compatible with the ' + 'exception.\n' + '\n' + 'If no except clause matches the exception, the search for an ' + 'exception\n' + 'handler continues in the surrounding code and on the ' + 'invocation stack.\n' + '[1]\n' + '\n' + 'If the evaluation of an expression in the header of an except ' + 'clause\n' + 'raises an exception, the original search for a handler is ' + 'canceled and\n' + 'a search starts for the new exception in the surrounding code ' + 'and on\n' + 'the call stack (it is treated as if the entire "try" statement ' + 'raised\n' + 'the exception).\n' + '\n' + 'When a matching except clause is found, the exception is ' + 'assigned to\n' + 'the target specified in that except clause, if present, and ' + 'the except\n' + "clause's suite is executed. All except clauses must have an\n" + 'executable block. When the end of this block is reached, ' + 'execution\n' + 'continues normally after the entire try statement. (This ' + 'means that\n' + 'if two nested handlers exist for the same exception, and the ' + 'exception\n' + 'occurs in the try clause of the inner handler, the outer ' + 'handler will\n' + 'not handle the exception.)\n' + '\n' + "Before an except clause's suite is executed, details about " + 'the\n' + 'exception are assigned to three variables in the "sys" ' + 'module:\n' + '"sys.exc_type" receives the object identifying the exception;\n' + '"sys.exc_value" receives the exception\'s parameter;\n' + '"sys.exc_traceback" receives a traceback object (see section ' + 'The\n' + 'standard type hierarchy) identifying the point in the program ' + 'where\n' + 'the exception occurred. These details are also available ' + 'through the\n' + '"sys.exc_info()" function, which returns a tuple "(exc_type,\n' + 'exc_value, exc_traceback)". Use of the corresponding ' + 'variables is\n' + 'deprecated in favor of this function, since their use is ' + 'unsafe in a\n' + 'threaded program. As of Python 1.5, the variables are ' + 'restored to\n' + 'their previous values (before the call) when returning from a ' + 'function\n' + 'that handled an exception.\n' + '\n' + 'The optional "else" clause is executed if and when control ' + 'flows off\n' + 'the end of the "try" clause. [2] Exceptions in the "else" ' + 'clause are\n' + 'not handled by the preceding "except" clauses.\n' + '\n' + 'If "finally" is present, it specifies a \'cleanup\' handler. ' + 'The "try"\n' + 'clause is executed, including any "except" and "else" ' + 'clauses. If an\n' + 'exception occurs in any of the clauses and is not handled, ' + 'the\n' + 'exception is temporarily saved. The "finally" clause is ' + 'executed. If\n' + 'there is a saved exception, it is re-raised at the end of the\n' + '"finally" clause. If the "finally" clause raises another ' + 'exception or\n' + 'executes a "return" or "break" statement, the saved exception ' + 'is\n' + 'discarded:\n' + '\n' + ' >>> def f():\n' + ' ... try:\n' + ' ... 1/0\n' + ' ... finally:\n' + ' ... return 42\n' + ' ...\n' + ' >>> f()\n' + ' 42\n' + '\n' + 'The exception information is not available to the program ' + 'during\n' + 'execution of the "finally" clause.\n' + '\n' + 'When a "return", "break" or "continue" statement is executed ' + 'in the\n' + '"try" suite of a "try"..."finally" statement, the "finally" ' + 'clause is\n' + 'also executed \'on the way out.\' A "continue" statement is ' + 'illegal in\n' + 'the "finally" clause. (The reason is a problem with the ' + 'current\n' + 'implementation --- this restriction may be lifted in the ' + 'future).\n' + '\n' + 'The return value of a function is determined by the last ' + '"return"\n' + 'statement executed. Since the "finally" clause always ' + 'executes, a\n' + '"return" statement executed in the "finally" clause will ' + 'always be the\n' + 'last one executed:\n' + '\n' + ' >>> def foo():\n' + ' ... try:\n' + " ... return 'try'\n" + ' ... finally:\n' + " ... return 'finally'\n" + ' ...\n' + ' >>> foo()\n' + " 'finally'\n" + '\n' + 'Additional information on exceptions can be found in section\n' + 'Exceptions, and information on using the "raise" statement to ' + 'generate\n' + 'exceptions may be found in section The raise statement.\n' + '\n' + '\n' + 'The "with" statement\n' + '====================\n' + '\n' + 'New in version 2.5.\n' + '\n' + 'The "with" statement is used to wrap the execution of a block ' + 'with\n' + 'methods defined by a context manager (see section With ' + 'Statement\n' + 'Context Managers). This allows common ' + '"try"..."except"..."finally"\n' + 'usage patterns to be encapsulated for convenient reuse.\n' + '\n' + ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' + ' with_item ::= expression ["as" target]\n' + '\n' + 'The execution of the "with" statement with one "item" proceeds ' + 'as\n' + 'follows:\n' + '\n' + '1. The context expression (the expression given in the ' + '"with_item")\n' + ' is evaluated to obtain a context manager.\n' + '\n' + '2. The context manager\'s "__exit__()" is loaded for later ' + 'use.\n' + '\n' + '3. The context manager\'s "__enter__()" method is invoked.\n' + '\n' + '4. If a target was included in the "with" statement, the ' + 'return\n' + ' value from "__enter__()" is assigned to it.\n' + '\n' + ' Note: The "with" statement guarantees that if the ' + '"__enter__()"\n' + ' method returns without an error, then "__exit__()" will ' + 'always be\n' + ' called. Thus, if an error occurs during the assignment to ' + 'the\n' + ' target list, it will be treated the same as an error ' + 'occurring\n' + ' within the suite would be. See step 6 below.\n' + '\n' + '5. The suite is executed.\n' + '\n' + '6. The context manager\'s "__exit__()" method is invoked. If ' + 'an\n' + ' exception caused the suite to be exited, its type, value, ' + 'and\n' + ' traceback are passed as arguments to "__exit__()". ' + 'Otherwise, three\n' + ' "None" arguments are supplied.\n' + '\n' + ' If the suite was exited due to an exception, and the return ' + 'value\n' + ' from the "__exit__()" method was false, the exception is ' + 'reraised.\n' + ' If the return value was true, the exception is suppressed, ' + 'and\n' + ' execution continues with the statement following the ' + '"with"\n' + ' statement.\n' + '\n' + ' If the suite was exited for any reason other than an ' + 'exception, the\n' + ' return value from "__exit__()" is ignored, and execution ' + 'proceeds\n' + ' at the normal location for the kind of exit that was ' + 'taken.\n' + '\n' + 'With more than one item, the context managers are processed as ' + 'if\n' + 'multiple "with" statements were nested:\n' + '\n' + ' with A() as a, B() as b:\n' + ' suite\n' + '\n' + 'is equivalent to\n' + '\n' + ' with A() as a:\n' + ' with B() as b:\n' + ' suite\n' + '\n' + 'Note: In Python 2.5, the "with" statement is only allowed when ' + 'the\n' + ' "with_statement" feature has been enabled. It is always ' + 'enabled in\n' + ' Python 2.6.\n' + '\n' + 'Changed in version 2.7: Support for multiple context ' + 'expressions.\n' + '\n' + 'See also: **PEP 0343** - The "with" statement\n' + '\n' + ' The specification, background, and examples for the ' + 'Python "with"\n' + ' statement.\n' + '\n' + '\n' + 'Function definitions\n' + '====================\n' + '\n' + 'A function definition defines a user-defined function object ' + '(see\n' + 'section The standard type hierarchy):\n' + '\n' + ' decorated ::= decorators (classdef | funcdef)\n' + ' decorators ::= decorator+\n' + ' decorator ::= "@" dotted_name ["(" [argument_list ' + '[","]] ")"] NEWLINE\n' + ' funcdef ::= "def" funcname "(" [parameter_list] ")" ' + '":" suite\n' + ' dotted_name ::= identifier ("." identifier)*\n' + ' parameter_list ::= (defparameter ",")*\n' + ' ( "*" identifier ["," "**" identifier]\n' + ' | "**" identifier\n' + ' | defparameter [","] )\n' + ' defparameter ::= parameter ["=" expression]\n' + ' sublist ::= parameter ("," parameter)* [","]\n' + ' parameter ::= identifier | "(" sublist ")"\n' + ' funcname ::= identifier\n' + '\n' + 'A function definition is an executable statement. Its ' + 'execution binds\n' + 'the function name in the current local namespace to a function ' + 'object\n' + '(a wrapper around the executable code for the function). ' + 'This\n' + 'function object contains a reference to the current global ' + 'namespace\n' + 'as the global namespace to be used when the function is ' + 'called.\n' + '\n' + 'The function definition does not execute the function body; ' + 'this gets\n' + 'executed only when the function is called. [3]\n' + '\n' + 'A function definition may be wrapped by one or more ' + '*decorator*\n' + 'expressions. Decorator expressions are evaluated when the ' + 'function is\n' + 'defined, in the scope that contains the function definition. ' + 'The\n' + 'result must be a callable, which is invoked with the function ' + 'object\n' + 'as the only argument. The returned value is bound to the ' + 'function name\n' + 'instead of the function object. Multiple decorators are ' + 'applied in\n' + 'nested fashion. For example, the following code:\n' + '\n' + ' @f1(arg)\n' + ' @f2\n' + ' def func(): pass\n' + '\n' + 'is equivalent to:\n' + '\n' + ' def func(): pass\n' + ' func = f1(arg)(f2(func))\n' + '\n' + 'When one or more top-level *parameters* have the form ' + '*parameter* "="\n' + '*expression*, the function is said to have "default parameter ' + 'values."\n' + 'For a parameter with a default value, the corresponding ' + '*argument* may\n' + "be omitted from a call, in which case the parameter's default " + 'value is\n' + 'substituted. If a parameter has a default value, all ' + 'following\n' + 'parameters must also have a default value --- this is a ' + 'syntactic\n' + 'restriction that is not expressed by the grammar.\n' + '\n' + '**Default parameter values are evaluated when the function ' + 'definition\n' + 'is executed.** This means that the expression is evaluated ' + 'once, when\n' + 'the function is defined, and that the same "pre-computed" ' + 'value is\n' + 'used for each call. This is especially important to ' + 'understand when a\n' + 'default parameter is a mutable object, such as a list or a ' + 'dictionary:\n' + 'if the function modifies the object (e.g. by appending an item ' + 'to a\n' + 'list), the default value is in effect modified. This is ' + 'generally not\n' + 'what was intended. A way around this is to use "None" as ' + 'the\n' + 'default, and explicitly test for it in the body of the ' + 'function, e.g.:\n' + '\n' + ' def whats_on_the_telly(penguin=None):\n' + ' if penguin is None:\n' + ' penguin = []\n' + ' penguin.append("property of the zoo")\n' + ' return penguin\n' + '\n' + 'Function call semantics are described in more detail in ' + 'section Calls.\n' + 'A function call always assigns values to all parameters ' + 'mentioned in\n' + 'the parameter list, either from position arguments, from ' + 'keyword\n' + 'arguments, or from default values. If the form ' + '""*identifier"" is\n' + 'present, it is initialized to a tuple receiving any excess ' + 'positional\n' + 'parameters, defaulting to the empty tuple. If the form\n' + '""**identifier"" is present, it is initialized to a new ' + 'dictionary\n' + 'receiving any excess keyword arguments, defaulting to a new ' + 'empty\n' + 'dictionary.\n' + '\n' + 'It is also possible to create anonymous functions (functions ' + 'not bound\n' + 'to a name), for immediate use in expressions. This uses ' + 'lambda\n' + 'expressions, described in section Lambdas. Note that the ' + 'lambda\n' + 'expression is merely a shorthand for a simplified function ' + 'definition;\n' + 'a function defined in a ""def"" statement can be passed around ' + 'or\n' + 'assigned to another name just like a function defined by a ' + 'lambda\n' + 'expression. The ""def"" form is actually more powerful since ' + 'it\n' + 'allows the execution of multiple statements.\n' + '\n' + "**Programmer's note:** Functions are first-class objects. A " + '""def""\n' + 'form executed inside a function definition defines a local ' + 'function\n' + 'that can be returned or passed around. Free variables used in ' + 'the\n' + 'nested function can access the local variables of the ' + 'function\n' + 'containing the def. See section Naming and binding for ' + 'details.\n' + '\n' + '\n' + 'Class definitions\n' + '=================\n' + '\n' + 'A class definition defines a class object (see section The ' + 'standard\n' + 'type hierarchy):\n' + '\n' + ' classdef ::= "class" classname [inheritance] ":" suite\n' + ' inheritance ::= "(" [expression_list] ")"\n' + ' classname ::= identifier\n' + '\n' + 'A class definition is an executable statement. It first ' + 'evaluates the\n' + 'inheritance list, if present. Each item in the inheritance ' + 'list\n' + 'should evaluate to a class object or class type which allows\n' + "subclassing. The class's suite is then executed in a new " + 'execution\n' + 'frame (see section Naming and binding), using a newly created ' + 'local\n' + 'namespace and the original global namespace. (Usually, the ' + 'suite\n' + "contains only function definitions.) When the class's suite " + 'finishes\n' + 'execution, its execution frame is discarded but its local ' + 'namespace is\n' + 'saved. [4] A class object is then created using the ' + 'inheritance list\n' + 'for the base classes and the saved local namespace for the ' + 'attribute\n' + 'dictionary. The class name is bound to this class object in ' + 'the\n' + 'original local namespace.\n' + '\n' + "**Programmer's note:** Variables defined in the class " + 'definition are\n' + 'class variables; they are shared by all instances. To create ' + 'instance\n' + 'variables, they can be set in a method with "self.name = ' + 'value". Both\n' + 'class and instance variables are accessible through the ' + 'notation\n' + '""self.name"", and an instance variable hides a class variable ' + 'with\n' + 'the same name when accessed in this way. Class variables can ' + 'be used\n' + 'as defaults for instance variables, but using mutable values ' + 'there can\n' + 'lead to unexpected results. For *new-style class*es, ' + 'descriptors can\n' + 'be used to create instance variables with different ' + 'implementation\n' + 'details.\n' + '\n' + 'Class definitions, like function definitions, may be wrapped ' + 'by one or\n' + 'more *decorator* expressions. The evaluation rules for the ' + 'decorator\n' + 'expressions are the same as for functions. The result must be ' + 'a class\n' + 'object, which is then bound to the class name.\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] The exception is propagated to the invocation stack ' + 'unless\n' + ' there is a "finally" clause which happens to raise ' + 'another\n' + ' exception. That new exception causes the old one to be ' + 'lost.\n' + '\n' + '[2] Currently, control "flows off the end" except in the case ' + 'of\n' + ' an exception or the execution of a "return", "continue", ' + 'or\n' + ' "break" statement.\n' + '\n' + '[3] A string literal appearing as the first statement in the\n' + " function body is transformed into the function's " + '"__doc__"\n' + " attribute and therefore the function's *docstring*.\n" + '\n' + '[4] A string literal appearing as the first statement in the ' + 'class\n' + ' body is transformed into the namespace\'s "__doc__" item ' + 'and\n' + " therefore the class's *docstring*.\n", + 'context-managers': '\n' + 'With Statement Context Managers\n' + '*******************************\n' + '\n' + 'New in version 2.5.\n' + '\n' + 'A *context manager* is an object that defines the ' + 'runtime context to\n' + 'be established when executing a "with" statement. The ' + 'context manager\n' + 'handles the entry into, and the exit from, the desired ' + 'runtime context\n' + 'for the execution of the block of code. Context ' + 'managers are normally\n' + 'invoked using the "with" statement (described in ' + 'section The with\n' + 'statement), but can also be used by directly invoking ' + 'their methods.\n' + '\n' + 'Typical uses of context managers include saving and ' + 'restoring various\n' + 'kinds of global state, locking and unlocking ' + 'resources, closing opened\n' + 'files, etc.\n' + '\n' + 'For more information on context managers, see Context ' + 'Manager Types.\n' + '\n' + 'object.__enter__(self)\n' + '\n' + ' Enter the runtime context related to this object. ' + 'The "with"\n' + " statement will bind this method's return value to " + 'the target(s)\n' + ' specified in the "as" clause of the statement, if ' + 'any.\n' + '\n' + 'object.__exit__(self, exc_type, exc_value, traceback)\n' + '\n' + ' Exit the runtime context related to this object. ' + 'The parameters\n' + ' describe the exception that caused the context to ' + 'be exited. If the\n' + ' context was exited without an exception, all three ' + 'arguments will\n' + ' be "None".\n' + '\n' + ' If an exception is supplied, and the method wishes ' + 'to suppress the\n' + ' exception (i.e., prevent it from being propagated), ' + 'it should\n' + ' return a true value. Otherwise, the exception will ' + 'be processed\n' + ' normally upon exit from this method.\n' + '\n' + ' Note that "__exit__()" methods should not reraise ' + 'the passed-in\n' + " exception; this is the caller's responsibility.\n" + '\n' + 'See also: **PEP 0343** - The "with" statement\n' + '\n' + ' The specification, background, and examples for ' + 'the Python "with"\n' + ' statement.\n', + 'continue': '\n' + 'The "continue" statement\n' + '************************\n' + '\n' + ' continue_stmt ::= "continue"\n' + '\n' + '"continue" may only occur syntactically nested in a "for" or ' + '"while"\n' + 'loop, but not nested in a function or class definition or ' + '"finally"\n' + 'clause within that loop. It continues with the next cycle of ' + 'the\n' + 'nearest enclosing loop.\n' + '\n' + 'When "continue" passes control out of a "try" statement with ' + 'a\n' + '"finally" clause, that "finally" clause is executed before ' + 'really\n' + 'starting the next loop cycle.\n', + 'conversions': '\n' + 'Arithmetic conversions\n' + '**********************\n' + '\n' + 'When a description of an arithmetic operator below uses the ' + 'phrase\n' + '"the numeric arguments are converted to a common type," the ' + 'arguments\n' + 'are coerced using the coercion rules listed at Coercion ' + 'rules. If\n' + 'both arguments are standard numeric types, the following ' + 'coercions are\n' + 'applied:\n' + '\n' + '* If either argument is a complex number, the other is ' + 'converted to\n' + ' complex;\n' + '\n' + '* otherwise, if either argument is a floating point number, ' + 'the\n' + ' other is converted to floating point;\n' + '\n' + '* otherwise, if either argument is a long integer, the ' + 'other is\n' + ' converted to long integer;\n' + '\n' + '* otherwise, both must be plain integers and no conversion ' + 'is\n' + ' necessary.\n' + '\n' + 'Some additional rules apply for certain operators (e.g., a ' + 'string left\n' + "argument to the '%' operator). Extensions can define their " + 'own\n' + 'coercions.\n', + 'customization': '\n' + 'Basic customization\n' + '*******************\n' + '\n' + 'object.__new__(cls[, ...])\n' + '\n' + ' Called to create a new instance of class *cls*. ' + '"__new__()" is a\n' + ' static method (special-cased so you need not declare ' + 'it as such)\n' + ' that takes the class of which an instance was ' + 'requested as its\n' + ' first argument. The remaining arguments are those ' + 'passed to the\n' + ' object constructor expression (the call to the ' + 'class). The return\n' + ' value of "__new__()" should be the new object instance ' + '(usually an\n' + ' instance of *cls*).\n' + '\n' + ' Typical implementations create a new instance of the ' + 'class by\n' + ' invoking the superclass\'s "__new__()" method using\n' + ' "super(currentclass, cls).__new__(cls[, ...])" with ' + 'appropriate\n' + ' arguments and then modifying the newly-created ' + 'instance as\n' + ' necessary before returning it.\n' + '\n' + ' If "__new__()" returns an instance of *cls*, then the ' + 'new\n' + ' instance\'s "__init__()" method will be invoked like\n' + ' "__init__(self[, ...])", where *self* is the new ' + 'instance and the\n' + ' remaining arguments are the same as were passed to ' + '"__new__()".\n' + '\n' + ' If "__new__()" does not return an instance of *cls*, ' + 'then the new\n' + ' instance\'s "__init__()" method will not be invoked.\n' + '\n' + ' "__new__()" is intended mainly to allow subclasses of ' + 'immutable\n' + ' types (like int, str, or tuple) to customize instance ' + 'creation. It\n' + ' is also commonly overridden in custom metaclasses in ' + 'order to\n' + ' customize class creation.\n' + '\n' + 'object.__init__(self[, ...])\n' + '\n' + ' Called after the instance has been created (by ' + '"__new__()"), but\n' + ' before it is returned to the caller. The arguments ' + 'are those\n' + ' passed to the class constructor expression. If a base ' + 'class has an\n' + ' "__init__()" method, the derived class\'s "__init__()" ' + 'method, if\n' + ' any, must explicitly call it to ensure proper ' + 'initialization of the\n' + ' base class part of the instance; for example:\n' + ' "BaseClass.__init__(self, [args...])".\n' + '\n' + ' Because "__new__()" and "__init__()" work together in ' + 'constructing\n' + ' objects ("__new__()" to create it, and "__init__()" to ' + 'customise\n' + ' it), no non-"None" value may be returned by ' + '"__init__()"; doing so\n' + ' will cause a "TypeError" to be raised at runtime.\n' + '\n' + 'object.__del__(self)\n' + '\n' + ' Called when the instance is about to be destroyed. ' + 'This is also\n' + ' called a destructor. If a base class has a ' + '"__del__()" method, the\n' + ' derived class\'s "__del__()" method, if any, must ' + 'explicitly call it\n' + ' to ensure proper deletion of the base class part of ' + 'the instance.\n' + ' Note that it is possible (though not recommended!) for ' + 'the\n' + ' "__del__()" method to postpone destruction of the ' + 'instance by\n' + ' creating a new reference to it. It may then be called ' + 'at a later\n' + ' time when this new reference is deleted. It is not ' + 'guaranteed that\n' + ' "__del__()" methods are called for objects that still ' + 'exist when\n' + ' the interpreter exits.\n' + '\n' + ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' + 'the former\n' + ' decrements the reference count for "x" by one, and ' + 'the latter is\n' + ' only called when "x"\'s reference count reaches ' + 'zero. Some common\n' + ' situations that may prevent the reference count of ' + 'an object from\n' + ' going to zero include: circular references between ' + 'objects (e.g.,\n' + ' a doubly-linked list or a tree data structure with ' + 'parent and\n' + ' child pointers); a reference to the object on the ' + 'stack frame of\n' + ' a function that caught an exception (the traceback ' + 'stored in\n' + ' "sys.exc_traceback" keeps the stack frame alive); or ' + 'a reference\n' + ' to the object on the stack frame that raised an ' + 'unhandled\n' + ' exception in interactive mode (the traceback stored ' + 'in\n' + ' "sys.last_traceback" keeps the stack frame alive). ' + 'The first\n' + ' situation can only be remedied by explicitly ' + 'breaking the cycles;\n' + ' the latter two situations can be resolved by storing ' + '"None" in\n' + ' "sys.exc_traceback" or "sys.last_traceback". ' + 'Circular references\n' + ' which are garbage are detected when the option cycle ' + 'detector is\n' + " enabled (it's on by default), but can only be " + 'cleaned up if there\n' + ' are no Python-level "__del__()" methods involved. ' + 'Refer to the\n' + ' documentation for the "gc" module for more ' + 'information about how\n' + ' "__del__()" methods are handled by the cycle ' + 'detector,\n' + ' particularly the description of the "garbage" ' + 'value.\n' + '\n' + ' Warning: Due to the precarious circumstances under ' + 'which\n' + ' "__del__()" methods are invoked, exceptions that ' + 'occur during\n' + ' their execution are ignored, and a warning is ' + 'printed to\n' + ' "sys.stderr" instead. Also, when "__del__()" is ' + 'invoked in\n' + ' response to a module being deleted (e.g., when ' + 'execution of the\n' + ' program is done), other globals referenced by the ' + '"__del__()"\n' + ' method may already have been deleted or in the ' + 'process of being\n' + ' torn down (e.g. the import machinery shutting ' + 'down). For this\n' + ' reason, "__del__()" methods should do the absolute ' + 'minimum needed\n' + ' to maintain external invariants. Starting with ' + 'version 1.5,\n' + ' Python guarantees that globals whose name begins ' + 'with a single\n' + ' underscore are deleted from their module before ' + 'other globals are\n' + ' deleted; if no other references to such globals ' + 'exist, this may\n' + ' help in assuring that imported modules are still ' + 'available at the\n' + ' time when the "__del__()" method is called.\n' + '\n' + ' See also the "-R" command-line option.\n' + '\n' + 'object.__repr__(self)\n' + '\n' + ' Called by the "repr()" built-in function and by string ' + 'conversions\n' + ' (reverse quotes) to compute the "official" string ' + 'representation of\n' + ' an object. If at all possible, this should look like ' + 'a valid\n' + ' Python expression that could be used to recreate an ' + 'object with the\n' + ' same value (given an appropriate environment). If ' + 'this is not\n' + ' possible, a string of the form "<...some useful ' + 'description...>"\n' + ' should be returned. The return value must be a string ' + 'object. If a\n' + ' class defines "__repr__()" but not "__str__()", then ' + '"__repr__()"\n' + ' is also used when an "informal" string representation ' + 'of instances\n' + ' of that class is required.\n' + '\n' + ' This is typically used for debugging, so it is ' + 'important that the\n' + ' representation is information-rich and unambiguous.\n' + '\n' + 'object.__str__(self)\n' + '\n' + ' Called by the "str()" built-in function and by the ' + '"print"\n' + ' statement to compute the "informal" string ' + 'representation of an\n' + ' object. This differs from "__repr__()" in that it ' + 'does not have to\n' + ' be a valid Python expression: a more convenient or ' + 'concise\n' + ' representation may be used instead. The return value ' + 'must be a\n' + ' string object.\n' + '\n' + 'object.__lt__(self, other)\n' + 'object.__le__(self, other)\n' + 'object.__eq__(self, other)\n' + 'object.__ne__(self, other)\n' + 'object.__gt__(self, other)\n' + 'object.__ge__(self, other)\n' + '\n' + ' New in version 2.1.\n' + '\n' + ' These are the so-called "rich comparison" methods, and ' + 'are called\n' + ' for comparison operators in preference to "__cmp__()" ' + 'below. The\n' + ' correspondence between operator symbols and method ' + 'names is as\n' + ' follows: "xy" call ' + '"x.__ne__(y)",\n' + ' "x>y" calls "x.__gt__(y)", and "x>=y" calls ' + '"x.__ge__(y)".\n' + '\n' + ' A rich comparison method may return the singleton ' + '"NotImplemented"\n' + ' if it does not implement the operation for a given ' + 'pair of\n' + ' arguments. By convention, "False" and "True" are ' + 'returned for a\n' + ' successful comparison. However, these methods can ' + 'return any value,\n' + ' so if the comparison operator is used in a Boolean ' + 'context (e.g.,\n' + ' in the condition of an "if" statement), Python will ' + 'call "bool()"\n' + ' on the value to determine if the result is true or ' + 'false.\n' + '\n' + ' There are no implied relationships among the ' + 'comparison operators.\n' + ' The truth of "x==y" does not imply that "x!=y" is ' + 'false.\n' + ' Accordingly, when defining "__eq__()", one should also ' + 'define\n' + ' "__ne__()" so that the operators will behave as ' + 'expected. See the\n' + ' paragraph on "__hash__()" for some important notes on ' + 'creating\n' + ' *hashable* objects which support custom comparison ' + 'operations and\n' + ' are usable as dictionary keys.\n' + '\n' + ' There are no swapped-argument versions of these ' + 'methods (to be used\n' + ' when the left argument does not support the operation ' + 'but the right\n' + ' argument does); rather, "__lt__()" and "__gt__()" are ' + "each other's\n" + ' reflection, "__le__()" and "__ge__()" are each ' + "other's reflection,\n" + ' and "__eq__()" and "__ne__()" are their own ' + 'reflection.\n' + '\n' + ' Arguments to rich comparison methods are never ' + 'coerced.\n' + '\n' + ' To automatically generate ordering operations from a ' + 'single root\n' + ' operation, see "functools.total_ordering()".\n' + '\n' + 'object.__cmp__(self, other)\n' + '\n' + ' Called by comparison operations if rich comparison ' + '(see above) is\n' + ' not defined. Should return a negative integer if ' + '"self < other",\n' + ' zero if "self == other", a positive integer if "self > ' + 'other". If\n' + ' no "__cmp__()", "__eq__()" or "__ne__()" operation is ' + 'defined,\n' + ' class instances are compared by object identity ' + '("address"). See\n' + ' also the description of "__hash__()" for some ' + 'important notes on\n' + ' creating *hashable* objects which support custom ' + 'comparison\n' + ' operations and are usable as dictionary keys. (Note: ' + 'the\n' + ' restriction that exceptions are not propagated by ' + '"__cmp__()" has\n' + ' been removed since Python 1.5.)\n' + '\n' + 'object.__rcmp__(self, other)\n' + '\n' + ' Changed in version 2.1: No longer supported.\n' + '\n' + 'object.__hash__(self)\n' + '\n' + ' Called by built-in function "hash()" and for ' + 'operations on members\n' + ' of hashed collections including "set", "frozenset", ' + 'and "dict".\n' + ' "__hash__()" should return an integer. The only ' + 'required property\n' + ' is that objects which compare equal have the same hash ' + 'value; it is\n' + ' advised to somehow mix together (e.g. using exclusive ' + 'or) the hash\n' + ' values for the components of the object that also play ' + 'a part in\n' + ' comparison of objects.\n' + '\n' + ' If a class does not define a "__cmp__()" or "__eq__()" ' + 'method it\n' + ' should not define a "__hash__()" operation either; if ' + 'it defines\n' + ' "__cmp__()" or "__eq__()" but not "__hash__()", its ' + 'instances will\n' + ' not be usable in hashed collections. If a class ' + 'defines mutable\n' + ' objects and implements a "__cmp__()" or "__eq__()" ' + 'method, it\n' + ' should not implement "__hash__()", since hashable ' + 'collection\n' + " implementations require that a object's hash value is " + 'immutable (if\n' + " the object's hash value changes, it will be in the " + 'wrong hash\n' + ' bucket).\n' + '\n' + ' User-defined classes have "__cmp__()" and "__hash__()" ' + 'methods by\n' + ' default; with them, all objects compare unequal ' + '(except with\n' + ' themselves) and "x.__hash__()" returns a result ' + 'derived from\n' + ' "id(x)".\n' + '\n' + ' Classes which inherit a "__hash__()" method from a ' + 'parent class but\n' + ' change the meaning of "__cmp__()" or "__eq__()" such ' + 'that the hash\n' + ' value returned is no longer appropriate (e.g. by ' + 'switching to a\n' + ' value-based concept of equality instead of the default ' + 'identity\n' + ' based equality) can explicitly flag themselves as ' + 'being unhashable\n' + ' by setting "__hash__ = None" in the class definition. ' + 'Doing so\n' + ' means that not only will instances of the class raise ' + 'an\n' + ' appropriate "TypeError" when a program attempts to ' + 'retrieve their\n' + ' hash value, but they will also be correctly identified ' + 'as\n' + ' unhashable when checking "isinstance(obj, ' + 'collections.Hashable)"\n' + ' (unlike classes which define their own "__hash__()" to ' + 'explicitly\n' + ' raise "TypeError").\n' + '\n' + ' Changed in version 2.5: "__hash__()" may now also ' + 'return a long\n' + ' integer object; the 32-bit integer is then derived ' + 'from the hash of\n' + ' that object.\n' + '\n' + ' Changed in version 2.6: "__hash__" may now be set to ' + '"None" to\n' + ' explicitly flag instances of a class as unhashable.\n' + '\n' + 'object.__nonzero__(self)\n' + '\n' + ' Called to implement truth value testing and the ' + 'built-in operation\n' + ' "bool()"; should return "False" or "True", or their ' + 'integer\n' + ' equivalents "0" or "1". When this method is not ' + 'defined,\n' + ' "__len__()" is called, if it is defined, and the ' + 'object is\n' + ' considered true if its result is nonzero. If a class ' + 'defines\n' + ' neither "__len__()" nor "__nonzero__()", all its ' + 'instances are\n' + ' considered true.\n' + '\n' + 'object.__unicode__(self)\n' + '\n' + ' Called to implement "unicode()" built-in; should ' + 'return a Unicode\n' + ' object. When this method is not defined, string ' + 'conversion is\n' + ' attempted, and the result of string conversion is ' + 'converted to\n' + ' Unicode using the system default encoding.\n', + 'debugger': '\n' + '"pdb" --- The Python Debugger\n' + '*****************************\n' + '\n' + '**Source code:** Lib/pdb.py\n' + '\n' + '======================================================================\n' + '\n' + 'The module "pdb" defines an interactive source code debugger ' + 'for\n' + 'Python programs. It supports setting (conditional) ' + 'breakpoints and\n' + 'single stepping at the source line level, inspection of stack ' + 'frames,\n' + 'source code listing, and evaluation of arbitrary Python code ' + 'in the\n' + 'context of any stack frame. It also supports post-mortem ' + 'debugging\n' + 'and can be called under program control.\n' + '\n' + 'The debugger is extensible --- it is actually defined as the ' + 'class\n' + '"Pdb". This is currently undocumented but easily understood by ' + 'reading\n' + 'the source. The extension interface uses the modules "bdb" ' + 'and "cmd".\n' + '\n' + 'The debugger\'s prompt is "(Pdb)". Typical usage to run a ' + 'program under\n' + 'control of the debugger is:\n' + '\n' + ' >>> import pdb\n' + ' >>> import mymodule\n' + " >>> pdb.run('mymodule.test()')\n" + ' > (0)?()\n' + ' (Pdb) continue\n' + ' > (1)?()\n' + ' (Pdb) continue\n' + " NameError: 'spam'\n" + ' > (1)?()\n' + ' (Pdb)\n' + '\n' + '"pdb.py" can also be invoked as a script to debug other ' + 'scripts. For\n' + 'example:\n' + '\n' + ' python -m pdb myscript.py\n' + '\n' + 'When invoked as a script, pdb will automatically enter ' + 'post-mortem\n' + 'debugging if the program being debugged exits abnormally. ' + 'After post-\n' + 'mortem debugging (or after normal exit of the program), pdb ' + 'will\n' + "restart the program. Automatic restarting preserves pdb's " + 'state (such\n' + 'as breakpoints) and in most cases is more useful than quitting ' + 'the\n' + "debugger upon program's exit.\n" + '\n' + 'New in version 2.4: Restarting post-mortem behavior added.\n' + '\n' + 'The typical usage to break into the debugger from a running ' + 'program is\n' + 'to insert\n' + '\n' + ' import pdb; pdb.set_trace()\n' + '\n' + 'at the location you want to break into the debugger. You can ' + 'then\n' + 'step through the code following this statement, and continue ' + 'running\n' + 'without the debugger using the "c" command.\n' + '\n' + 'The typical usage to inspect a crashed program is:\n' + '\n' + ' >>> import pdb\n' + ' >>> import mymodule\n' + ' >>> mymodule.test()\n' + ' Traceback (most recent call last):\n' + ' File "", line 1, in ?\n' + ' File "./mymodule.py", line 4, in test\n' + ' test2()\n' + ' File "./mymodule.py", line 3, in test2\n' + ' print spam\n' + ' NameError: spam\n' + ' >>> pdb.pm()\n' + ' > ./mymodule.py(3)test2()\n' + ' -> print spam\n' + ' (Pdb)\n' + '\n' + 'The module defines the following functions; each enters the ' + 'debugger\n' + 'in a slightly different way:\n' + '\n' + 'pdb.run(statement[, globals[, locals]])\n' + '\n' + ' Execute the *statement* (given as a string) under debugger ' + 'control.\n' + ' The debugger prompt appears before any code is executed; ' + 'you can\n' + ' set breakpoints and type "continue", or you can step ' + 'through the\n' + ' statement using "step" or "next" (all these commands are ' + 'explained\n' + ' below). The optional *globals* and *locals* arguments ' + 'specify the\n' + ' environment in which the code is executed; by default the\n' + ' dictionary of the module "__main__" is used. (See the ' + 'explanation\n' + ' of the "exec" statement or the "eval()" built-in ' + 'function.)\n' + '\n' + 'pdb.runeval(expression[, globals[, locals]])\n' + '\n' + ' Evaluate the *expression* (given as a string) under ' + 'debugger\n' + ' control. When "runeval()" returns, it returns the value of ' + 'the\n' + ' expression. Otherwise this function is similar to ' + '"run()".\n' + '\n' + 'pdb.runcall(function[, argument, ...])\n' + '\n' + ' Call the *function* (a function or method object, not a ' + 'string)\n' + ' with the given arguments. When "runcall()" returns, it ' + 'returns\n' + ' whatever the function call returned. The debugger prompt ' + 'appears\n' + ' as soon as the function is entered.\n' + '\n' + 'pdb.set_trace()\n' + '\n' + ' Enter the debugger at the calling stack frame. This is ' + 'useful to\n' + ' hard-code a breakpoint at a given point in a program, even ' + 'if the\n' + ' code is not otherwise being debugged (e.g. when an ' + 'assertion\n' + ' fails).\n' + '\n' + 'pdb.post_mortem([traceback])\n' + '\n' + ' Enter post-mortem debugging of the given *traceback* ' + 'object. If no\n' + ' *traceback* is given, it uses the one of the exception that ' + 'is\n' + ' currently being handled (an exception must be being handled ' + 'if the\n' + ' default is to be used).\n' + '\n' + 'pdb.pm()\n' + '\n' + ' Enter post-mortem debugging of the traceback found in\n' + ' "sys.last_traceback".\n' + '\n' + 'The "run*" functions and "set_trace()" are aliases for ' + 'instantiating\n' + 'the "Pdb" class and calling the method of the same name. If ' + 'you want\n' + 'to access further features, you have to do this yourself:\n' + '\n' + "class class pdb.Pdb(completekey='tab', stdin=None, " + 'stdout=None, skip=None)\n' + '\n' + ' "Pdb" is the debugger class.\n' + '\n' + ' The *completekey*, *stdin* and *stdout* arguments are ' + 'passed to the\n' + ' underlying "cmd.Cmd" class; see the description there.\n' + '\n' + ' The *skip* argument, if given, must be an iterable of ' + 'glob-style\n' + ' module name patterns. The debugger will not step into ' + 'frames that\n' + ' originate in a module that matches one of these patterns. ' + '[1]\n' + '\n' + ' Example call to enable tracing with *skip*:\n' + '\n' + " import pdb; pdb.Pdb(skip=['django.*']).set_trace()\n" + '\n' + ' New in version 2.7: The *skip* argument.\n' + '\n' + ' run(statement[, globals[, locals]])\n' + ' runeval(expression[, globals[, locals]])\n' + ' runcall(function[, argument, ...])\n' + ' set_trace()\n' + '\n' + ' See the documentation for the functions explained ' + 'above.\n', + 'del': '\n' + 'The "del" statement\n' + '*******************\n' + '\n' + ' del_stmt ::= "del" target_list\n' + '\n' + 'Deletion is recursively defined very similar to the way assignment ' + 'is\n' + 'defined. Rather than spelling it out in full details, here are ' + 'some\n' + 'hints.\n' + '\n' + 'Deletion of a target list recursively deletes each target, from ' + 'left\n' + 'to right.\n' + '\n' + 'Deletion of a name removes the binding of that name from the local ' + 'or\n' + 'global namespace, depending on whether the name occurs in a ' + '"global"\n' + 'statement in the same code block. If the name is unbound, a\n' + '"NameError" exception will be raised.\n' + '\n' + 'It is illegal to delete a name from the local namespace if it ' + 'occurs\n' + 'as a free variable in a nested block.\n' + '\n' + 'Deletion of attribute references, subscriptions and slicings is ' + 'passed\n' + 'to the primary object involved; deletion of a slicing is in ' + 'general\n' + 'equivalent to assignment of an empty slice of the right type (but ' + 'even\n' + 'this is determined by the sliced object).\n', + 'dict': '\n' + 'Dictionary displays\n' + '*******************\n' + '\n' + 'A dictionary display is a possibly empty series of key/datum ' + 'pairs\n' + 'enclosed in curly braces:\n' + '\n' + ' dict_display ::= "{" [key_datum_list | ' + 'dict_comprehension] "}"\n' + ' key_datum_list ::= key_datum ("," key_datum)* [","]\n' + ' key_datum ::= expression ":" expression\n' + ' dict_comprehension ::= expression ":" expression comp_for\n' + '\n' + 'A dictionary display yields a new dictionary object.\n' + '\n' + 'If a comma-separated sequence of key/datum pairs is given, they ' + 'are\n' + 'evaluated from left to right to define the entries of the ' + 'dictionary:\n' + 'each key object is used as a key into the dictionary to store the\n' + 'corresponding datum. This means that you can specify the same ' + 'key\n' + "multiple times in the key/datum list, and the final dictionary's " + 'value\n' + 'for that key will be the last one given.\n' + '\n' + 'A dict comprehension, in contrast to list and set comprehensions,\n' + 'needs two expressions separated with a colon followed by the ' + 'usual\n' + '"for" and "if" clauses. When the comprehension is run, the ' + 'resulting\n' + 'key and value elements are inserted in the new dictionary in the ' + 'order\n' + 'they are produced.\n' + '\n' + 'Restrictions on the types of the key values are listed earlier in\n' + 'section The standard type hierarchy. (To summarize, the key type\n' + 'should be *hashable*, which excludes all mutable objects.) ' + 'Clashes\n' + 'between duplicate keys are not detected; the last datum ' + '(textually\n' + 'rightmost in the display) stored for a given key value prevails.\n', + 'dynamic-features': '\n' + 'Interaction with dynamic features\n' + '*********************************\n' + '\n' + 'There are several cases where Python statements are ' + 'illegal when used\n' + 'in conjunction with nested scopes that contain free ' + 'variables.\n' + '\n' + 'If a variable is referenced in an enclosing scope, it ' + 'is illegal to\n' + 'delete the name. An error will be reported at compile ' + 'time.\n' + '\n' + 'If the wild card form of import --- "import *" --- is ' + 'used in a\n' + 'function and the function contains or is a nested ' + 'block with free\n' + 'variables, the compiler will raise a "SyntaxError".\n' + '\n' + 'If "exec" is used in a function and the function ' + 'contains or is a\n' + 'nested block with free variables, the compiler will ' + 'raise a\n' + '"SyntaxError" unless the exec explicitly specifies the ' + 'local namespace\n' + 'for the "exec". (In other words, "exec obj" would be ' + 'illegal, but\n' + '"exec obj in ns" would be legal.)\n' + '\n' + 'The "eval()", "execfile()", and "input()" functions ' + 'and the "exec"\n' + 'statement do not have access to the full environment ' + 'for resolving\n' + 'names. Names may be resolved in the local and global ' + 'namespaces of\n' + 'the caller. Free variables are not resolved in the ' + 'nearest enclosing\n' + 'namespace, but in the global namespace. [1] The "exec" ' + 'statement and\n' + 'the "eval()" and "execfile()" functions have optional ' + 'arguments to\n' + 'override the global and local namespace. If only one ' + 'namespace is\n' + 'specified, it is used for both.\n', + 'else': '\n' + 'The "if" statement\n' + '******************\n' + '\n' + 'The "if" statement is used for conditional execution:\n' + '\n' + ' if_stmt ::= "if" expression ":" suite\n' + ' ( "elif" expression ":" suite )*\n' + ' ["else" ":" suite]\n' + '\n' + 'It selects exactly one of the suites by evaluating the expressions ' + 'one\n' + 'by one until one is found to be true (see section Boolean ' + 'operations\n' + 'for the definition of true and false); then that suite is ' + 'executed\n' + '(and no other part of the "if" statement is executed or ' + 'evaluated).\n' + 'If all expressions are false, the suite of the "else" clause, if\n' + 'present, is executed.\n', + 'exceptions': '\n' + 'Exceptions\n' + '**********\n' + '\n' + 'Exceptions are a means of breaking out of the normal flow of ' + 'control\n' + 'of a code block in order to handle errors or other ' + 'exceptional\n' + 'conditions. An exception is *raised* at the point where the ' + 'error is\n' + 'detected; it may be *handled* by the surrounding code block ' + 'or by any\n' + 'code block that directly or indirectly invoked the code ' + 'block where\n' + 'the error occurred.\n' + '\n' + 'The Python interpreter raises an exception when it detects a ' + 'run-time\n' + 'error (such as division by zero). A Python program can ' + 'also\n' + 'explicitly raise an exception with the "raise" statement. ' + 'Exception\n' + 'handlers are specified with the "try" ... "except" ' + 'statement. The\n' + '"finally" clause of such a statement can be used to specify ' + 'cleanup\n' + 'code which does not handle the exception, but is executed ' + 'whether an\n' + 'exception occurred or not in the preceding code.\n' + '\n' + 'Python uses the "termination" model of error handling: an ' + 'exception\n' + 'handler can find out what happened and continue execution at ' + 'an outer\n' + 'level, but it cannot repair the cause of the error and retry ' + 'the\n' + 'failing operation (except by re-entering the offending piece ' + 'of code\n' + 'from the top).\n' + '\n' + 'When an exception is not handled at all, the interpreter ' + 'terminates\n' + 'execution of the program, or returns to its interactive main ' + 'loop. In\n' + 'either case, it prints a stack backtrace, except when the ' + 'exception is\n' + '"SystemExit".\n' + '\n' + 'Exceptions are identified by class instances. The "except" ' + 'clause is\n' + 'selected depending on the class of the instance: it must ' + 'reference the\n' + 'class of the instance or a base class thereof. The instance ' + 'can be\n' + 'received by the handler and can carry additional information ' + 'about the\n' + 'exceptional condition.\n' + '\n' + 'Exceptions can also be identified by strings, in which case ' + 'the\n' + '"except" clause is selected by object identity. An ' + 'arbitrary value\n' + 'can be raised along with the identifying string which can be ' + 'passed to\n' + 'the handler.\n' + '\n' + 'Note: Messages to exceptions are not part of the Python ' + 'API. Their\n' + ' contents may change from one version of Python to the next ' + 'without\n' + ' warning and should not be relied on by code which will run ' + 'under\n' + ' multiple versions of the interpreter.\n' + '\n' + 'See also the description of the "try" statement in section ' + 'The try\n' + 'statement and "raise" statement in section The raise ' + 'statement.\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] This limitation occurs because the code that is executed ' + 'by\n' + ' these operations is not available at the time the module ' + 'is\n' + ' compiled.\n', + 'exec': '\n' + 'The "exec" statement\n' + '********************\n' + '\n' + ' exec_stmt ::= "exec" or_expr ["in" expression ["," ' + 'expression]]\n' + '\n' + 'This statement supports dynamic execution of Python code. The ' + 'first\n' + 'expression should evaluate to either a Unicode string, a ' + '*Latin-1*\n' + 'encoded string, an open file object, a code object, or a tuple. ' + 'If it\n' + 'is a string, the string is parsed as a suite of Python statements\n' + 'which is then executed (unless a syntax error occurs). [1] If it ' + 'is an\n' + 'open file, the file is parsed until EOF and executed. If it is a ' + 'code\n' + 'object, it is simply executed. For the interpretation of a tuple, ' + 'see\n' + "below. In all cases, the code that's executed is expected to be " + 'valid\n' + 'as file input (see section File input). Be aware that the ' + '"return"\n' + 'and "yield" statements may not be used outside of function ' + 'definitions\n' + 'even within the context of code passed to the "exec" statement.\n' + '\n' + 'In all cases, if the optional parts are omitted, the code is ' + 'executed\n' + 'in the current scope. If only the first expression after "in" is\n' + 'specified, it should be a dictionary, which will be used for both ' + 'the\n' + 'global and the local variables. If two expressions are given, ' + 'they\n' + 'are used for the global and local variables, respectively. If\n' + 'provided, *locals* can be any mapping object. Remember that at ' + 'module\n' + 'level, globals and locals are the same dictionary. If two ' + 'separate\n' + 'objects are given as *globals* and *locals*, the code will be ' + 'executed\n' + 'as if it were embedded in a class definition.\n' + '\n' + 'The first expression may also be a tuple of length 2 or 3. In ' + 'this\n' + 'case, the optional parts must be omitted. The form "exec(expr,\n' + 'globals)" is equivalent to "exec expr in globals", while the form\n' + '"exec(expr, globals, locals)" is equivalent to "exec expr in ' + 'globals,\n' + 'locals". The tuple form of "exec" provides compatibility with ' + 'Python\n' + '3, where "exec" is a function rather than a statement.\n' + '\n' + 'Changed in version 2.4: Formerly, *locals* was required to be a\n' + 'dictionary.\n' + '\n' + 'As a side effect, an implementation may insert additional keys ' + 'into\n' + 'the dictionaries given besides those corresponding to variable ' + 'names\n' + 'set by the executed code. For example, the current implementation ' + 'may\n' + 'add a reference to the dictionary of the built-in module ' + '"__builtin__"\n' + 'under the key "__builtins__" (!).\n' + '\n' + "**Programmer's hints:** dynamic evaluation of expressions is " + 'supported\n' + 'by the built-in function "eval()". The built-in functions ' + '"globals()"\n' + 'and "locals()" return the current global and local dictionary,\n' + 'respectively, which may be useful to pass around for use by ' + '"exec".\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] Note that the parser only accepts the Unix-style end of line\n' + ' convention. If you are reading the code from a file, make sure ' + 'to\n' + ' use *universal newlines* mode to convert Windows or Mac-style\n' + ' newlines.\n', + 'execmodel': '\n' + 'Execution model\n' + '***************\n' + '\n' + '\n' + 'Naming and binding\n' + '==================\n' + '\n' + '*Names* refer to objects. Names are introduced by name ' + 'binding\n' + 'operations. Each occurrence of a name in the program text ' + 'refers to\n' + 'the *binding* of that name established in the innermost ' + 'function block\n' + 'containing the use.\n' + '\n' + 'A *block* is a piece of Python program text that is executed ' + 'as a\n' + 'unit. The following are blocks: a module, a function body, ' + 'and a class\n' + 'definition. Each command typed interactively is a block. A ' + 'script\n' + 'file (a file given as standard input to the interpreter or ' + 'specified\n' + 'on the interpreter command line the first argument) is a code ' + 'block.\n' + 'A script command (a command specified on the interpreter ' + 'command line\n' + "with the '**-c**' option) is a code block. The file read by " + 'the\n' + 'built-in function "execfile()" is a code block. The string ' + 'argument\n' + 'passed to the built-in function "eval()" and to the "exec" ' + 'statement\n' + 'is a code block. The expression read and evaluated by the ' + 'built-in\n' + 'function "input()" is a code block.\n' + '\n' + 'A code block is executed in an *execution frame*. A frame ' + 'contains\n' + 'some administrative information (used for debugging) and ' + 'determines\n' + "where and how execution continues after the code block's " + 'execution has\n' + 'completed.\n' + '\n' + 'A *scope* defines the visibility of a name within a block. ' + 'If a local\n' + 'variable is defined in a block, its scope includes that ' + 'block. If the\n' + 'definition occurs in a function block, the scope extends to ' + 'any blocks\n' + 'contained within the defining one, unless a contained block ' + 'introduces\n' + 'a different binding for the name. The scope of names defined ' + 'in a\n' + 'class block is limited to the class block; it does not extend ' + 'to the\n' + 'code blocks of methods -- this includes generator expressions ' + 'since\n' + 'they are implemented using a function scope. This means that ' + 'the\n' + 'following will fail:\n' + '\n' + ' class A:\n' + ' a = 42\n' + ' b = list(a + i for i in range(10))\n' + '\n' + 'When a name is used in a code block, it is resolved using the ' + 'nearest\n' + 'enclosing scope. The set of all such scopes visible to a ' + 'code block\n' + "is called the block's *environment*.\n" + '\n' + 'If a name is bound in a block, it is a local variable of that ' + 'block.\n' + 'If a name is bound at the module level, it is a global ' + 'variable. (The\n' + 'variables of the module code block are local and global.) If ' + 'a\n' + 'variable is used in a code block but not defined there, it is ' + 'a *free\n' + 'variable*.\n' + '\n' + 'When a name is not found at all, a "NameError" exception is ' + 'raised.\n' + 'If the name refers to a local variable that has not been ' + 'bound, a\n' + '"UnboundLocalError" exception is raised. "UnboundLocalError" ' + 'is a\n' + 'subclass of "NameError".\n' + '\n' + 'The following constructs bind names: formal parameters to ' + 'functions,\n' + '"import" statements, class and function definitions (these ' + 'bind the\n' + 'class or function name in the defining block), and targets ' + 'that are\n' + 'identifiers if occurring in an assignment, "for" loop header, ' + 'in the\n' + 'second position of an "except" clause header or after "as" in ' + 'a "with"\n' + 'statement. The "import" statement of the form "from ... ' + 'import *"\n' + 'binds all names defined in the imported module, except those ' + 'beginning\n' + 'with an underscore. This form may only be used at the module ' + 'level.\n' + '\n' + 'A target occurring in a "del" statement is also considered ' + 'bound for\n' + 'this purpose (though the actual semantics are to unbind the ' + 'name). It\n' + 'is illegal to unbind a name that is referenced by an ' + 'enclosing scope;\n' + 'the compiler will report a "SyntaxError".\n' + '\n' + 'Each assignment or import statement occurs within a block ' + 'defined by a\n' + 'class or function definition or at the module level (the ' + 'top-level\n' + 'code block).\n' + '\n' + 'If a name binding operation occurs anywhere within a code ' + 'block, all\n' + 'uses of the name within the block are treated as references ' + 'to the\n' + 'current block. This can lead to errors when a name is used ' + 'within a\n' + 'block before it is bound. This rule is subtle. Python lacks\n' + 'declarations and allows name binding operations to occur ' + 'anywhere\n' + 'within a code block. The local variables of a code block can ' + 'be\n' + 'determined by scanning the entire text of the block for name ' + 'binding\n' + 'operations.\n' + '\n' + 'If the global statement occurs within a block, all uses of ' + 'the name\n' + 'specified in the statement refer to the binding of that name ' + 'in the\n' + 'top-level namespace. Names are resolved in the top-level ' + 'namespace by\n' + 'searching the global namespace, i.e. the namespace of the ' + 'module\n' + 'containing the code block, and the builtins namespace, the ' + 'namespace\n' + 'of the module "__builtin__". The global namespace is ' + 'searched first.\n' + 'If the name is not found there, the builtins namespace is ' + 'searched.\n' + 'The global statement must precede all uses of the name.\n' + '\n' + 'The builtins namespace associated with the execution of a ' + 'code block\n' + 'is actually found by looking up the name "__builtins__" in ' + 'its global\n' + 'namespace; this should be a dictionary or a module (in the ' + 'latter case\n' + "the module's dictionary is used). By default, when in the " + '"__main__"\n' + 'module, "__builtins__" is the built-in module "__builtin__" ' + '(note: no\n' + '\'s\'); when in any other module, "__builtins__" is an alias ' + 'for the\n' + 'dictionary of the "__builtin__" module itself. ' + '"__builtins__" can be\n' + 'set to a user-created dictionary to create a weak form of ' + 'restricted\n' + 'execution.\n' + '\n' + '**CPython implementation detail:** Users should not touch\n' + '"__builtins__"; it is strictly an implementation detail. ' + 'Users\n' + 'wanting to override values in the builtins namespace should ' + '"import"\n' + 'the "__builtin__" (no \'s\') module and modify its ' + 'attributes\n' + 'appropriately.\n' + '\n' + 'The namespace for a module is automatically created the first ' + 'time a\n' + 'module is imported. The main module for a script is always ' + 'called\n' + '"__main__".\n' + '\n' + 'The "global" statement has the same scope as a name binding ' + 'operation\n' + 'in the same block. If the nearest enclosing scope for a free ' + 'variable\n' + 'contains a global statement, the free variable is treated as ' + 'a global.\n' + '\n' + 'A class definition is an executable statement that may use ' + 'and define\n' + 'names. These references follow the normal rules for name ' + 'resolution.\n' + 'The namespace of the class definition becomes the attribute ' + 'dictionary\n' + 'of the class. Names defined at the class scope are not ' + 'visible in\n' + 'methods.\n' + '\n' + '\n' + 'Interaction with dynamic features\n' + '---------------------------------\n' + '\n' + 'There are several cases where Python statements are illegal ' + 'when used\n' + 'in conjunction with nested scopes that contain free ' + 'variables.\n' + '\n' + 'If a variable is referenced in an enclosing scope, it is ' + 'illegal to\n' + 'delete the name. An error will be reported at compile time.\n' + '\n' + 'If the wild card form of import --- "import *" --- is used in ' + 'a\n' + 'function and the function contains or is a nested block with ' + 'free\n' + 'variables, the compiler will raise a "SyntaxError".\n' + '\n' + 'If "exec" is used in a function and the function contains or ' + 'is a\n' + 'nested block with free variables, the compiler will raise a\n' + '"SyntaxError" unless the exec explicitly specifies the local ' + 'namespace\n' + 'for the "exec". (In other words, "exec obj" would be ' + 'illegal, but\n' + '"exec obj in ns" would be legal.)\n' + '\n' + 'The "eval()", "execfile()", and "input()" functions and the ' + '"exec"\n' + 'statement do not have access to the full environment for ' + 'resolving\n' + 'names. Names may be resolved in the local and global ' + 'namespaces of\n' + 'the caller. Free variables are not resolved in the nearest ' + 'enclosing\n' + 'namespace, but in the global namespace. [1] The "exec" ' + 'statement and\n' + 'the "eval()" and "execfile()" functions have optional ' + 'arguments to\n' + 'override the global and local namespace. If only one ' + 'namespace is\n' + 'specified, it is used for both.\n' + '\n' + '\n' + 'Exceptions\n' + '==========\n' + '\n' + 'Exceptions are a means of breaking out of the normal flow of ' + 'control\n' + 'of a code block in order to handle errors or other ' + 'exceptional\n' + 'conditions. An exception is *raised* at the point where the ' + 'error is\n' + 'detected; it may be *handled* by the surrounding code block ' + 'or by any\n' + 'code block that directly or indirectly invoked the code block ' + 'where\n' + 'the error occurred.\n' + '\n' + 'The Python interpreter raises an exception when it detects a ' + 'run-time\n' + 'error (such as division by zero). A Python program can also\n' + 'explicitly raise an exception with the "raise" statement. ' + 'Exception\n' + 'handlers are specified with the "try" ... "except" ' + 'statement. The\n' + '"finally" clause of such a statement can be used to specify ' + 'cleanup\n' + 'code which does not handle the exception, but is executed ' + 'whether an\n' + 'exception occurred or not in the preceding code.\n' + '\n' + 'Python uses the "termination" model of error handling: an ' + 'exception\n' + 'handler can find out what happened and continue execution at ' + 'an outer\n' + 'level, but it cannot repair the cause of the error and retry ' + 'the\n' + 'failing operation (except by re-entering the offending piece ' + 'of code\n' + 'from the top).\n' + '\n' + 'When an exception is not handled at all, the interpreter ' + 'terminates\n' + 'execution of the program, or returns to its interactive main ' + 'loop. In\n' + 'either case, it prints a stack backtrace, except when the ' + 'exception is\n' + '"SystemExit".\n' + '\n' + 'Exceptions are identified by class instances. The "except" ' + 'clause is\n' + 'selected depending on the class of the instance: it must ' + 'reference the\n' + 'class of the instance or a base class thereof. The instance ' + 'can be\n' + 'received by the handler and can carry additional information ' + 'about the\n' + 'exceptional condition.\n' + '\n' + 'Exceptions can also be identified by strings, in which case ' + 'the\n' + '"except" clause is selected by object identity. An arbitrary ' + 'value\n' + 'can be raised along with the identifying string which can be ' + 'passed to\n' + 'the handler.\n' + '\n' + 'Note: Messages to exceptions are not part of the Python API. ' + 'Their\n' + ' contents may change from one version of Python to the next ' + 'without\n' + ' warning and should not be relied on by code which will run ' + 'under\n' + ' multiple versions of the interpreter.\n' + '\n' + 'See also the description of the "try" statement in section ' + 'The try\n' + 'statement and "raise" statement in section The raise ' + 'statement.\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] This limitation occurs because the code that is executed ' + 'by\n' + ' these operations is not available at the time the module ' + 'is\n' + ' compiled.\n', + 'exprlists': '\n' + 'Expression lists\n' + '****************\n' + '\n' + ' expression_list ::= expression ( "," expression )* [","]\n' + '\n' + 'An expression list containing at least one comma yields a ' + 'tuple. The\n' + 'length of the tuple is the number of expressions in the ' + 'list. The\n' + 'expressions are evaluated from left to right.\n' + '\n' + 'The trailing comma is required only to create a single tuple ' + '(a.k.a. a\n' + '*singleton*); it is optional in all other cases. A single ' + 'expression\n' + "without a trailing comma doesn't create a tuple, but rather " + 'yields the\n' + 'value of that expression. (To create an empty tuple, use an ' + 'empty pair\n' + 'of parentheses: "()".)\n', + 'floating': '\n' + 'Floating point literals\n' + '***********************\n' + '\n' + 'Floating point literals are described by the following ' + 'lexical\n' + 'definitions:\n' + '\n' + ' floatnumber ::= pointfloat | exponentfloat\n' + ' pointfloat ::= [intpart] fraction | intpart "."\n' + ' exponentfloat ::= (intpart | pointfloat) exponent\n' + ' intpart ::= digit+\n' + ' fraction ::= "." digit+\n' + ' exponent ::= ("e" | "E") ["+" | "-"] digit+\n' + '\n' + 'Note that the integer and exponent parts of floating point ' + 'numbers can\n' + 'look like octal integers, but are interpreted using radix 10. ' + 'For\n' + 'example, "077e010" is legal, and denotes the same number as ' + '"77e10".\n' + 'The allowed range of floating point literals is ' + 'implementation-\n' + 'dependent. Some examples of floating point literals:\n' + '\n' + ' 3.14 10. .001 1e100 3.14e-10 0e0\n' + '\n' + 'Note that numeric literals do not include a sign; a phrase ' + 'like "-1"\n' + 'is actually an expression composed of the unary operator "-" ' + 'and the\n' + 'literal "1".\n', + 'for': '\n' + 'The "for" statement\n' + '*******************\n' + '\n' + 'The "for" statement is used to iterate over the elements of a ' + 'sequence\n' + '(such as a string, tuple or list) or other iterable object:\n' + '\n' + ' for_stmt ::= "for" target_list "in" expression_list ":" suite\n' + ' ["else" ":" suite]\n' + '\n' + 'The expression list is evaluated once; it should yield an iterable\n' + 'object. An iterator is created for the result of the\n' + '"expression_list". The suite is then executed once for each item\n' + 'provided by the iterator, in the order of ascending indices. Each\n' + 'item in turn is assigned to the target list using the standard ' + 'rules\n' + 'for assignments, and then the suite is executed. When the items ' + 'are\n' + 'exhausted (which is immediately when the sequence is empty), the ' + 'suite\n' + 'in the "else" clause, if present, is executed, and the loop\n' + 'terminates.\n' + '\n' + 'A "break" statement executed in the first suite terminates the ' + 'loop\n' + 'without executing the "else" clause\'s suite. A "continue" ' + 'statement\n' + 'executed in the first suite skips the rest of the suite and ' + 'continues\n' + 'with the next item, or with the "else" clause if there was no next\n' + 'item.\n' + '\n' + 'The suite may assign to the variable(s) in the target list; this ' + 'does\n' + 'not affect the next item assigned to it.\n' + '\n' + 'The target list is not deleted when the loop is finished, but if ' + 'the\n' + 'sequence is empty, it will not have been assigned to at all by the\n' + 'loop. Hint: the built-in function "range()" returns a sequence of\n' + 'integers suitable to emulate the effect of Pascal\'s "for i := a to ' + 'b\n' + 'do"; e.g., "range(3)" returns the list "[0, 1, 2]".\n' + '\n' + 'Note: There is a subtlety when the sequence is being modified by ' + 'the\n' + ' loop (this can only occur for mutable sequences, i.e. lists). An\n' + ' internal counter is used to keep track of which item is used ' + 'next,\n' + ' and this is incremented on each iteration. When this counter ' + 'has\n' + ' reached the length of the sequence the loop terminates. This ' + 'means\n' + ' that if the suite deletes the current (or a previous) item from ' + 'the\n' + ' sequence, the next item will be skipped (since it gets the index ' + 'of\n' + ' the current item which has already been treated). Likewise, if ' + 'the\n' + ' suite inserts an item in the sequence before the current item, ' + 'the\n' + ' current item will be treated again the next time through the ' + 'loop.\n' + ' This can lead to nasty bugs that can be avoided by making a\n' + ' temporary copy using a slice of the whole sequence, e.g.,\n' + '\n' + ' for x in a[:]:\n' + ' if x < 0: a.remove(x)\n', + 'formatstrings': '\n' + 'Format String Syntax\n' + '********************\n' + '\n' + 'The "str.format()" method and the "Formatter" class share ' + 'the same\n' + 'syntax for format strings (although in the case of ' + '"Formatter",\n' + 'subclasses can define their own format string syntax).\n' + '\n' + 'Format strings contain "replacement fields" surrounded by ' + 'curly braces\n' + '"{}". Anything that is not contained in braces is ' + 'considered literal\n' + 'text, which is copied unchanged to the output. If you ' + 'need to include\n' + 'a brace character in the literal text, it can be escaped ' + 'by doubling:\n' + '"{{" and "}}".\n' + '\n' + 'The grammar for a replacement field is as follows:\n' + '\n' + ' replacement_field ::= "{" [field_name] ["!" ' + 'conversion] [":" format_spec] "}"\n' + ' field_name ::= arg_name ("." attribute_name ' + '| "[" element_index "]")*\n' + ' arg_name ::= [identifier | integer]\n' + ' attribute_name ::= identifier\n' + ' element_index ::= integer | index_string\n' + ' index_string ::= +\n' + ' conversion ::= "r" | "s"\n' + ' format_spec ::= \n' + '\n' + 'In less formal terms, the replacement field can start ' + 'with a\n' + '*field_name* that specifies the object whose value is to ' + 'be formatted\n' + 'and inserted into the output instead of the replacement ' + 'field. The\n' + '*field_name* is optionally followed by a *conversion* ' + 'field, which is\n' + 'preceded by an exclamation point "\'!\'", and a ' + '*format_spec*, which is\n' + 'preceded by a colon "\':\'". These specify a non-default ' + 'format for the\n' + 'replacement value.\n' + '\n' + 'See also the Format Specification Mini-Language section.\n' + '\n' + 'The *field_name* itself begins with an *arg_name* that is ' + 'either a\n' + "number or a keyword. If it's a number, it refers to a " + 'positional\n' + "argument, and if it's a keyword, it refers to a named " + 'keyword\n' + 'argument. If the numerical arg_names in a format string ' + 'are 0, 1, 2,\n' + '... in sequence, they can all be omitted (not just some) ' + 'and the\n' + 'numbers 0, 1, 2, ... will be automatically inserted in ' + 'that order.\n' + 'Because *arg_name* is not quote-delimited, it is not ' + 'possible to\n' + 'specify arbitrary dictionary keys (e.g., the strings ' + '"\'10\'" or\n' + '"\':-]\'") within a format string. The *arg_name* can be ' + 'followed by any\n' + 'number of index or attribute expressions. An expression ' + 'of the form\n' + '"\'.name\'" selects the named attribute using ' + '"getattr()", while an\n' + 'expression of the form "\'[index]\'" does an index lookup ' + 'using\n' + '"__getitem__()".\n' + '\n' + 'Changed in version 2.7: The positional argument ' + 'specifiers can be\n' + 'omitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n' + '\n' + 'Some simple format string examples:\n' + '\n' + ' "First, thou shalt count to {0}" # References first ' + 'positional argument\n' + ' "Bring me a {}" # Implicitly ' + 'references the first positional argument\n' + ' "From {} to {}" # Same as "From {0} ' + 'to {1}"\n' + ' "My quest is {name}" # References keyword ' + "argument 'name'\n" + ' "Weight in tons {0.weight}" # \'weight\' ' + 'attribute of first positional arg\n' + ' "Units destroyed: {players[0]}" # First element of ' + "keyword argument 'players'.\n" + '\n' + 'The *conversion* field causes a type coercion before ' + 'formatting.\n' + 'Normally, the job of formatting a value is done by the ' + '"__format__()"\n' + 'method of the value itself. However, in some cases it is ' + 'desirable to\n' + 'force a type to be formatted as a string, overriding its ' + 'own\n' + 'definition of formatting. By converting the value to a ' + 'string before\n' + 'calling "__format__()", the normal formatting logic is ' + 'bypassed.\n' + '\n' + 'Two conversion flags are currently supported: "\'!s\'" ' + 'which calls\n' + '"str()" on the value, and "\'!r\'" which calls "repr()".\n' + '\n' + 'Some examples:\n' + '\n' + ' "Harold\'s a clever {0!s}" # Calls str() on the ' + 'argument first\n' + ' "Bring out the holy {name!r}" # Calls repr() on the ' + 'argument first\n' + '\n' + 'The *format_spec* field contains a specification of how ' + 'the value\n' + 'should be presented, including such details as field ' + 'width, alignment,\n' + 'padding, decimal precision and so on. Each value type ' + 'can define its\n' + 'own "formatting mini-language" or interpretation of the ' + '*format_spec*.\n' + '\n' + 'Most built-in types support a common formatting ' + 'mini-language, which\n' + 'is described in the next section.\n' + '\n' + 'A *format_spec* field can also include nested replacement ' + 'fields\n' + 'within it. These nested replacement fields can contain ' + 'only a field\n' + 'name; conversion flags and format specifications are not ' + 'allowed. The\n' + 'replacement fields within the format_spec are substituted ' + 'before the\n' + '*format_spec* string is interpreted. This allows the ' + 'formatting of a\n' + 'value to be dynamically specified.\n' + '\n' + 'See the Format examples section for some examples.\n' + '\n' + '\n' + 'Format Specification Mini-Language\n' + '==================================\n' + '\n' + '"Format specifications" are used within replacement ' + 'fields contained\n' + 'within a format string to define how individual values ' + 'are presented\n' + '(see Format String Syntax). They can also be passed ' + 'directly to the\n' + 'built-in "format()" function. Each formattable type may ' + 'define how\n' + 'the format specification is to be interpreted.\n' + '\n' + 'Most built-in types implement the following options for ' + 'format\n' + 'specifications, although some of the formatting options ' + 'are only\n' + 'supported by the numeric types.\n' + '\n' + 'A general convention is that an empty format string ' + '("""") produces\n' + 'the same result as if you had called "str()" on the ' + 'value. A non-empty\n' + 'format string typically modifies the result.\n' + '\n' + 'The general form of a *standard format specifier* is:\n' + '\n' + ' format_spec ::= ' + '[[fill]align][sign][#][0][width][,][.precision][type]\n' + ' fill ::= \n' + ' align ::= "<" | ">" | "=" | "^"\n' + ' sign ::= "+" | "-" | " "\n' + ' width ::= integer\n' + ' precision ::= integer\n' + ' type ::= "b" | "c" | "d" | "e" | "E" | "f" | ' + '"F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n' + '\n' + 'If a valid *align* value is specified, it can be preceded ' + 'by a *fill*\n' + 'character that can be any character and defaults to a ' + 'space if\n' + 'omitted. Note that it is not possible to use "{" and "}" ' + 'as *fill*\n' + 'char while using the "str.format()" method; this ' + 'limitation however\n' + 'doesn\'t affect the "format()" function.\n' + '\n' + 'The meaning of the various alignment options is as ' + 'follows:\n' + '\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | Option | ' + 'Meaning ' + '|\n' + ' ' + '+===========+============================================================+\n' + ' | "\'<\'" | Forces the field to be left-aligned ' + 'within the available |\n' + ' | | space (this is the default for most ' + 'objects). |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'>\'" | Forces the field to be right-aligned ' + 'within the available |\n' + ' | | space (this is the default for ' + 'numbers). |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'=\'" | Forces the padding to be placed after ' + 'the sign (if any) |\n' + ' | | but before the digits. This is used for ' + 'printing fields |\n' + " | | in the form '+000000120'. This alignment " + 'option is only |\n' + ' | | valid for numeric ' + 'types. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'^\'" | Forces the field to be centered within ' + 'the available |\n' + ' | | ' + 'space. ' + '|\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + '\n' + 'Note that unless a minimum field width is defined, the ' + 'field width\n' + 'will always be the same size as the data to fill it, so ' + 'that the\n' + 'alignment option has no meaning in this case.\n' + '\n' + 'The *sign* option is only valid for number types, and can ' + 'be one of\n' + 'the following:\n' + '\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | Option | ' + 'Meaning ' + '|\n' + ' ' + '+===========+============================================================+\n' + ' | "\'+\'" | indicates that a sign should be used ' + 'for both positive as |\n' + ' | | well as negative ' + 'numbers. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'-\'" | indicates that a sign should be used ' + 'only for negative |\n' + ' | | numbers (this is the default ' + 'behavior). |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | space | indicates that a leading space should be ' + 'used on positive |\n' + ' | | numbers, and a minus sign on negative ' + 'numbers. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + '\n' + 'The "\'#\'" option is only valid for integers, and only ' + 'for binary,\n' + 'octal, or hexadecimal output. If present, it specifies ' + 'that the\n' + 'output will be prefixed by "\'0b\'", "\'0o\'", or ' + '"\'0x\'", respectively.\n' + '\n' + 'The "\',\'" option signals the use of a comma for a ' + 'thousands separator.\n' + 'For a locale aware separator, use the "\'n\'" integer ' + 'presentation type\n' + 'instead.\n' + '\n' + 'Changed in version 2.7: Added the "\',\'" option (see ' + 'also **PEP 378**).\n' + '\n' + '*width* is a decimal integer defining the minimum field ' + 'width. If not\n' + 'specified, then the field width will be determined by the ' + 'content.\n' + '\n' + 'Preceding the *width* field by a zero ("\'0\'") character ' + 'enables sign-\n' + 'aware zero-padding for numeric types. This is equivalent ' + 'to a *fill*\n' + 'character of "\'0\'" with an *alignment* type of ' + '"\'=\'".\n' + '\n' + 'The *precision* is a decimal number indicating how many ' + 'digits should\n' + 'be displayed after the decimal point for a floating point ' + 'value\n' + 'formatted with "\'f\'" and "\'F\'", or before and after ' + 'the decimal point\n' + 'for a floating point value formatted with "\'g\'" or ' + '"\'G\'". For non-\n' + 'number types the field indicates the maximum field size - ' + 'in other\n' + 'words, how many characters will be used from the field ' + 'content. The\n' + '*precision* is not allowed for integer values.\n' + '\n' + 'Finally, the *type* determines how the data should be ' + 'presented.\n' + '\n' + 'The available string presentation types are:\n' + '\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | Type | ' + 'Meaning ' + '|\n' + ' ' + '+===========+============================================================+\n' + ' | "\'s\'" | String format. This is the default ' + 'type for strings and |\n' + ' | | may be ' + 'omitted. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | None | The same as ' + '"\'s\'". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + '\n' + 'The available integer presentation types are:\n' + '\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | Type | ' + 'Meaning ' + '|\n' + ' ' + '+===========+============================================================+\n' + ' | "\'b\'" | Binary format. Outputs the number in ' + 'base 2. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'c\'" | Character. Converts the integer to the ' + 'corresponding |\n' + ' | | unicode character before ' + 'printing. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'d\'" | Decimal Integer. Outputs the number in ' + 'base 10. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'o\'" | Octal format. Outputs the number in ' + 'base 8. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'x\'" | Hex format. Outputs the number in base ' + '16, using lower- |\n' + ' | | case letters for the digits above ' + '9. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'X\'" | Hex format. Outputs the number in base ' + '16, using upper- |\n' + ' | | case letters for the digits above ' + '9. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'n\'" | Number. This is the same as "\'d\'", ' + 'except that it uses the |\n' + ' | | current locale setting to insert the ' + 'appropriate number |\n' + ' | | separator ' + 'characters. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | None | The same as ' + '"\'d\'". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + '\n' + 'In addition to the above presentation types, integers can ' + 'be formatted\n' + 'with the floating point presentation types listed below ' + '(except "\'n\'"\n' + 'and None). When doing so, "float()" is used to convert ' + 'the integer to\n' + 'a floating point number before formatting.\n' + '\n' + 'The available presentation types for floating point and ' + 'decimal values\n' + 'are:\n' + '\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | Type | ' + 'Meaning ' + '|\n' + ' ' + '+===========+============================================================+\n' + ' | "\'e\'" | Exponent notation. Prints the number ' + 'in scientific |\n' + " | | notation using the letter 'e' to " + 'indicate the exponent. |\n' + ' | | The default precision is ' + '"6". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'E\'" | Exponent notation. Same as "\'e\'" ' + 'except it uses an upper |\n' + " | | case 'E' as the separator " + 'character. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'f\'" | Fixed point. Displays the number as a ' + 'fixed-point number. |\n' + ' | | The default precision is ' + '"6". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'F\'" | Fixed point. Same as ' + '"\'f\'". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'g\'" | General format. For a given precision ' + '"p >= 1", this |\n' + ' | | rounds the number to "p" significant ' + 'digits and then |\n' + ' | | formats the result in either fixed-point ' + 'format or in |\n' + ' | | scientific notation, depending on its ' + 'magnitude. The |\n' + ' | | precise rules are as follows: suppose ' + 'that the result |\n' + ' | | formatted with presentation type "\'e\'" ' + 'and precision "p-1" |\n' + ' | | would have exponent "exp". Then if "-4 ' + '<= exp < p", the |\n' + ' | | number is formatted with presentation ' + 'type "\'f\'" and |\n' + ' | | precision "p-1-exp". Otherwise, the ' + 'number is formatted |\n' + ' | | with presentation type "\'e\'" and ' + 'precision "p-1". In both |\n' + ' | | cases insignificant trailing zeros are ' + 'removed from the |\n' + ' | | significand, and the decimal point is ' + 'also removed if |\n' + ' | | there are no remaining digits following ' + 'it. Positive and |\n' + ' | | negative infinity, positive and negative ' + 'zero, and nans, |\n' + ' | | are formatted as "inf", "-inf", "0", ' + '"-0" and "nan" |\n' + ' | | respectively, regardless of the ' + 'precision. A precision of |\n' + ' | | "0" is treated as equivalent to a ' + 'precision of "1". The |\n' + ' | | default precision is ' + '"6". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'G\'" | General format. Same as "\'g\'" except ' + 'switches to "\'E\'" if |\n' + ' | | the number gets too large. The ' + 'representations of infinity |\n' + ' | | and NaN are uppercased, ' + 'too. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'n\'" | Number. This is the same as "\'g\'", ' + 'except that it uses the |\n' + ' | | current locale setting to insert the ' + 'appropriate number |\n' + ' | | separator ' + 'characters. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | "\'%\'" | Percentage. Multiplies the number by ' + '100 and displays in |\n' + ' | | fixed ("\'f\'") format, followed by a ' + 'percent sign. |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + ' | None | The same as ' + '"\'g\'". |\n' + ' ' + '+-----------+------------------------------------------------------------+\n' + '\n' + '\n' + 'Format examples\n' + '===============\n' + '\n' + 'This section contains examples of the new format syntax ' + 'and comparison\n' + 'with the old "%"-formatting.\n' + '\n' + 'In most of the cases the syntax is similar to the old ' + '"%"-formatting,\n' + 'with the addition of the "{}" and with ":" used instead ' + 'of "%". For\n' + 'example, "\'%03.2f\'" can be translated to ' + '"\'{:03.2f}\'".\n' + '\n' + 'The new format syntax also supports new and different ' + 'options, shown\n' + 'in the follow examples.\n' + '\n' + 'Accessing arguments by position:\n' + '\n' + " >>> '{0}, {1}, {2}'.format('a', 'b', 'c')\n" + " 'a, b, c'\n" + " >>> '{}, {}, {}'.format('a', 'b', 'c') # 2.7+ only\n" + " 'a, b, c'\n" + " >>> '{2}, {1}, {0}'.format('a', 'b', 'c')\n" + " 'c, b, a'\n" + " >>> '{2}, {1}, {0}'.format(*'abc') # unpacking " + 'argument sequence\n' + " 'c, b, a'\n" + " >>> '{0}{1}{0}'.format('abra', 'cad') # arguments' " + 'indices can be repeated\n' + " 'abracadabra'\n" + '\n' + 'Accessing arguments by name:\n' + '\n' + " >>> 'Coordinates: {latitude}, " + "{longitude}'.format(latitude='37.24N', " + "longitude='-115.81W')\n" + " 'Coordinates: 37.24N, -115.81W'\n" + " >>> coord = {'latitude': '37.24N', 'longitude': " + "'-115.81W'}\n" + " >>> 'Coordinates: {latitude}, " + "{longitude}'.format(**coord)\n" + " 'Coordinates: 37.24N, -115.81W'\n" + '\n' + "Accessing arguments' attributes:\n" + '\n' + ' >>> c = 3-5j\n' + " >>> ('The complex number {0} is formed from the real " + "part {0.real} '\n" + " ... 'and the imaginary part {0.imag}.').format(c)\n" + " 'The complex number (3-5j) is formed from the real " + "part 3.0 and the imaginary part -5.0.'\n" + ' >>> class Point(object):\n' + ' ... def __init__(self, x, y):\n' + ' ... self.x, self.y = x, y\n' + ' ... def __str__(self):\n' + " ... return 'Point({self.x}, " + "{self.y})'.format(self=self)\n" + ' ...\n' + ' >>> str(Point(4, 2))\n' + " 'Point(4, 2)'\n" + '\n' + "Accessing arguments' items:\n" + '\n' + ' >>> coord = (3, 5)\n' + " >>> 'X: {0[0]}; Y: {0[1]}'.format(coord)\n" + " 'X: 3; Y: 5'\n" + '\n' + 'Replacing "%s" and "%r":\n' + '\n' + ' >>> "repr() shows quotes: {!r}; str() doesn\'t: ' + '{!s}".format(\'test1\', \'test2\')\n' + ' "repr() shows quotes: \'test1\'; str() doesn\'t: ' + 'test2"\n' + '\n' + 'Aligning the text and specifying a width:\n' + '\n' + " >>> '{:<30}'.format('left aligned')\n" + " 'left aligned '\n" + " >>> '{:>30}'.format('right aligned')\n" + " ' right aligned'\n" + " >>> '{:^30}'.format('centered')\n" + " ' centered '\n" + " >>> '{:*^30}'.format('centered') # use '*' as a fill " + 'char\n' + " '***********centered***********'\n" + '\n' + 'Replacing "%+f", "%-f", and "% f" and specifying a sign:\n' + '\n' + " >>> '{:+f}; {:+f}'.format(3.14, -3.14) # show it " + 'always\n' + " '+3.140000; -3.140000'\n" + " >>> '{: f}; {: f}'.format(3.14, -3.14) # show a space " + 'for positive numbers\n' + " ' 3.140000; -3.140000'\n" + " >>> '{:-f}; {:-f}'.format(3.14, -3.14) # show only " + "the minus -- same as '{:f}; {:f}'\n" + " '3.140000; -3.140000'\n" + '\n' + 'Replacing "%x" and "%o" and converting the value to ' + 'different bases:\n' + '\n' + ' >>> # format also supports binary numbers\n' + ' >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: ' + '{0:b}".format(42)\n' + " 'int: 42; hex: 2a; oct: 52; bin: 101010'\n" + ' >>> # with 0x, 0o, or 0b as prefix:\n' + ' >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: ' + '{0:#b}".format(42)\n' + " 'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'\n" + '\n' + 'Using the comma as a thousands separator:\n' + '\n' + " >>> '{:,}'.format(1234567890)\n" + " '1,234,567,890'\n" + '\n' + 'Expressing a percentage:\n' + '\n' + ' >>> points = 19.5\n' + ' >>> total = 22\n' + " >>> 'Correct answers: {:.2%}'.format(points/total)\n" + " 'Correct answers: 88.64%'\n" + '\n' + 'Using type-specific formatting:\n' + '\n' + ' >>> import datetime\n' + ' >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n' + " >>> '{:%Y-%m-%d %H:%M:%S}'.format(d)\n" + " '2010-07-04 12:15:58'\n" + '\n' + 'Nesting arguments and more complex examples:\n' + '\n' + " >>> for align, text in zip('<^>', ['left', 'center', " + "'right']):\n" + " ... '{0:{fill}{align}16}'.format(text, fill=align, " + 'align=align)\n' + ' ...\n' + " 'left<<<<<<<<<<<<'\n" + " '^^^^^center^^^^^'\n" + " '>>>>>>>>>>>right'\n" + ' >>>\n' + ' >>> octets = [192, 168, 0, 1]\n' + " >>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets)\n" + " 'C0A80001'\n" + ' >>> int(_, 16)\n' + ' 3232235521\n' + ' >>>\n' + ' >>> width = 5\n' + ' >>> for num in range(5,12):\n' + " ... for base in 'dXob':\n" + " ... print '{0:{width}{base}}'.format(num, " + 'base=base, width=width),\n' + ' ... print\n' + ' ...\n' + ' 5 5 5 101\n' + ' 6 6 6 110\n' + ' 7 7 7 111\n' + ' 8 8 10 1000\n' + ' 9 9 11 1001\n' + ' 10 A 12 1010\n' + ' 11 B 13 1011\n', + 'function': '\n' + 'Function definitions\n' + '********************\n' + '\n' + 'A function definition defines a user-defined function object ' + '(see\n' + 'section The standard type hierarchy):\n' + '\n' + ' decorated ::= decorators (classdef | funcdef)\n' + ' decorators ::= decorator+\n' + ' decorator ::= "@" dotted_name ["(" [argument_list ' + '[","]] ")"] NEWLINE\n' + ' funcdef ::= "def" funcname "(" [parameter_list] ")" ' + '":" suite\n' + ' dotted_name ::= identifier ("." identifier)*\n' + ' parameter_list ::= (defparameter ",")*\n' + ' ( "*" identifier ["," "**" identifier]\n' + ' | "**" identifier\n' + ' | defparameter [","] )\n' + ' defparameter ::= parameter ["=" expression]\n' + ' sublist ::= parameter ("," parameter)* [","]\n' + ' parameter ::= identifier | "(" sublist ")"\n' + ' funcname ::= identifier\n' + '\n' + 'A function definition is an executable statement. Its ' + 'execution binds\n' + 'the function name in the current local namespace to a function ' + 'object\n' + '(a wrapper around the executable code for the function). ' + 'This\n' + 'function object contains a reference to the current global ' + 'namespace\n' + 'as the global namespace to be used when the function is ' + 'called.\n' + '\n' + 'The function definition does not execute the function body; ' + 'this gets\n' + 'executed only when the function is called. [3]\n' + '\n' + 'A function definition may be wrapped by one or more ' + '*decorator*\n' + 'expressions. Decorator expressions are evaluated when the ' + 'function is\n' + 'defined, in the scope that contains the function definition. ' + 'The\n' + 'result must be a callable, which is invoked with the function ' + 'object\n' + 'as the only argument. The returned value is bound to the ' + 'function name\n' + 'instead of the function object. Multiple decorators are ' + 'applied in\n' + 'nested fashion. For example, the following code:\n' + '\n' + ' @f1(arg)\n' + ' @f2\n' + ' def func(): pass\n' + '\n' + 'is equivalent to:\n' + '\n' + ' def func(): pass\n' + ' func = f1(arg)(f2(func))\n' + '\n' + 'When one or more top-level *parameters* have the form ' + '*parameter* "="\n' + '*expression*, the function is said to have "default parameter ' + 'values."\n' + 'For a parameter with a default value, the corresponding ' + '*argument* may\n' + "be omitted from a call, in which case the parameter's default " + 'value is\n' + 'substituted. If a parameter has a default value, all ' + 'following\n' + 'parameters must also have a default value --- this is a ' + 'syntactic\n' + 'restriction that is not expressed by the grammar.\n' + '\n' + '**Default parameter values are evaluated when the function ' + 'definition\n' + 'is executed.** This means that the expression is evaluated ' + 'once, when\n' + 'the function is defined, and that the same "pre-computed" ' + 'value is\n' + 'used for each call. This is especially important to ' + 'understand when a\n' + 'default parameter is a mutable object, such as a list or a ' + 'dictionary:\n' + 'if the function modifies the object (e.g. by appending an item ' + 'to a\n' + 'list), the default value is in effect modified. This is ' + 'generally not\n' + 'what was intended. A way around this is to use "None" as ' + 'the\n' + 'default, and explicitly test for it in the body of the ' + 'function, e.g.:\n' + '\n' + ' def whats_on_the_telly(penguin=None):\n' + ' if penguin is None:\n' + ' penguin = []\n' + ' penguin.append("property of the zoo")\n' + ' return penguin\n' + '\n' + 'Function call semantics are described in more detail in ' + 'section Calls.\n' + 'A function call always assigns values to all parameters ' + 'mentioned in\n' + 'the parameter list, either from position arguments, from ' + 'keyword\n' + 'arguments, or from default values. If the form ' + '""*identifier"" is\n' + 'present, it is initialized to a tuple receiving any excess ' + 'positional\n' + 'parameters, defaulting to the empty tuple. If the form\n' + '""**identifier"" is present, it is initialized to a new ' + 'dictionary\n' + 'receiving any excess keyword arguments, defaulting to a new ' + 'empty\n' + 'dictionary.\n' + '\n' + 'It is also possible to create anonymous functions (functions ' + 'not bound\n' + 'to a name), for immediate use in expressions. This uses ' + 'lambda\n' + 'expressions, described in section Lambdas. Note that the ' + 'lambda\n' + 'expression is merely a shorthand for a simplified function ' + 'definition;\n' + 'a function defined in a ""def"" statement can be passed around ' + 'or\n' + 'assigned to another name just like a function defined by a ' + 'lambda\n' + 'expression. The ""def"" form is actually more powerful since ' + 'it\n' + 'allows the execution of multiple statements.\n' + '\n' + "**Programmer's note:** Functions are first-class objects. A " + '""def""\n' + 'form executed inside a function definition defines a local ' + 'function\n' + 'that can be returned or passed around. Free variables used in ' + 'the\n' + 'nested function can access the local variables of the ' + 'function\n' + 'containing the def. See section Naming and binding for ' + 'details.\n', + 'global': '\n' + 'The "global" statement\n' + '**********************\n' + '\n' + ' global_stmt ::= "global" identifier ("," identifier)*\n' + '\n' + 'The "global" statement is a declaration which holds for the ' + 'entire\n' + 'current code block. It means that the listed identifiers are to ' + 'be\n' + 'interpreted as globals. It would be impossible to assign to a ' + 'global\n' + 'variable without "global", although free variables may refer to\n' + 'globals without being declared global.\n' + '\n' + 'Names listed in a "global" statement must not be used in the ' + 'same code\n' + 'block textually preceding that "global" statement.\n' + '\n' + 'Names listed in a "global" statement must not be defined as ' + 'formal\n' + 'parameters or in a "for" loop control target, "class" ' + 'definition,\n' + 'function definition, or "import" statement.\n' + '\n' + '**CPython implementation detail:** The current implementation ' + 'does not\n' + 'enforce the latter two restrictions, but programs should not ' + 'abuse\n' + 'this freedom, as future implementations may enforce them or ' + 'silently\n' + 'change the meaning of the program.\n' + '\n' + '**Programmer\'s note:** the "global" is a directive to the ' + 'parser. It\n' + 'applies only to code parsed at the same time as the "global"\n' + 'statement. In particular, a "global" statement contained in an ' + '"exec"\n' + 'statement does not affect the code block *containing* the ' + '"exec"\n' + 'statement, and code contained in an "exec" statement is ' + 'unaffected by\n' + '"global" statements in the code containing the "exec" ' + 'statement. The\n' + 'same applies to the "eval()", "execfile()" and "compile()" ' + 'functions.\n', + 'id-classes': '\n' + 'Reserved classes of identifiers\n' + '*******************************\n' + '\n' + 'Certain classes of identifiers (besides keywords) have ' + 'special\n' + 'meanings. These classes are identified by the patterns of ' + 'leading and\n' + 'trailing underscore characters:\n' + '\n' + '"_*"\n' + ' Not imported by "from module import *". The special ' + 'identifier "_"\n' + ' is used in the interactive interpreter to store the ' + 'result of the\n' + ' last evaluation; it is stored in the "__builtin__" ' + 'module. When\n' + ' not in interactive mode, "_" has no special meaning and ' + 'is not\n' + ' defined. See section The import statement.\n' + '\n' + ' Note: The name "_" is often used in conjunction with\n' + ' internationalization; refer to the documentation for ' + 'the\n' + ' "gettext" module for more information on this ' + 'convention.\n' + '\n' + '"__*__"\n' + ' System-defined names. These names are defined by the ' + 'interpreter\n' + ' and its implementation (including the standard library). ' + 'Current\n' + ' system names are discussed in the Special method names ' + 'section and\n' + ' elsewhere. More will likely be defined in future ' + 'versions of\n' + ' Python. *Any* use of "__*__" names, in any context, that ' + 'does not\n' + ' follow explicitly documented use, is subject to breakage ' + 'without\n' + ' warning.\n' + '\n' + '"__*"\n' + ' Class-private names. Names in this category, when used ' + 'within the\n' + ' context of a class definition, are re-written to use a ' + 'mangled form\n' + ' to help avoid name clashes between "private" attributes ' + 'of base and\n' + ' derived classes. See section Identifiers (Names).\n', + 'identifiers': '\n' + 'Identifiers and keywords\n' + '************************\n' + '\n' + 'Identifiers (also referred to as *names*) are described by ' + 'the\n' + 'following lexical definitions:\n' + '\n' + ' identifier ::= (letter|"_") (letter | digit | "_")*\n' + ' letter ::= lowercase | uppercase\n' + ' lowercase ::= "a"..."z"\n' + ' uppercase ::= "A"..."Z"\n' + ' digit ::= "0"..."9"\n' + '\n' + 'Identifiers are unlimited in length. Case is significant.\n' + '\n' + '\n' + 'Keywords\n' + '========\n' + '\n' + 'The following identifiers are used as reserved words, or ' + '*keywords* of\n' + 'the language, and cannot be used as ordinary identifiers. ' + 'They must\n' + 'be spelled exactly as written here:\n' + '\n' + ' and del from not while\n' + ' as elif global or with\n' + ' assert else if pass yield\n' + ' break except import print\n' + ' class exec in raise\n' + ' continue finally is return\n' + ' def for lambda try\n' + '\n' + 'Changed in version 2.4: "None" became a constant and is now ' + 'recognized\n' + 'by the compiler as a name for the built-in object "None". ' + 'Although it\n' + 'is not a keyword, you cannot assign a different object to ' + 'it.\n' + '\n' + 'Changed in version 2.5: Using "as" and "with" as ' + 'identifiers triggers\n' + 'a warning. To use them as keywords, enable the ' + '"with_statement"\n' + 'future feature .\n' + '\n' + 'Changed in version 2.6: "as" and "with" are full keywords.\n' + '\n' + '\n' + 'Reserved classes of identifiers\n' + '===============================\n' + '\n' + 'Certain classes of identifiers (besides keywords) have ' + 'special\n' + 'meanings. These classes are identified by the patterns of ' + 'leading and\n' + 'trailing underscore characters:\n' + '\n' + '"_*"\n' + ' Not imported by "from module import *". The special ' + 'identifier "_"\n' + ' is used in the interactive interpreter to store the ' + 'result of the\n' + ' last evaluation; it is stored in the "__builtin__" ' + 'module. When\n' + ' not in interactive mode, "_" has no special meaning and ' + 'is not\n' + ' defined. See section The import statement.\n' + '\n' + ' Note: The name "_" is often used in conjunction with\n' + ' internationalization; refer to the documentation for ' + 'the\n' + ' "gettext" module for more information on this ' + 'convention.\n' + '\n' + '"__*__"\n' + ' System-defined names. These names are defined by the ' + 'interpreter\n' + ' and its implementation (including the standard ' + 'library). Current\n' + ' system names are discussed in the Special method names ' + 'section and\n' + ' elsewhere. More will likely be defined in future ' + 'versions of\n' + ' Python. *Any* use of "__*__" names, in any context, ' + 'that does not\n' + ' follow explicitly documented use, is subject to breakage ' + 'without\n' + ' warning.\n' + '\n' + '"__*"\n' + ' Class-private names. Names in this category, when used ' + 'within the\n' + ' context of a class definition, are re-written to use a ' + 'mangled form\n' + ' to help avoid name clashes between "private" attributes ' + 'of base and\n' + ' derived classes. See section Identifiers (Names).\n', + 'if': '\n' + 'The "if" statement\n' + '******************\n' + '\n' + 'The "if" statement is used for conditional execution:\n' + '\n' + ' if_stmt ::= "if" expression ":" suite\n' + ' ( "elif" expression ":" suite )*\n' + ' ["else" ":" suite]\n' + '\n' + 'It selects exactly one of the suites by evaluating the expressions ' + 'one\n' + 'by one until one is found to be true (see section Boolean ' + 'operations\n' + 'for the definition of true and false); then that suite is executed\n' + '(and no other part of the "if" statement is executed or evaluated).\n' + 'If all expressions are false, the suite of the "else" clause, if\n' + 'present, is executed.\n', + 'imaginary': '\n' + 'Imaginary literals\n' + '******************\n' + '\n' + 'Imaginary literals are described by the following lexical ' + 'definitions:\n' + '\n' + ' imagnumber ::= (floatnumber | intpart) ("j" | "J")\n' + '\n' + 'An imaginary literal yields a complex number with a real part ' + 'of 0.0.\n' + 'Complex numbers are represented as a pair of floating point ' + 'numbers\n' + 'and have the same restrictions on their range. To create a ' + 'complex\n' + 'number with a nonzero real part, add a floating point number ' + 'to it,\n' + 'e.g., "(3+4j)". Some examples of imaginary literals:\n' + '\n' + ' 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', + 'import': '\n' + 'The "import" statement\n' + '**********************\n' + '\n' + ' import_stmt ::= "import" module ["as" name] ( "," module ' + '["as" name] )*\n' + ' | "from" relative_module "import" identifier ' + '["as" name]\n' + ' ( "," identifier ["as" name] )*\n' + ' | "from" relative_module "import" "(" ' + 'identifier ["as" name]\n' + ' ( "," identifier ["as" name] )* [","] ")"\n' + ' | "from" module "import" "*"\n' + ' module ::= (identifier ".")* identifier\n' + ' relative_module ::= "."* module | "."+\n' + ' name ::= identifier\n' + '\n' + 'Import statements are executed in two steps: (1) find a module, ' + 'and\n' + 'initialize it if necessary; (2) define a name or names in the ' + 'local\n' + 'namespace (of the scope where the "import" statement occurs). ' + 'The\n' + 'statement comes in two forms differing on whether it uses the ' + '"from"\n' + 'keyword. The first form (without "from") repeats these steps for ' + 'each\n' + 'identifier in the list. The form with "from" performs step (1) ' + 'once,\n' + 'and then performs step (2) repeatedly.\n' + '\n' + 'To understand how step (1) occurs, one must first understand ' + 'how\n' + 'Python handles hierarchical naming of modules. To help organize\n' + 'modules and provide a hierarchy in naming, Python has a concept ' + 'of\n' + 'packages. A package can contain other packages and modules ' + 'while\n' + 'modules cannot contain other modules or packages. From a file ' + 'system\n' + 'perspective, packages are directories and modules are files.\n' + '\n' + 'Once the name of the module is known (unless otherwise ' + 'specified, the\n' + 'term "module" will refer to both packages and modules), ' + 'searching for\n' + 'the module or package can begin. The first place checked is\n' + '"sys.modules", the cache of all modules that have been imported\n' + 'previously. If the module is found there then it is used in step ' + '(2)\n' + 'of import.\n' + '\n' + 'If the module is not found in the cache, then "sys.meta_path" ' + 'is\n' + 'searched (the specification for "sys.meta_path" can be found in ' + '**PEP\n' + '302**). The object is a list of *finder* objects which are ' + 'queried in\n' + 'order as to whether they know how to load the module by calling ' + 'their\n' + '"find_module()" method with the name of the module. If the ' + 'module\n' + 'happens to be contained within a package (as denoted by the ' + 'existence\n' + 'of a dot in the name), then a second argument to "find_module()" ' + 'is\n' + 'given as the value of the "__path__" attribute from the parent ' + 'package\n' + '(everything up to the last dot in the name of the module being\n' + 'imported). If a finder can find the module it returns a ' + '*loader*\n' + '(discussed later) or returns "None".\n' + '\n' + 'If none of the finders on "sys.meta_path" are able to find the ' + 'module\n' + 'then some implicitly defined finders are queried. ' + 'Implementations of\n' + 'Python vary in what implicit meta path finders are defined. The ' + 'one\n' + 'they all do define, though, is one that handles ' + '"sys.path_hooks",\n' + '"sys.path_importer_cache", and "sys.path".\n' + '\n' + 'The implicit finder searches for the requested module in the ' + '"paths"\n' + 'specified in one of two places ("paths" do not have to be file ' + 'system\n' + 'paths). If the module being imported is supposed to be ' + 'contained\n' + 'within a package then the second argument passed to ' + '"find_module()",\n' + '"__path__" on the parent package, is used as the source of ' + 'paths. If\n' + 'the module is not contained in a package then "sys.path" is used ' + 'as\n' + 'the source of paths.\n' + '\n' + 'Once the source of paths is chosen it is iterated over to find ' + 'a\n' + 'finder that can handle that path. The dict at\n' + '"sys.path_importer_cache" caches finders for paths and is ' + 'checked for\n' + 'a finder. If the path does not have a finder cached then\n' + '"sys.path_hooks" is searched by calling each object in the list ' + 'with a\n' + 'single argument of the path, returning a finder or raises\n' + '"ImportError". If a finder is returned then it is cached in\n' + '"sys.path_importer_cache" and then used for that path entry. If ' + 'no\n' + 'finder can be found but the path exists then a value of "None" ' + 'is\n' + 'stored in "sys.path_importer_cache" to signify that an implicit, ' + 'file-\n' + 'based finder that handles modules stored as individual files ' + 'should be\n' + 'used for that path. If the path does not exist then a finder ' + 'which\n' + 'always returns "None" is placed in the cache for the path.\n' + '\n' + 'If no finder can find the module then "ImportError" is raised.\n' + 'Otherwise some finder returned a loader whose "load_module()" ' + 'method\n' + 'is called with the name of the module to load (see **PEP 302** ' + 'for the\n' + 'original definition of loaders). A loader has several ' + 'responsibilities\n' + 'to perform on a module it loads. First, if the module already ' + 'exists\n' + 'in "sys.modules" (a possibility if the loader is called outside ' + 'of the\n' + 'import machinery) then it is to use that module for ' + 'initialization and\n' + 'not a new module. But if the module does not exist in ' + '"sys.modules"\n' + 'then it is to be added to that dict before initialization ' + 'begins. If\n' + 'an error occurs during loading of the module and it was added ' + 'to\n' + '"sys.modules" it is to be removed from the dict. If an error ' + 'occurs\n' + 'but the module was already in "sys.modules" it is left in the ' + 'dict.\n' + '\n' + 'The loader must set several attributes on the module. "__name__" ' + 'is to\n' + 'be set to the name of the module. "__file__" is to be the "path" ' + 'to\n' + 'the file unless the module is built-in (and thus listed in\n' + '"sys.builtin_module_names") in which case the attribute is not ' + 'set. If\n' + 'what is being imported is a package then "__path__" is to be set ' + 'to a\n' + 'list of paths to be searched when looking for modules and ' + 'packages\n' + 'contained within the package being imported. "__package__" is ' + 'optional\n' + 'but should be set to the name of package that contains the ' + 'module or\n' + 'package (the empty string is used for module not contained in a\n' + 'package). "__loader__" is also optional but should be set to ' + 'the\n' + 'loader object that is loading the module.\n' + '\n' + 'If an error occurs during loading then the loader raises ' + '"ImportError"\n' + 'if some other exception is not already being propagated. ' + 'Otherwise the\n' + 'loader returns the module that was loaded and initialized.\n' + '\n' + 'When step (1) finishes without raising an exception, step (2) ' + 'can\n' + 'begin.\n' + '\n' + 'The first form of "import" statement binds the module name in ' + 'the\n' + 'local namespace to the module object, and then goes on to import ' + 'the\n' + 'next identifier, if any. If the module name is followed by ' + '"as", the\n' + 'name following "as" is used as the local name for the module.\n' + '\n' + 'The "from" form does not bind the module name: it goes through ' + 'the\n' + 'list of identifiers, looks each one of them up in the module ' + 'found in\n' + 'step (1), and binds the name in the local namespace to the ' + 'object thus\n' + 'found. As with the first form of "import", an alternate local ' + 'name\n' + 'can be supplied by specifying ""as" localname". If a name is ' + 'not\n' + 'found, "ImportError" is raised. If the list of identifiers is\n' + 'replaced by a star ("\'*\'"), all public names defined in the ' + 'module are\n' + 'bound in the local namespace of the "import" statement..\n' + '\n' + 'The *public names* defined by a module are determined by ' + 'checking the\n' + 'module\'s namespace for a variable named "__all__"; if defined, ' + 'it must\n' + 'be a sequence of strings which are names defined or imported by ' + 'that\n' + 'module. The names given in "__all__" are all considered public ' + 'and\n' + 'are required to exist. If "__all__" is not defined, the set of ' + 'public\n' + "names includes all names found in the module's namespace which " + 'do not\n' + 'begin with an underscore character ("\'_\'"). "__all__" should ' + 'contain\n' + 'the entire public API. It is intended to avoid accidentally ' + 'exporting\n' + 'items that are not part of the API (such as library modules ' + 'which were\n' + 'imported and used within the module).\n' + '\n' + 'The "from" form with "*" may only occur in a module scope. If ' + 'the\n' + 'wild card form of import --- "import *" --- is used in a ' + 'function and\n' + 'the function contains or is a nested block with free variables, ' + 'the\n' + 'compiler will raise a "SyntaxError".\n' + '\n' + 'When specifying what module to import you do not have to specify ' + 'the\n' + 'absolute name of the module. When a module or package is ' + 'contained\n' + 'within another package it is possible to make a relative import ' + 'within\n' + 'the same top package without having to mention the package name. ' + 'By\n' + 'using leading dots in the specified module or package after ' + '"from" you\n' + 'can specify how high to traverse up the current package ' + 'hierarchy\n' + 'without specifying exact names. One leading dot means the ' + 'current\n' + 'package where the module making the import exists. Two dots ' + 'means up\n' + 'one package level. Three dots is up two levels, etc. So if you ' + 'execute\n' + '"from . import mod" from a module in the "pkg" package then you ' + 'will\n' + 'end up importing "pkg.mod". If you execute "from ..subpkg2 ' + 'import mod"\n' + 'from within "pkg.subpkg1" you will import "pkg.subpkg2.mod". ' + 'The\n' + 'specification for relative imports is contained within **PEP ' + '328**.\n' + '\n' + '"importlib.import_module()" is provided to support applications ' + 'that\n' + 'determine which modules need to be loaded dynamically.\n' + '\n' + '\n' + 'Future statements\n' + '=================\n' + '\n' + 'A *future statement* is a directive to the compiler that a ' + 'particular\n' + 'module should be compiled using syntax or semantics that will ' + 'be\n' + 'available in a specified future release of Python. The future\n' + 'statement is intended to ease migration to future versions of ' + 'Python\n' + 'that introduce incompatible changes to the language. It allows ' + 'use of\n' + 'the new features on a per-module basis before the release in ' + 'which the\n' + 'feature becomes standard.\n' + '\n' + ' future_statement ::= "from" "__future__" "import" feature ' + '["as" name]\n' + ' ("," feature ["as" name])*\n' + ' | "from" "__future__" "import" "(" ' + 'feature ["as" name]\n' + ' ("," feature ["as" name])* [","] ")"\n' + ' feature ::= identifier\n' + ' name ::= identifier\n' + '\n' + 'A future statement must appear near the top of the module. The ' + 'only\n' + 'lines that can appear before a future statement are:\n' + '\n' + '* the module docstring (if any),\n' + '\n' + '* comments,\n' + '\n' + '* blank lines, and\n' + '\n' + '* other future statements.\n' + '\n' + 'The features recognized by Python 2.6 are "unicode_literals",\n' + '"print_function", "absolute_import", "division", "generators",\n' + '"nested_scopes" and "with_statement". "generators", ' + '"with_statement",\n' + '"nested_scopes" are redundant in Python version 2.6 and above ' + 'because\n' + 'they are always enabled.\n' + '\n' + 'A future statement is recognized and treated specially at ' + 'compile\n' + 'time: Changes to the semantics of core constructs are often\n' + 'implemented by generating different code. It may even be the ' + 'case\n' + 'that a new feature introduces new incompatible syntax (such as a ' + 'new\n' + 'reserved word), in which case the compiler may need to parse ' + 'the\n' + 'module differently. Such decisions cannot be pushed off until\n' + 'runtime.\n' + '\n' + 'For any given release, the compiler knows which feature names ' + 'have\n' + 'been defined, and raises a compile-time error if a future ' + 'statement\n' + 'contains a feature not known to it.\n' + '\n' + 'The direct runtime semantics are the same as for any import ' + 'statement:\n' + 'there is a standard module "__future__", described later, and it ' + 'will\n' + 'be imported in the usual way at the time the future statement ' + 'is\n' + 'executed.\n' + '\n' + 'The interesting runtime semantics depend on the specific ' + 'feature\n' + 'enabled by the future statement.\n' + '\n' + 'Note that there is nothing special about the statement:\n' + '\n' + ' import __future__ [as name]\n' + '\n' + "That is not a future statement; it's an ordinary import " + 'statement with\n' + 'no special semantics or syntax restrictions.\n' + '\n' + 'Code compiled by an "exec" statement or calls to the built-in\n' + 'functions "compile()" and "execfile()" that occur in a module ' + '"M"\n' + 'containing a future statement will, by default, use the new ' + 'syntax or\n' + 'semantics associated with the future statement. This can, ' + 'starting\n' + 'with Python 2.2 be controlled by optional arguments to ' + '"compile()" ---\n' + 'see the documentation of that function for details.\n' + '\n' + 'A future statement typed at an interactive interpreter prompt ' + 'will\n' + 'take effect for the rest of the interpreter session. If an\n' + 'interpreter is started with the "-i" option, is passed a script ' + 'name\n' + 'to execute, and the script includes a future statement, it will ' + 'be in\n' + 'effect in the interactive session started after the script is\n' + 'executed.\n' + '\n' + 'See also: **PEP 236** - Back to the __future__\n' + '\n' + ' The original proposal for the __future__ mechanism.\n', + 'in': '\n' + 'Comparisons\n' + '***********\n' + '\n' + 'Unlike C, all comparison operations in Python have the same ' + 'priority,\n' + 'which is lower than that of any arithmetic, shifting or bitwise\n' + 'operation. Also unlike C, expressions like "a < b < c" have the\n' + 'interpretation that is conventional in mathematics:\n' + '\n' + ' comparison ::= or_expr ( comp_operator or_expr )*\n' + ' comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "<>" | "!="\n' + ' | "is" ["not"] | ["not"] "in"\n' + '\n' + 'Comparisons yield boolean values: "True" or "False".\n' + '\n' + 'Comparisons can be chained arbitrarily, e.g., "x < y <= z" is\n' + 'equivalent to "x < y and y <= z", except that "y" is evaluated only\n' + 'once (but in both cases "z" is not evaluated at all when "x < y" is\n' + 'found to be false).\n' + '\n' + 'Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and ' + '*op1*,\n' + '*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... ' + 'y\n' + 'opN z" is equivalent to "a op1 b and b op2 c and ... y opN z", ' + 'except\n' + 'that each expression is evaluated at most once.\n' + '\n' + 'Note that "a op1 b op2 c" doesn\'t imply any kind of comparison ' + 'between\n' + '*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\n' + 'perhaps not pretty).\n' + '\n' + 'The forms "<>" and "!=" are equivalent; for consistency with C, ' + '"!="\n' + 'is preferred; where "!=" is mentioned below "<>" is also accepted.\n' + 'The "<>" spelling is considered obsolescent.\n' + '\n' + 'The operators "<", ">", "==", ">=", "<=", and "!=" compare the ' + 'values\n' + 'of two objects. The objects need not have the same type. If both ' + 'are\n' + 'numbers, they are converted to a common type. Otherwise, objects ' + 'of\n' + 'different types *always* compare unequal, and are ordered ' + 'consistently\n' + 'but arbitrarily. You can control comparison behavior of objects of\n' + 'non-built-in types by defining a "__cmp__" method or rich ' + 'comparison\n' + 'methods like "__gt__", described in section Special method names.\n' + '\n' + '(This unusual definition of comparison was used to simplify the\n' + 'definition of operations like sorting and the "in" and "not in"\n' + 'operators. In the future, the comparison rules for objects of\n' + 'different types are likely to change.)\n' + '\n' + 'Comparison of objects of the same type depends on the type:\n' + '\n' + '* Numbers are compared arithmetically.\n' + '\n' + '* Strings are compared lexicographically using the numeric\n' + ' equivalents (the result of the built-in function "ord()") of ' + 'their\n' + ' characters. Unicode and 8-bit strings are fully interoperable in\n' + ' this behavior. [4]\n' + '\n' + '* Tuples and lists are compared lexicographically using comparison\n' + ' of corresponding elements. This means that to compare equal, ' + 'each\n' + ' element must compare equal and the two sequences must be of the ' + 'same\n' + ' type and have the same length.\n' + '\n' + ' If not equal, the sequences are ordered the same as their first\n' + ' differing elements. For example, "cmp([1,2,x], [1,2,y])" returns\n' + ' the same as "cmp(x,y)". If the corresponding element does not\n' + ' exist, the shorter sequence is ordered first (for example, "[1,2] ' + '<\n' + ' [1,2,3]").\n' + '\n' + '* Mappings (dictionaries) compare equal if and only if their sorted\n' + ' (key, value) lists compare equal. [5] Outcomes other than ' + 'equality\n' + ' are resolved consistently, but are not otherwise defined. [6]\n' + '\n' + '* Most other objects of built-in types compare unequal unless they\n' + ' are the same object; the choice whether one object is considered\n' + ' smaller or larger than another one is made arbitrarily but\n' + ' consistently within one execution of a program.\n' + '\n' + 'The operators "in" and "not in" test for collection membership. "x ' + 'in\n' + 's" evaluates to true if *x* is a member of the collection *s*, and\n' + 'false otherwise. "x not in s" returns the negation of "x in s". ' + 'The\n' + 'collection membership test has traditionally been bound to ' + 'sequences;\n' + 'an object is a member of a collection if the collection is a ' + 'sequence\n' + 'and contains an element equal to that object. However, it make ' + 'sense\n' + 'for many other object types to support membership tests without ' + 'being\n' + 'a sequence. In particular, dictionaries (for keys) and sets ' + 'support\n' + 'membership testing.\n' + '\n' + 'For the list and tuple types, "x in y" is true if and only if there\n' + 'exists an index *i* such that "x == y[i]" is true.\n' + '\n' + 'For the Unicode and string types, "x in y" is true if and only if ' + '*x*\n' + 'is a substring of *y*. An equivalent test is "y.find(x) != -1".\n' + 'Note, *x* and *y* need not be the same type; consequently, "u\'ab\' ' + 'in\n' + '\'abc\'" will return "True". Empty strings are always considered to ' + 'be a\n' + 'substring of any other string, so """ in "abc"" will return "True".\n' + '\n' + 'Changed in version 2.3: Previously, *x* was required to be a string ' + 'of\n' + 'length "1".\n' + '\n' + 'For user-defined classes which define the "__contains__()" method, ' + '"x\n' + 'in y" is true if and only if "y.__contains__(x)" is true.\n' + '\n' + 'For user-defined classes which do not define "__contains__()" but ' + 'do\n' + 'define "__iter__()", "x in y" is true if some value "z" with "x == ' + 'z"\n' + 'is produced while iterating over "y". If an exception is raised\n' + 'during the iteration, it is as if "in" raised that exception.\n' + '\n' + 'Lastly, the old-style iteration protocol is tried: if a class ' + 'defines\n' + '"__getitem__()", "x in y" is true if and only if there is a non-\n' + 'negative integer index *i* such that "x == y[i]", and all lower\n' + 'integer indices do not raise "IndexError" exception. (If any other\n' + 'exception is raised, it is as if "in" raised that exception).\n' + '\n' + 'The operator "not in" is defined to have the inverse true value of\n' + '"in".\n' + '\n' + 'The operators "is" and "is not" test for object identity: "x is y" ' + 'is\n' + 'true if and only if *x* and *y* are the same object. "x is not y"\n' + 'yields the inverse truth value. [7]\n', + 'integers': '\n' + 'Integer and long integer literals\n' + '*********************************\n' + '\n' + 'Integer and long integer literals are described by the ' + 'following\n' + 'lexical definitions:\n' + '\n' + ' longinteger ::= integer ("l" | "L")\n' + ' integer ::= decimalinteger | octinteger | hexinteger ' + '| bininteger\n' + ' decimalinteger ::= nonzerodigit digit* | "0"\n' + ' octinteger ::= "0" ("o" | "O") octdigit+ | "0" ' + 'octdigit+\n' + ' hexinteger ::= "0" ("x" | "X") hexdigit+\n' + ' bininteger ::= "0" ("b" | "B") bindigit+\n' + ' nonzerodigit ::= "1"..."9"\n' + ' octdigit ::= "0"..."7"\n' + ' bindigit ::= "0" | "1"\n' + ' hexdigit ::= digit | "a"..."f" | "A"..."F"\n' + '\n' + 'Although both lower case "\'l\'" and upper case "\'L\'" are ' + 'allowed as\n' + 'suffix for long integers, it is strongly recommended to always ' + 'use\n' + '"\'L\'", since the letter "\'l\'" looks too much like the ' + 'digit "\'1\'".\n' + '\n' + 'Plain integer literals that are above the largest ' + 'representable plain\n' + 'integer (e.g., 2147483647 when using 32-bit arithmetic) are ' + 'accepted\n' + 'as if they were long integers instead. [1] There is no limit ' + 'for long\n' + 'integer literals apart from what can be stored in available ' + 'memory.\n' + '\n' + 'Some examples of plain integer literals (first row) and long ' + 'integer\n' + 'literals (second and third rows):\n' + '\n' + ' 7 2147483647 0177\n' + ' 3L 79228162514264337593543950336L 0377L ' + '0x100000000L\n' + ' 79228162514264337593543950336 0xdeadbeef\n', + 'lambda': '\n' + 'Lambdas\n' + '*******\n' + '\n' + ' lambda_expr ::= "lambda" [parameter_list]: expression\n' + ' old_lambda_expr ::= "lambda" [parameter_list]: ' + 'old_expression\n' + '\n' + 'Lambda expressions (sometimes called lambda forms) have the ' + 'same\n' + 'syntactic position as expressions. They are a shorthand to ' + 'create\n' + 'anonymous functions; the expression "lambda arguments: ' + 'expression"\n' + 'yields a function object. The unnamed object behaves like a ' + 'function\n' + 'object defined with\n' + '\n' + ' def name(arguments):\n' + ' return expression\n' + '\n' + 'See section Function definitions for the syntax of parameter ' + 'lists.\n' + 'Note that functions created with lambda expressions cannot ' + 'contain\n' + 'statements.\n', + 'lists': '\n' + 'List displays\n' + '*************\n' + '\n' + 'A list display is a possibly empty series of expressions enclosed ' + 'in\n' + 'square brackets:\n' + '\n' + ' list_display ::= "[" [expression_list | ' + 'list_comprehension] "]"\n' + ' list_comprehension ::= expression list_for\n' + ' list_for ::= "for" target_list "in" ' + 'old_expression_list [list_iter]\n' + ' old_expression_list ::= old_expression [("," old_expression)+ ' + '[","]]\n' + ' old_expression ::= or_test | old_lambda_expr\n' + ' list_iter ::= list_for | list_if\n' + ' list_if ::= "if" old_expression [list_iter]\n' + '\n' + 'A list display yields a new list object. Its contents are ' + 'specified\n' + 'by providing either a list of expressions or a list ' + 'comprehension.\n' + 'When a comma-separated list of expressions is supplied, its ' + 'elements\n' + 'are evaluated from left to right and placed into the list object ' + 'in\n' + 'that order. When a list comprehension is supplied, it consists ' + 'of a\n' + 'single expression followed by at least one "for" clause and zero ' + 'or\n' + 'more "for" or "if" clauses. In this case, the elements of the ' + 'new\n' + 'list are those that would be produced by considering each of the ' + '"for"\n' + 'or "if" clauses a block, nesting from left to right, and ' + 'evaluating\n' + 'the expression to produce a list element each time the innermost ' + 'block\n' + 'is reached [1].\n', + 'naming': '\n' + 'Naming and binding\n' + '******************\n' + '\n' + '*Names* refer to objects. Names are introduced by name binding\n' + 'operations. Each occurrence of a name in the program text refers ' + 'to\n' + 'the *binding* of that name established in the innermost function ' + 'block\n' + 'containing the use.\n' + '\n' + 'A *block* is a piece of Python program text that is executed as ' + 'a\n' + 'unit. The following are blocks: a module, a function body, and a ' + 'class\n' + 'definition. Each command typed interactively is a block. A ' + 'script\n' + 'file (a file given as standard input to the interpreter or ' + 'specified\n' + 'on the interpreter command line the first argument) is a code ' + 'block.\n' + 'A script command (a command specified on the interpreter command ' + 'line\n' + "with the '**-c**' option) is a code block. The file read by " + 'the\n' + 'built-in function "execfile()" is a code block. The string ' + 'argument\n' + 'passed to the built-in function "eval()" and to the "exec" ' + 'statement\n' + 'is a code block. The expression read and evaluated by the ' + 'built-in\n' + 'function "input()" is a code block.\n' + '\n' + 'A code block is executed in an *execution frame*. A frame ' + 'contains\n' + 'some administrative information (used for debugging) and ' + 'determines\n' + "where and how execution continues after the code block's " + 'execution has\n' + 'completed.\n' + '\n' + 'A *scope* defines the visibility of a name within a block. If a ' + 'local\n' + 'variable is defined in a block, its scope includes that block. ' + 'If the\n' + 'definition occurs in a function block, the scope extends to any ' + 'blocks\n' + 'contained within the defining one, unless a contained block ' + 'introduces\n' + 'a different binding for the name. The scope of names defined in ' + 'a\n' + 'class block is limited to the class block; it does not extend to ' + 'the\n' + 'code blocks of methods -- this includes generator expressions ' + 'since\n' + 'they are implemented using a function scope. This means that ' + 'the\n' + 'following will fail:\n' + '\n' + ' class A:\n' + ' a = 42\n' + ' b = list(a + i for i in range(10))\n' + '\n' + 'When a name is used in a code block, it is resolved using the ' + 'nearest\n' + 'enclosing scope. The set of all such scopes visible to a code ' + 'block\n' + "is called the block's *environment*.\n" + '\n' + 'If a name is bound in a block, it is a local variable of that ' + 'block.\n' + 'If a name is bound at the module level, it is a global ' + 'variable. (The\n' + 'variables of the module code block are local and global.) If a\n' + 'variable is used in a code block but not defined there, it is a ' + '*free\n' + 'variable*.\n' + '\n' + 'When a name is not found at all, a "NameError" exception is ' + 'raised.\n' + 'If the name refers to a local variable that has not been bound, ' + 'a\n' + '"UnboundLocalError" exception is raised. "UnboundLocalError" is ' + 'a\n' + 'subclass of "NameError".\n' + '\n' + 'The following constructs bind names: formal parameters to ' + 'functions,\n' + '"import" statements, class and function definitions (these bind ' + 'the\n' + 'class or function name in the defining block), and targets that ' + 'are\n' + 'identifiers if occurring in an assignment, "for" loop header, in ' + 'the\n' + 'second position of an "except" clause header or after "as" in a ' + '"with"\n' + 'statement. The "import" statement of the form "from ... import ' + '*"\n' + 'binds all names defined in the imported module, except those ' + 'beginning\n' + 'with an underscore. This form may only be used at the module ' + 'level.\n' + '\n' + 'A target occurring in a "del" statement is also considered bound ' + 'for\n' + 'this purpose (though the actual semantics are to unbind the ' + 'name). It\n' + 'is illegal to unbind a name that is referenced by an enclosing ' + 'scope;\n' + 'the compiler will report a "SyntaxError".\n' + '\n' + 'Each assignment or import statement occurs within a block ' + 'defined by a\n' + 'class or function definition or at the module level (the ' + 'top-level\n' + 'code block).\n' + '\n' + 'If a name binding operation occurs anywhere within a code block, ' + 'all\n' + 'uses of the name within the block are treated as references to ' + 'the\n' + 'current block. This can lead to errors when a name is used ' + 'within a\n' + 'block before it is bound. This rule is subtle. Python lacks\n' + 'declarations and allows name binding operations to occur ' + 'anywhere\n' + 'within a code block. The local variables of a code block can ' + 'be\n' + 'determined by scanning the entire text of the block for name ' + 'binding\n' + 'operations.\n' + '\n' + 'If the global statement occurs within a block, all uses of the ' + 'name\n' + 'specified in the statement refer to the binding of that name in ' + 'the\n' + 'top-level namespace. Names are resolved in the top-level ' + 'namespace by\n' + 'searching the global namespace, i.e. the namespace of the ' + 'module\n' + 'containing the code block, and the builtins namespace, the ' + 'namespace\n' + 'of the module "__builtin__". The global namespace is searched ' + 'first.\n' + 'If the name is not found there, the builtins namespace is ' + 'searched.\n' + 'The global statement must precede all uses of the name.\n' + '\n' + 'The builtins namespace associated with the execution of a code ' + 'block\n' + 'is actually found by looking up the name "__builtins__" in its ' + 'global\n' + 'namespace; this should be a dictionary or a module (in the ' + 'latter case\n' + "the module's dictionary is used). By default, when in the " + '"__main__"\n' + 'module, "__builtins__" is the built-in module "__builtin__" ' + '(note: no\n' + '\'s\'); when in any other module, "__builtins__" is an alias for ' + 'the\n' + 'dictionary of the "__builtin__" module itself. "__builtins__" ' + 'can be\n' + 'set to a user-created dictionary to create a weak form of ' + 'restricted\n' + 'execution.\n' + '\n' + '**CPython implementation detail:** Users should not touch\n' + '"__builtins__"; it is strictly an implementation detail. Users\n' + 'wanting to override values in the builtins namespace should ' + '"import"\n' + 'the "__builtin__" (no \'s\') module and modify its attributes\n' + 'appropriately.\n' + '\n' + 'The namespace for a module is automatically created the first ' + 'time a\n' + 'module is imported. The main module for a script is always ' + 'called\n' + '"__main__".\n' + '\n' + 'The "global" statement has the same scope as a name binding ' + 'operation\n' + 'in the same block. If the nearest enclosing scope for a free ' + 'variable\n' + 'contains a global statement, the free variable is treated as a ' + 'global.\n' + '\n' + 'A class definition is an executable statement that may use and ' + 'define\n' + 'names. These references follow the normal rules for name ' + 'resolution.\n' + 'The namespace of the class definition becomes the attribute ' + 'dictionary\n' + 'of the class. Names defined at the class scope are not visible ' + 'in\n' + 'methods.\n' + '\n' + '\n' + 'Interaction with dynamic features\n' + '=================================\n' + '\n' + 'There are several cases where Python statements are illegal when ' + 'used\n' + 'in conjunction with nested scopes that contain free variables.\n' + '\n' + 'If a variable is referenced in an enclosing scope, it is illegal ' + 'to\n' + 'delete the name. An error will be reported at compile time.\n' + '\n' + 'If the wild card form of import --- "import *" --- is used in a\n' + 'function and the function contains or is a nested block with ' + 'free\n' + 'variables, the compiler will raise a "SyntaxError".\n' + '\n' + 'If "exec" is used in a function and the function contains or is ' + 'a\n' + 'nested block with free variables, the compiler will raise a\n' + '"SyntaxError" unless the exec explicitly specifies the local ' + 'namespace\n' + 'for the "exec". (In other words, "exec obj" would be illegal, ' + 'but\n' + '"exec obj in ns" would be legal.)\n' + '\n' + 'The "eval()", "execfile()", and "input()" functions and the ' + '"exec"\n' + 'statement do not have access to the full environment for ' + 'resolving\n' + 'names. Names may be resolved in the local and global namespaces ' + 'of\n' + 'the caller. Free variables are not resolved in the nearest ' + 'enclosing\n' + 'namespace, but in the global namespace. [1] The "exec" statement ' + 'and\n' + 'the "eval()" and "execfile()" functions have optional arguments ' + 'to\n' + 'override the global and local namespace. If only one namespace ' + 'is\n' + 'specified, it is used for both.\n', + 'numbers': '\n' + 'Numeric literals\n' + '****************\n' + '\n' + 'There are four types of numeric literals: plain integers, long\n' + 'integers, floating point numbers, and imaginary numbers. There ' + 'are no\n' + 'complex literals (complex numbers can be formed by adding a ' + 'real\n' + 'number and an imaginary number).\n' + '\n' + 'Note that numeric literals do not include a sign; a phrase like ' + '"-1"\n' + 'is actually an expression composed of the unary operator ' + '\'"-"\' and the\n' + 'literal "1".\n', + 'numeric-types': '\n' + 'Emulating numeric types\n' + '***********************\n' + '\n' + 'The following methods can be defined to emulate numeric ' + 'objects.\n' + 'Methods corresponding to operations that are not ' + 'supported by the\n' + 'particular kind of number implemented (e.g., bitwise ' + 'operations for\n' + 'non-integral numbers) should be left undefined.\n' + '\n' + 'object.__add__(self, other)\n' + 'object.__sub__(self, other)\n' + 'object.__mul__(self, other)\n' + 'object.__floordiv__(self, other)\n' + 'object.__mod__(self, other)\n' + 'object.__divmod__(self, other)\n' + 'object.__pow__(self, other[, modulo])\n' + 'object.__lshift__(self, other)\n' + 'object.__rshift__(self, other)\n' + 'object.__and__(self, other)\n' + 'object.__xor__(self, other)\n' + 'object.__or__(self, other)\n' + '\n' + ' These methods are called to implement the binary ' + 'arithmetic\n' + ' operations ("+", "-", "*", "//", "%", "divmod()", ' + '"pow()", "**",\n' + ' "<<", ">>", "&", "^", "|"). For instance, to evaluate ' + 'the\n' + ' expression "x + y", where *x* is an instance of a ' + 'class that has an\n' + ' "__add__()" method, "x.__add__(y)" is called. The ' + '"__divmod__()"\n' + ' method should be the equivalent to using ' + '"__floordiv__()" and\n' + ' "__mod__()"; it should not be related to ' + '"__truediv__()" (described\n' + ' below). Note that "__pow__()" should be defined to ' + 'accept an\n' + ' optional third argument if the ternary version of the ' + 'built-in\n' + ' "pow()" function is to be supported.\n' + '\n' + ' If one of those methods does not support the operation ' + 'with the\n' + ' supplied arguments, it should return ' + '"NotImplemented".\n' + '\n' + 'object.__div__(self, other)\n' + 'object.__truediv__(self, other)\n' + '\n' + ' The division operator ("/") is implemented by these ' + 'methods. The\n' + ' "__truediv__()" method is used when ' + '"__future__.division" is in\n' + ' effect, otherwise "__div__()" is used. If only one of ' + 'these two\n' + ' methods is defined, the object will not support ' + 'division in the\n' + ' alternate context; "TypeError" will be raised ' + 'instead.\n' + '\n' + 'object.__radd__(self, other)\n' + 'object.__rsub__(self, other)\n' + 'object.__rmul__(self, other)\n' + 'object.__rdiv__(self, other)\n' + 'object.__rtruediv__(self, other)\n' + 'object.__rfloordiv__(self, other)\n' + 'object.__rmod__(self, other)\n' + 'object.__rdivmod__(self, other)\n' + 'object.__rpow__(self, other)\n' + 'object.__rlshift__(self, other)\n' + 'object.__rrshift__(self, other)\n' + 'object.__rand__(self, other)\n' + 'object.__rxor__(self, other)\n' + 'object.__ror__(self, other)\n' + '\n' + ' These methods are called to implement the binary ' + 'arithmetic\n' + ' operations ("+", "-", "*", "/", "%", "divmod()", ' + '"pow()", "**",\n' + ' "<<", ">>", "&", "^", "|") with reflected (swapped) ' + 'operands.\n' + ' These functions are only called if the left operand ' + 'does not\n' + ' support the corresponding operation and the operands ' + 'are of\n' + ' different types. [2] For instance, to evaluate the ' + 'expression "x -\n' + ' y", where *y* is an instance of a class that has an ' + '"__rsub__()"\n' + ' method, "y.__rsub__(x)" is called if "x.__sub__(y)" ' + 'returns\n' + ' *NotImplemented*.\n' + '\n' + ' Note that ternary "pow()" will not try calling ' + '"__rpow__()" (the\n' + ' coercion rules would become too complicated).\n' + '\n' + " Note: If the right operand's type is a subclass of the " + 'left\n' + " operand's type and that subclass provides the " + 'reflected method\n' + ' for the operation, this method will be called before ' + 'the left\n' + " operand's non-reflected method. This behavior " + 'allows subclasses\n' + " to override their ancestors' operations.\n" + '\n' + 'object.__iadd__(self, other)\n' + 'object.__isub__(self, other)\n' + 'object.__imul__(self, other)\n' + 'object.__idiv__(self, other)\n' + 'object.__itruediv__(self, other)\n' + 'object.__ifloordiv__(self, other)\n' + 'object.__imod__(self, other)\n' + 'object.__ipow__(self, other[, modulo])\n' + 'object.__ilshift__(self, other)\n' + 'object.__irshift__(self, other)\n' + 'object.__iand__(self, other)\n' + 'object.__ixor__(self, other)\n' + 'object.__ior__(self, other)\n' + '\n' + ' These methods are called to implement the augmented ' + 'arithmetic\n' + ' assignments ("+=", "-=", "*=", "/=", "//=", "%=", ' + '"**=", "<<=",\n' + ' ">>=", "&=", "^=", "|="). These methods should ' + 'attempt to do the\n' + ' operation in-place (modifying *self*) and return the ' + 'result (which\n' + ' could be, but does not have to be, *self*). If a ' + 'specific method\n' + ' is not defined, the augmented assignment falls back to ' + 'the normal\n' + ' methods. For instance, to execute the statement "x += ' + 'y", where\n' + ' *x* is an instance of a class that has an "__iadd__()" ' + 'method,\n' + ' "x.__iadd__(y)" is called. If *x* is an instance of a ' + 'class that\n' + ' does not define a "__iadd__()" method, "x.__add__(y)" ' + 'and\n' + ' "y.__radd__(x)" are considered, as with the evaluation ' + 'of "x + y".\n' + '\n' + 'object.__neg__(self)\n' + 'object.__pos__(self)\n' + 'object.__abs__(self)\n' + 'object.__invert__(self)\n' + '\n' + ' Called to implement the unary arithmetic operations ' + '("-", "+",\n' + ' "abs()" and "~").\n' + '\n' + 'object.__complex__(self)\n' + 'object.__int__(self)\n' + 'object.__long__(self)\n' + 'object.__float__(self)\n' + '\n' + ' Called to implement the built-in functions ' + '"complex()", "int()",\n' + ' "long()", and "float()". Should return a value of the ' + 'appropriate\n' + ' type.\n' + '\n' + 'object.__oct__(self)\n' + 'object.__hex__(self)\n' + '\n' + ' Called to implement the built-in functions "oct()" and ' + '"hex()".\n' + ' Should return a string value.\n' + '\n' + 'object.__index__(self)\n' + '\n' + ' Called to implement "operator.index()". Also called ' + 'whenever\n' + ' Python needs an integer object (such as in slicing). ' + 'Must return\n' + ' an integer (int or long).\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'object.__coerce__(self, other)\n' + '\n' + ' Called to implement "mixed-mode" numeric arithmetic. ' + 'Should either\n' + ' return a 2-tuple containing *self* and *other* ' + 'converted to a\n' + ' common numeric type, or "None" if conversion is ' + 'impossible. When\n' + ' the common type would be the type of "other", it is ' + 'sufficient to\n' + ' return "None", since the interpreter will also ask the ' + 'other object\n' + ' to attempt a coercion (but sometimes, if the ' + 'implementation of the\n' + ' other type cannot be changed, it is useful to do the ' + 'conversion to\n' + ' the other type here). A return value of ' + '"NotImplemented" is\n' + ' equivalent to returning "None".\n', + 'objects': '\n' + 'Objects, values and types\n' + '*************************\n' + '\n' + "*Objects* are Python's abstraction for data. All data in a " + 'Python\n' + 'program is represented by objects or by relations between ' + 'objects. (In\n' + "a sense, and in conformance to Von Neumann's model of a " + '"stored\n' + 'program computer," code is also represented by objects.)\n' + '\n' + "Every object has an identity, a type and a value. An object's\n" + '*identity* never changes once it has been created; you may ' + 'think of it\n' + 'as the object\'s address in memory. The \'"is"\' operator ' + 'compares the\n' + 'identity of two objects; the "id()" function returns an ' + 'integer\n' + 'representing its identity (currently implemented as its ' + 'address). An\n' + "object's *type* is also unchangeable. [1] An object's type " + 'determines\n' + 'the operations that the object supports (e.g., "does it have a\n' + 'length?") and also defines the possible values for objects of ' + 'that\n' + 'type. The "type()" function returns an object\'s type (which ' + 'is an\n' + 'object itself). The *value* of some objects can change. ' + 'Objects\n' + 'whose value can change are said to be *mutable*; objects whose ' + 'value\n' + 'is unchangeable once they are created are called *immutable*. ' + '(The\n' + 'value of an immutable container object that contains a ' + 'reference to a\n' + "mutable object can change when the latter's value is changed; " + 'however\n' + 'the container is still considered immutable, because the ' + 'collection of\n' + 'objects it contains cannot be changed. So, immutability is ' + 'not\n' + 'strictly the same as having an unchangeable value, it is more ' + 'subtle.)\n' + "An object's mutability is determined by its type; for " + 'instance,\n' + 'numbers, strings and tuples are immutable, while dictionaries ' + 'and\n' + 'lists are mutable.\n' + '\n' + 'Objects are never explicitly destroyed; however, when they ' + 'become\n' + 'unreachable they may be garbage-collected. An implementation ' + 'is\n' + 'allowed to postpone garbage collection or omit it altogether ' + '--- it is\n' + 'a matter of implementation quality how garbage collection is\n' + 'implemented, as long as no objects are collected that are ' + 'still\n' + 'reachable.\n' + '\n' + '**CPython implementation detail:** CPython currently uses a ' + 'reference-\n' + 'counting scheme with (optional) delayed detection of cyclically ' + 'linked\n' + 'garbage, which collects most objects as soon as they become\n' + 'unreachable, but is not guaranteed to collect garbage ' + 'containing\n' + 'circular references. See the documentation of the "gc" module ' + 'for\n' + 'information on controlling the collection of cyclic garbage. ' + 'Other\n' + 'implementations act differently and CPython may change. Do not ' + 'depend\n' + 'on immediate finalization of objects when they become ' + 'unreachable (ex:\n' + 'always close files).\n' + '\n' + "Note that the use of the implementation's tracing or debugging\n" + 'facilities may keep objects alive that would normally be ' + 'collectable.\n' + 'Also note that catching an exception with a ' + '\'"try"..."except"\'\n' + 'statement may keep objects alive.\n' + '\n' + 'Some objects contain references to "external" resources such as ' + 'open\n' + 'files or windows. It is understood that these resources are ' + 'freed\n' + 'when the object is garbage-collected, but since garbage ' + 'collection is\n' + 'not guaranteed to happen, such objects also provide an explicit ' + 'way to\n' + 'release the external resource, usually a "close()" method. ' + 'Programs\n' + 'are strongly recommended to explicitly close such objects. ' + 'The\n' + '\'"try"..."finally"\' statement provides a convenient way to do ' + 'this.\n' + '\n' + 'Some objects contain references to other objects; these are ' + 'called\n' + '*containers*. Examples of containers are tuples, lists and\n' + "dictionaries. The references are part of a container's value. " + 'In\n' + 'most cases, when we talk about the value of a container, we ' + 'imply the\n' + 'values, not the identities of the contained objects; however, ' + 'when we\n' + 'talk about the mutability of a container, only the identities ' + 'of the\n' + 'immediately contained objects are implied. So, if an ' + 'immutable\n' + 'container (like a tuple) contains a reference to a mutable ' + 'object, its\n' + 'value changes if that mutable object is changed.\n' + '\n' + 'Types affect almost all aspects of object behavior. Even the\n' + 'importance of object identity is affected in some sense: for ' + 'immutable\n' + 'types, operations that compute new values may actually return ' + 'a\n' + 'reference to any existing object with the same type and value, ' + 'while\n' + 'for mutable objects this is not allowed. E.g., after "a = 1; b ' + '= 1",\n' + '"a" and "b" may or may not refer to the same object with the ' + 'value\n' + 'one, depending on the implementation, but after "c = []; d = ' + '[]", "c"\n' + 'and "d" are guaranteed to refer to two different, unique, ' + 'newly\n' + 'created empty lists. (Note that "c = d = []" assigns the same ' + 'object\n' + 'to both "c" and "d".)\n', + 'operator-summary': '\n' + 'Operator precedence\n' + '*******************\n' + '\n' + 'The following table summarizes the operator ' + 'precedences in Python,\n' + 'from lowest precedence (least binding) to highest ' + 'precedence (most\n' + 'binding). Operators in the same box have the same ' + 'precedence. Unless\n' + 'the syntax is explicitly given, operators are binary. ' + 'Operators in\n' + 'the same box group left to right (except for ' + 'comparisons, including\n' + 'tests, which all have the same precedence and chain ' + 'from left to right\n' + '--- see section Comparisons --- and exponentiation, ' + 'which groups from\n' + 'right to left).\n' + '\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| Operator | ' + 'Description |\n' + '+=================================================+=======================================+\n' + '| "lambda" | ' + 'Lambda expression |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "if" -- "else" | ' + 'Conditional expression |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "or" | ' + 'Boolean OR |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "and" | ' + 'Boolean AND |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "not" "x" | ' + 'Boolean NOT |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "in", "not in", "is", "is not", "<", "<=", ">", | ' + 'Comparisons, including membership |\n' + '| ">=", "<>", "!=", "==" | ' + 'tests and identity tests |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "|" | ' + 'Bitwise OR |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "^" | ' + 'Bitwise XOR |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "&" | ' + 'Bitwise AND |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "<<", ">>" | ' + 'Shifts |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "+", "-" | ' + 'Addition and subtraction |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "*", "/", "//", "%" | ' + 'Multiplication, division, remainder |\n' + '| | ' + '[8] |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "+x", "-x", "~x" | ' + 'Positive, negative, bitwise NOT |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "**" | ' + 'Exponentiation [9] |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "x[index]", "x[index:index]", | ' + 'Subscription, slicing, call, |\n' + '| "x(arguments...)", "x.attribute" | ' + 'attribute reference |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '| "(expressions...)", "[expressions...]", "{key: | ' + 'Binding or tuple display, list |\n' + '| value...}", "`expressions...`" | ' + 'display, dictionary display, string |\n' + '| | ' + 'conversion |\n' + '+-------------------------------------------------+---------------------------------------+\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] In Python 2.3 and later releases, a list ' + 'comprehension "leaks"\n' + ' the control variables of each "for" it contains ' + 'into the\n' + ' containing scope. However, this behavior is ' + 'deprecated, and\n' + ' relying on it will not work in Python 3.\n' + '\n' + '[2] While "abs(x%y) < abs(y)" is true mathematically, ' + 'for floats\n' + ' it may not be true numerically due to roundoff. ' + 'For example, and\n' + ' assuming a platform on which a Python float is an ' + 'IEEE 754 double-\n' + ' precision number, in order that "-1e-100 % 1e100" ' + 'have the same\n' + ' sign as "1e100", the computed result is "-1e-100 + ' + '1e100", which\n' + ' is numerically exactly equal to "1e100". The ' + 'function\n' + ' "math.fmod()" returns a result whose sign matches ' + 'the sign of the\n' + ' first argument instead, and so returns "-1e-100" ' + 'in this case.\n' + ' Which approach is more appropriate depends on the ' + 'application.\n' + '\n' + '[3] If x is very close to an exact integer multiple of ' + "y, it's\n" + ' possible for "floor(x/y)" to be one larger than ' + '"(x-x%y)/y" due to\n' + ' rounding. In such cases, Python returns the ' + 'latter result, in\n' + ' order to preserve that "divmod(x,y)[0] * y + x % ' + 'y" be very close\n' + ' to "x".\n' + '\n' + '[4] While comparisons between unicode strings make ' + 'sense at the\n' + ' byte level, they may be counter-intuitive to ' + 'users. For example,\n' + ' the strings "u"\\u00C7"" and "u"\\u0043\\u0327"" ' + 'compare differently,\n' + ' even though they both represent the same unicode ' + 'character (LATIN\n' + ' CAPITAL LETTER C WITH CEDILLA). To compare strings ' + 'in a human\n' + ' recognizable way, compare using ' + '"unicodedata.normalize()".\n' + '\n' + '[5] The implementation computes this efficiently, ' + 'without\n' + ' constructing lists or sorting.\n' + '\n' + '[6] Earlier versions of Python used lexicographic ' + 'comparison of\n' + ' the sorted (key, value) lists, but this was very ' + 'expensive for the\n' + ' common case of comparing for equality. An even ' + 'earlier version of\n' + ' Python compared dictionaries by identity only, but ' + 'this caused\n' + ' surprises because people expected to be able to ' + 'test a dictionary\n' + ' for emptiness by comparing it to "{}".\n' + '\n' + '[7] Due to automatic garbage-collection, free lists, ' + 'and the\n' + ' dynamic nature of descriptors, you may notice ' + 'seemingly unusual\n' + ' behaviour in certain uses of the "is" operator, ' + 'like those\n' + ' involving comparisons between instance methods, or ' + 'constants.\n' + ' Check their documentation for more info.\n' + '\n' + '[8] The "%" operator is also used for string ' + 'formatting; the same\n' + ' precedence applies.\n' + '\n' + '[9] The power operator "**" binds less tightly than an ' + 'arithmetic\n' + ' or bitwise unary operator on its right, that is, ' + '"2**-1" is "0.5".\n', + 'pass': '\n' + 'The "pass" statement\n' + '********************\n' + '\n' + ' pass_stmt ::= "pass"\n' + '\n' + '"pass" is a null operation --- when it is executed, nothing ' + 'happens.\n' + 'It is useful as a placeholder when a statement is required\n' + 'syntactically, but no code needs to be executed, for example:\n' + '\n' + ' def f(arg): pass # a function that does nothing (yet)\n' + '\n' + ' class C: pass # a class with no methods (yet)\n', + 'power': '\n' + 'The power operator\n' + '******************\n' + '\n' + 'The power operator binds more tightly than unary operators on ' + 'its\n' + 'left; it binds less tightly than unary operators on its right. ' + 'The\n' + 'syntax is:\n' + '\n' + ' power ::= primary ["**" u_expr]\n' + '\n' + 'Thus, in an unparenthesized sequence of power and unary ' + 'operators, the\n' + 'operators are evaluated from right to left (this does not ' + 'constrain\n' + 'the evaluation order for the operands): "-1**2" results in "-1".\n' + '\n' + 'The power operator has the same semantics as the built-in ' + '"pow()"\n' + 'function, when called with two arguments: it yields its left ' + 'argument\n' + 'raised to the power of its right argument. The numeric arguments ' + 'are\n' + 'first converted to a common type. The result type is that of ' + 'the\n' + 'arguments after coercion.\n' + '\n' + 'With mixed operand types, the coercion rules for binary ' + 'arithmetic\n' + 'operators apply. For int and long int operands, the result has ' + 'the\n' + 'same type as the operands (after coercion) unless the second ' + 'argument\n' + 'is negative; in that case, all arguments are converted to float ' + 'and a\n' + 'float result is delivered. For example, "10**2" returns "100", ' + 'but\n' + '"10**-2" returns "0.01". (This last feature was added in Python ' + '2.2.\n' + 'In Python 2.1 and before, if both arguments were of integer types ' + 'and\n' + 'the second argument was negative, an exception was raised).\n' + '\n' + 'Raising "0.0" to a negative power results in a ' + '"ZeroDivisionError".\n' + 'Raising a negative number to a fractional power results in a\n' + '"ValueError".\n', + 'print': '\n' + 'The "print" statement\n' + '*********************\n' + '\n' + ' print_stmt ::= "print" ([expression ("," expression)* [","]]\n' + ' | ">>" expression [("," expression)+ [","]])\n' + '\n' + '"print" evaluates each expression in turn and writes the ' + 'resulting\n' + 'object to standard output (see below). If an object is not a ' + 'string,\n' + 'it is first converted to a string using the rules for string\n' + 'conversions. The (resulting or original) string is then ' + 'written. A\n' + 'space is written before each object is (converted and) written, ' + 'unless\n' + 'the output system believes it is positioned at the beginning of ' + 'a\n' + 'line. This is the case (1) when no characters have yet been ' + 'written\n' + 'to standard output, (2) when the last character written to ' + 'standard\n' + 'output is a whitespace character except "\' \'", or (3) when the ' + 'last\n' + 'write operation on standard output was not a "print" statement. ' + '(In\n' + 'some cases it may be functional to write an empty string to ' + 'standard\n' + 'output for this reason.)\n' + '\n' + 'Note: Objects which act like file objects but which are not the\n' + ' built-in file objects often do not properly emulate this aspect ' + 'of\n' + " the file object's behavior, so it is best not to rely on this.\n" + '\n' + 'A "\'\\n\'" character is written at the end, unless the "print" ' + 'statement\n' + 'ends with a comma. This is the only action if the statement ' + 'contains\n' + 'just the keyword "print".\n' + '\n' + 'Standard output is defined as the file object named "stdout" in ' + 'the\n' + 'built-in module "sys". If no such object exists, or if it does ' + 'not\n' + 'have a "write()" method, a "RuntimeError" exception is raised.\n' + '\n' + '"print" also has an extended form, defined by the second portion ' + 'of\n' + 'the syntax described above. This form is sometimes referred to ' + 'as\n' + '""print" chevron." In this form, the first expression after the ' + '">>"\n' + 'must evaluate to a "file-like" object, specifically an object ' + 'that has\n' + 'a "write()" method as described above. With this extended form, ' + 'the\n' + 'subsequent expressions are printed to this file object. If the ' + 'first\n' + 'expression evaluates to "None", then "sys.stdout" is used as the ' + 'file\n' + 'for output.\n', + 'raise': '\n' + 'The "raise" statement\n' + '*********************\n' + '\n' + ' raise_stmt ::= "raise" [expression ["," expression ["," ' + 'expression]]]\n' + '\n' + 'If no expressions are present, "raise" re-raises the last ' + 'exception\n' + 'that was active in the current scope. If no exception is active ' + 'in\n' + 'the current scope, a "TypeError" exception is raised indicating ' + 'that\n' + 'this is an error (if running under IDLE, a "Queue.Empty" ' + 'exception is\n' + 'raised instead).\n' + '\n' + 'Otherwise, "raise" evaluates the expressions to get three ' + 'objects,\n' + 'using "None" as the value of omitted expressions. The first two\n' + 'objects are used to determine the *type* and *value* of the ' + 'exception.\n' + '\n' + 'If the first object is an instance, the type of the exception is ' + 'the\n' + 'class of the instance, the instance itself is the value, and the\n' + 'second object must be "None".\n' + '\n' + 'If the first object is a class, it becomes the type of the ' + 'exception.\n' + 'The second object is used to determine the exception value: If it ' + 'is\n' + 'an instance of the class, the instance becomes the exception ' + 'value. If\n' + 'the second object is a tuple, it is used as the argument list for ' + 'the\n' + 'class constructor; if it is "None", an empty argument list is ' + 'used,\n' + 'and any other object is treated as a single argument to the\n' + 'constructor. The instance so created by calling the constructor ' + 'is\n' + 'used as the exception value.\n' + '\n' + 'If a third object is present and not "None", it must be a ' + 'traceback\n' + 'object (see section The standard type hierarchy), and it is\n' + 'substituted instead of the current location as the place where ' + 'the\n' + 'exception occurred. If the third object is present and not a\n' + 'traceback object or "None", a "TypeError" exception is raised. ' + 'The\n' + 'three-expression form of "raise" is useful to re-raise an ' + 'exception\n' + 'transparently in an except clause, but "raise" with no ' + 'expressions\n' + 'should be preferred if the exception to be re-raised was the ' + 'most\n' + 'recently active exception in the current scope.\n' + '\n' + 'Additional information on exceptions can be found in section\n' + 'Exceptions, and information about handling exceptions is in ' + 'section\n' + 'The try statement.\n', + 'return': '\n' + 'The "return" statement\n' + '**********************\n' + '\n' + ' return_stmt ::= "return" [expression_list]\n' + '\n' + '"return" may only occur syntactically nested in a function ' + 'definition,\n' + 'not within a nested class definition.\n' + '\n' + 'If an expression list is present, it is evaluated, else "None" ' + 'is\n' + 'substituted.\n' + '\n' + '"return" leaves the current function call with the expression ' + 'list (or\n' + '"None") as return value.\n' + '\n' + 'When "return" passes control out of a "try" statement with a ' + '"finally"\n' + 'clause, that "finally" clause is executed before really leaving ' + 'the\n' + 'function.\n' + '\n' + 'In a generator function, the "return" statement is not allowed ' + 'to\n' + 'include an "expression_list". In that context, a bare "return"\n' + 'indicates that the generator is done and will cause ' + '"StopIteration" to\n' + 'be raised.\n', + 'sequence-types': '\n' + 'Emulating container types\n' + '*************************\n' + '\n' + 'The following methods can be defined to implement ' + 'container objects.\n' + 'Containers usually are sequences (such as lists or ' + 'tuples) or mappings\n' + '(like dictionaries), but can represent other containers ' + 'as well. The\n' + 'first set of methods is used either to emulate a ' + 'sequence or to\n' + 'emulate a mapping; the difference is that for a ' + 'sequence, the\n' + 'allowable keys should be the integers *k* for which "0 ' + '<= k < N" where\n' + '*N* is the length of the sequence, or slice objects, ' + 'which define a\n' + 'range of items. (For backwards compatibility, the ' + 'method\n' + '"__getslice__()" (see below) can also be defined to ' + 'handle simple, but\n' + 'not extended slices.) It is also recommended that ' + 'mappings provide the\n' + 'methods "keys()", "values()", "items()", "has_key()", ' + '"get()",\n' + '"clear()", "setdefault()", "iterkeys()", ' + '"itervalues()",\n' + '"iteritems()", "pop()", "popitem()", "copy()", and ' + '"update()" behaving\n' + "similar to those for Python's standard dictionary " + 'objects. The\n' + '"UserDict" module provides a "DictMixin" class to help ' + 'create those\n' + 'methods from a base set of "__getitem__()", ' + '"__setitem__()",\n' + '"__delitem__()", and "keys()". Mutable sequences should ' + 'provide\n' + 'methods "append()", "count()", "index()", "extend()", ' + '"insert()",\n' + '"pop()", "remove()", "reverse()" and "sort()", like ' + 'Python standard\n' + 'list objects. Finally, sequence types should implement ' + 'addition\n' + '(meaning concatenation) and multiplication (meaning ' + 'repetition) by\n' + 'defining the methods "__add__()", "__radd__()", ' + '"__iadd__()",\n' + '"__mul__()", "__rmul__()" and "__imul__()" described ' + 'below; they\n' + 'should not define "__coerce__()" or other numerical ' + 'operators. It is\n' + 'recommended that both mappings and sequences implement ' + 'the\n' + '"__contains__()" method to allow efficient use of the ' + '"in" operator;\n' + 'for mappings, "in" should be equivalent of "has_key()"; ' + 'for sequences,\n' + 'it should search through the values. It is further ' + 'recommended that\n' + 'both mappings and sequences implement the "__iter__()" ' + 'method to allow\n' + 'efficient iteration through the container; for mappings, ' + '"__iter__()"\n' + 'should be the same as "iterkeys()"; for sequences, it ' + 'should iterate\n' + 'through the values.\n' + '\n' + 'object.__len__(self)\n' + '\n' + ' Called to implement the built-in function "len()". ' + 'Should return\n' + ' the length of the object, an integer ">=" 0. Also, ' + 'an object that\n' + ' doesn\'t define a "__nonzero__()" method and whose ' + '"__len__()"\n' + ' method returns zero is considered to be false in a ' + 'Boolean context.\n' + '\n' + 'object.__getitem__(self, key)\n' + '\n' + ' Called to implement evaluation of "self[key]". For ' + 'sequence types,\n' + ' the accepted keys should be integers and slice ' + 'objects. Note that\n' + ' the special interpretation of negative indexes (if ' + 'the class wishes\n' + ' to emulate a sequence type) is up to the ' + '"__getitem__()" method. If\n' + ' *key* is of an inappropriate type, "TypeError" may be ' + 'raised; if of\n' + ' a value outside the set of indexes for the sequence ' + '(after any\n' + ' special interpretation of negative values), ' + '"IndexError" should be\n' + ' raised. For mapping types, if *key* is missing (not ' + 'in the\n' + ' container), "KeyError" should be raised.\n' + '\n' + ' Note: "for" loops expect that an "IndexError" will be ' + 'raised for\n' + ' illegal indexes to allow proper detection of the ' + 'end of the\n' + ' sequence.\n' + '\n' + 'object.__missing__(self, key)\n' + '\n' + ' Called by "dict"."__getitem__()" to implement ' + '"self[key]" for dict\n' + ' subclasses when key is not in the dictionary.\n' + '\n' + 'object.__setitem__(self, key, value)\n' + '\n' + ' Called to implement assignment to "self[key]". Same ' + 'note as for\n' + ' "__getitem__()". This should only be implemented for ' + 'mappings if\n' + ' the objects support changes to the values for keys, ' + 'or if new keys\n' + ' can be added, or for sequences if elements can be ' + 'replaced. The\n' + ' same exceptions should be raised for improper *key* ' + 'values as for\n' + ' the "__getitem__()" method.\n' + '\n' + 'object.__delitem__(self, key)\n' + '\n' + ' Called to implement deletion of "self[key]". Same ' + 'note as for\n' + ' "__getitem__()". This should only be implemented for ' + 'mappings if\n' + ' the objects support removal of keys, or for sequences ' + 'if elements\n' + ' can be removed from the sequence. The same ' + 'exceptions should be\n' + ' raised for improper *key* values as for the ' + '"__getitem__()" method.\n' + '\n' + 'object.__iter__(self)\n' + '\n' + ' This method is called when an iterator is required ' + 'for a container.\n' + ' This method should return a new iterator object that ' + 'can iterate\n' + ' over all the objects in the container. For mappings, ' + 'it should\n' + ' iterate over the keys of the container, and should ' + 'also be made\n' + ' available as the method "iterkeys()".\n' + '\n' + ' Iterator objects also need to implement this method; ' + 'they are\n' + ' required to return themselves. For more information ' + 'on iterator\n' + ' objects, see Iterator Types.\n' + '\n' + 'object.__reversed__(self)\n' + '\n' + ' Called (if present) by the "reversed()" built-in to ' + 'implement\n' + ' reverse iteration. It should return a new iterator ' + 'object that\n' + ' iterates over all the objects in the container in ' + 'reverse order.\n' + '\n' + ' If the "__reversed__()" method is not provided, the ' + '"reversed()"\n' + ' built-in will fall back to using the sequence ' + 'protocol ("__len__()"\n' + ' and "__getitem__()"). Objects that support the ' + 'sequence protocol\n' + ' should only provide "__reversed__()" if they can ' + 'provide an\n' + ' implementation that is more efficient than the one ' + 'provided by\n' + ' "reversed()".\n' + '\n' + ' New in version 2.6.\n' + '\n' + 'The membership test operators ("in" and "not in") are ' + 'normally\n' + 'implemented as an iteration through a sequence. ' + 'However, container\n' + 'objects can supply the following special method with a ' + 'more efficient\n' + 'implementation, which also does not require the object ' + 'be a sequence.\n' + '\n' + 'object.__contains__(self, item)\n' + '\n' + ' Called to implement membership test operators. ' + 'Should return true\n' + ' if *item* is in *self*, false otherwise. For mapping ' + 'objects, this\n' + ' should consider the keys of the mapping rather than ' + 'the values or\n' + ' the key-item pairs.\n' + '\n' + ' For objects that don\'t define "__contains__()", the ' + 'membership test\n' + ' first tries iteration via "__iter__()", then the old ' + 'sequence\n' + ' iteration protocol via "__getitem__()", see this ' + 'section in the\n' + ' language reference.\n', + 'shifting': '\n' + 'Shifting operations\n' + '*******************\n' + '\n' + 'The shifting operations have lower priority than the ' + 'arithmetic\n' + 'operations:\n' + '\n' + ' shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n' + '\n' + 'These operators accept plain or long integers as arguments. ' + 'The\n' + 'arguments are converted to a common type. They shift the ' + 'first\n' + 'argument to the left or right by the number of bits given by ' + 'the\n' + 'second argument.\n' + '\n' + 'A right shift by *n* bits is defined as division by "pow(2, ' + 'n)". A\n' + 'left shift by *n* bits is defined as multiplication with ' + '"pow(2, n)".\n' + 'Negative shift counts raise a "ValueError" exception.\n' + '\n' + 'Note: In the current implementation, the right-hand operand ' + 'is\n' + ' required to be at most "sys.maxsize". If the right-hand ' + 'operand is\n' + ' larger than "sys.maxsize" an "OverflowError" exception is ' + 'raised.\n', + 'slicings': '\n' + 'Slicings\n' + '********\n' + '\n' + 'A slicing selects a range of items in a sequence object (e.g., ' + 'a\n' + 'string, tuple or list). Slicings may be used as expressions ' + 'or as\n' + 'targets in assignment or "del" statements. The syntax for a ' + 'slicing:\n' + '\n' + ' slicing ::= simple_slicing | extended_slicing\n' + ' simple_slicing ::= primary "[" short_slice "]"\n' + ' extended_slicing ::= primary "[" slice_list "]"\n' + ' slice_list ::= slice_item ("," slice_item)* [","]\n' + ' slice_item ::= expression | proper_slice | ellipsis\n' + ' proper_slice ::= short_slice | long_slice\n' + ' short_slice ::= [lower_bound] ":" [upper_bound]\n' + ' long_slice ::= short_slice ":" [stride]\n' + ' lower_bound ::= expression\n' + ' upper_bound ::= expression\n' + ' stride ::= expression\n' + ' ellipsis ::= "..."\n' + '\n' + 'There is ambiguity in the formal syntax here: anything that ' + 'looks like\n' + 'an expression list also looks like a slice list, so any ' + 'subscription\n' + 'can be interpreted as a slicing. Rather than further ' + 'complicating the\n' + 'syntax, this is disambiguated by defining that in this case ' + 'the\n' + 'interpretation as a subscription takes priority over the\n' + 'interpretation as a slicing (this is the case if the slice ' + 'list\n' + 'contains no proper slice nor ellipses). Similarly, when the ' + 'slice\n' + 'list has exactly one short slice and no trailing comma, the\n' + 'interpretation as a simple slicing takes priority over that as ' + 'an\n' + 'extended slicing.\n' + '\n' + 'The semantics for a simple slicing are as follows. The ' + 'primary must\n' + 'evaluate to a sequence object. The lower and upper bound ' + 'expressions,\n' + 'if present, must evaluate to plain integers; defaults are zero ' + 'and the\n' + '"sys.maxint", respectively. If either bound is negative, the\n' + "sequence's length is added to it. The slicing now selects all " + 'items\n' + 'with index *k* such that "i <= k < j" where *i* and *j* are ' + 'the\n' + 'specified lower and upper bounds. This may be an empty ' + 'sequence. It\n' + 'is not an error if *i* or *j* lie outside the range of valid ' + 'indexes\n' + "(such items don't exist so they aren't selected).\n" + '\n' + 'The semantics for an extended slicing are as follows. The ' + 'primary\n' + 'must evaluate to a mapping object, and it is indexed with a ' + 'key that\n' + 'is constructed from the slice list, as follows. If the slice ' + 'list\n' + 'contains at least one comma, the key is a tuple containing ' + 'the\n' + 'conversion of the slice items; otherwise, the conversion of ' + 'the lone\n' + 'slice item is the key. The conversion of a slice item that is ' + 'an\n' + 'expression is that expression. The conversion of an ellipsis ' + 'slice\n' + 'item is the built-in "Ellipsis" object. The conversion of a ' + 'proper\n' + 'slice is a slice object (see section The standard type ' + 'hierarchy)\n' + 'whose "start", "stop" and "step" attributes are the values of ' + 'the\n' + 'expressions given as lower bound, upper bound and stride,\n' + 'respectively, substituting "None" for missing expressions.\n', + 'specialattrs': '\n' + 'Special Attributes\n' + '******************\n' + '\n' + 'The implementation adds a few special read-only attributes ' + 'to several\n' + 'object types, where they are relevant. Some of these are ' + 'not reported\n' + 'by the "dir()" built-in function.\n' + '\n' + 'object.__dict__\n' + '\n' + ' A dictionary or other mapping object used to store an ' + "object's\n" + ' (writable) attributes.\n' + '\n' + 'object.__methods__\n' + '\n' + ' Deprecated since version 2.2: Use the built-in function ' + '"dir()" to\n' + " get a list of an object's attributes. This attribute is " + 'no longer\n' + ' available.\n' + '\n' + 'object.__members__\n' + '\n' + ' Deprecated since version 2.2: Use the built-in function ' + '"dir()" to\n' + " get a list of an object's attributes. This attribute is " + 'no longer\n' + ' available.\n' + '\n' + 'instance.__class__\n' + '\n' + ' The class to which a class instance belongs.\n' + '\n' + 'class.__bases__\n' + '\n' + ' The tuple of base classes of a class object.\n' + '\n' + 'class.__name__\n' + '\n' + ' The name of the class or type.\n' + '\n' + 'The following attributes are only supported by *new-style ' + 'class*es.\n' + '\n' + 'class.__mro__\n' + '\n' + ' This attribute is a tuple of classes that are ' + 'considered when\n' + ' looking for base classes during method resolution.\n' + '\n' + 'class.mro()\n' + '\n' + ' This method can be overridden by a metaclass to ' + 'customize the\n' + ' method resolution order for its instances. It is ' + 'called at class\n' + ' instantiation, and its result is stored in "__mro__".\n' + '\n' + 'class.__subclasses__()\n' + '\n' + ' Each new-style class keeps a list of weak references to ' + 'its\n' + ' immediate subclasses. This method returns a list of ' + 'all those\n' + ' references still alive. Example:\n' + '\n' + ' >>> int.__subclasses__()\n' + " []\n" + '\n' + '-[ Footnotes ]-\n' + '\n' + '[1] Additional information on these special methods may be ' + 'found\n' + ' in the Python Reference Manual (Basic customization).\n' + '\n' + '[2] As a consequence, the list "[1, 2]" is considered ' + 'equal to\n' + ' "[1.0, 2.0]", and similarly for tuples.\n' + '\n' + "[3] They must have since the parser can't tell the type of " + 'the\n' + ' operands.\n' + '\n' + '[4] Cased characters are those with general category ' + 'property\n' + ' being one of "Lu" (Letter, uppercase), "Ll" (Letter, ' + 'lowercase),\n' + ' or "Lt" (Letter, titlecase).\n' + '\n' + '[5] To format only a tuple you should therefore provide a\n' + ' singleton tuple whose only element is the tuple to be ' + 'formatted.\n' + '\n' + '[6] The advantage of leaving the newline on is that ' + 'returning an\n' + ' empty string is then an unambiguous EOF indication. ' + 'It is also\n' + ' possible (in cases where it might matter, for example, ' + 'if you want\n' + ' to make an exact copy of a file while scanning its ' + 'lines) to tell\n' + ' whether the last line of a file ended in a newline or ' + 'not (yes\n' + ' this happens!).\n', + 'specialnames': '\n' + 'Special method names\n' + '********************\n' + '\n' + 'A class can implement certain operations that are invoked ' + 'by special\n' + 'syntax (such as arithmetic operations or subscripting and ' + 'slicing) by\n' + "defining methods with special names. This is Python's " + 'approach to\n' + '*operator overloading*, allowing classes to define their ' + 'own behavior\n' + 'with respect to language operators. For instance, if a ' + 'class defines\n' + 'a method named "__getitem__()", and "x" is an instance of ' + 'this class,\n' + 'then "x[i]" is roughly equivalent to "x.__getitem__(i)" ' + 'for old-style\n' + 'classes and "type(x).__getitem__(x, i)" for new-style ' + 'classes. Except\n' + 'where mentioned, attempts to execute an operation raise an ' + 'exception\n' + 'when no appropriate method is defined (typically ' + '"AttributeError" or\n' + '"TypeError").\n' + '\n' + 'When implementing a class that emulates any built-in type, ' + 'it is\n' + 'important that the emulation only be implemented to the ' + 'degree that it\n' + 'makes sense for the object being modelled. For example, ' + 'some\n' + 'sequences may work well with retrieval of individual ' + 'elements, but\n' + 'extracting a slice may not make sense. (One example of ' + 'this is the\n' + '"NodeList" interface in the W3C\'s Document Object ' + 'Model.)\n' + '\n' + '\n' + 'Basic customization\n' + '===================\n' + '\n' + 'object.__new__(cls[, ...])\n' + '\n' + ' Called to create a new instance of class *cls*. ' + '"__new__()" is a\n' + ' static method (special-cased so you need not declare it ' + 'as such)\n' + ' that takes the class of which an instance was requested ' + 'as its\n' + ' first argument. The remaining arguments are those ' + 'passed to the\n' + ' object constructor expression (the call to the class). ' + 'The return\n' + ' value of "__new__()" should be the new object instance ' + '(usually an\n' + ' instance of *cls*).\n' + '\n' + ' Typical implementations create a new instance of the ' + 'class by\n' + ' invoking the superclass\'s "__new__()" method using\n' + ' "super(currentclass, cls).__new__(cls[, ...])" with ' + 'appropriate\n' + ' arguments and then modifying the newly-created instance ' + 'as\n' + ' necessary before returning it.\n' + '\n' + ' If "__new__()" returns an instance of *cls*, then the ' + 'new\n' + ' instance\'s "__init__()" method will be invoked like\n' + ' "__init__(self[, ...])", where *self* is the new ' + 'instance and the\n' + ' remaining arguments are the same as were passed to ' + '"__new__()".\n' + '\n' + ' If "__new__()" does not return an instance of *cls*, ' + 'then the new\n' + ' instance\'s "__init__()" method will not be invoked.\n' + '\n' + ' "__new__()" is intended mainly to allow subclasses of ' + 'immutable\n' + ' types (like int, str, or tuple) to customize instance ' + 'creation. It\n' + ' is also commonly overridden in custom metaclasses in ' + 'order to\n' + ' customize class creation.\n' + '\n' + 'object.__init__(self[, ...])\n' + '\n' + ' Called after the instance has been created (by ' + '"__new__()"), but\n' + ' before it is returned to the caller. The arguments are ' + 'those\n' + ' passed to the class constructor expression. If a base ' + 'class has an\n' + ' "__init__()" method, the derived class\'s "__init__()" ' + 'method, if\n' + ' any, must explicitly call it to ensure proper ' + 'initialization of the\n' + ' base class part of the instance; for example:\n' + ' "BaseClass.__init__(self, [args...])".\n' + '\n' + ' Because "__new__()" and "__init__()" work together in ' + 'constructing\n' + ' objects ("__new__()" to create it, and "__init__()" to ' + 'customise\n' + ' it), no non-"None" value may be returned by ' + '"__init__()"; doing so\n' + ' will cause a "TypeError" to be raised at runtime.\n' + '\n' + 'object.__del__(self)\n' + '\n' + ' Called when the instance is about to be destroyed. ' + 'This is also\n' + ' called a destructor. If a base class has a "__del__()" ' + 'method, the\n' + ' derived class\'s "__del__()" method, if any, must ' + 'explicitly call it\n' + ' to ensure proper deletion of the base class part of the ' + 'instance.\n' + ' Note that it is possible (though not recommended!) for ' + 'the\n' + ' "__del__()" method to postpone destruction of the ' + 'instance by\n' + ' creating a new reference to it. It may then be called ' + 'at a later\n' + ' time when this new reference is deleted. It is not ' + 'guaranteed that\n' + ' "__del__()" methods are called for objects that still ' + 'exist when\n' + ' the interpreter exits.\n' + '\n' + ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' + 'the former\n' + ' decrements the reference count for "x" by one, and ' + 'the latter is\n' + ' only called when "x"\'s reference count reaches ' + 'zero. Some common\n' + ' situations that may prevent the reference count of an ' + 'object from\n' + ' going to zero include: circular references between ' + 'objects (e.g.,\n' + ' a doubly-linked list or a tree data structure with ' + 'parent and\n' + ' child pointers); a reference to the object on the ' + 'stack frame of\n' + ' a function that caught an exception (the traceback ' + 'stored in\n' + ' "sys.exc_traceback" keeps the stack frame alive); or ' + 'a reference\n' + ' to the object on the stack frame that raised an ' + 'unhandled\n' + ' exception in interactive mode (the traceback stored ' + 'in\n' + ' "sys.last_traceback" keeps the stack frame alive). ' + 'The first\n' + ' situation can only be remedied by explicitly breaking ' + 'the cycles;\n' + ' the latter two situations can be resolved by storing ' + '"None" in\n' + ' "sys.exc_traceback" or "sys.last_traceback". ' + 'Circular references\n' + ' which are garbage are detected when the option cycle ' + 'detector is\n' + " enabled (it's on by default), but can only be cleaned " + 'up if there\n' + ' are no Python-level "__del__()" methods involved. ' + 'Refer to the\n' + ' documentation for the "gc" module for more ' + 'information about how\n' + ' "__del__()" methods are handled by the cycle ' + 'detector,\n' + ' particularly the description of the "garbage" value.\n' + '\n' + ' Warning: Due to the precarious circumstances under ' + 'which\n' + ' "__del__()" methods are invoked, exceptions that ' + 'occur during\n' + ' their execution are ignored, and a warning is printed ' + 'to\n' + ' "sys.stderr" instead. Also, when "__del__()" is ' + 'invoked in\n' + ' response to a module being deleted (e.g., when ' + 'execution of the\n' + ' program is done), other globals referenced by the ' + '"__del__()"\n' + ' method may already have been deleted or in the ' + 'process of being\n' + ' torn down (e.g. the import machinery shutting down). ' + 'For this\n' + ' reason, "__del__()" methods should do the absolute ' + 'minimum needed\n' + ' to maintain external invariants. Starting with ' + 'version 1.5,\n' + ' Python guarantees that globals whose name begins with ' + 'a single\n' + ' underscore are deleted from their module before other ' + 'globals are\n' + ' deleted; if no other references to such globals ' + 'exist, this may\n' + ' help in assuring that imported modules are still ' + 'available at the\n' + ' time when the "__del__()" method is called.\n' + '\n' + ' See also the "-R" command-line option.\n' + '\n' + 'object.__repr__(self)\n' + '\n' + ' Called by the "repr()" built-in function and by string ' + 'conversions\n' + ' (reverse quotes) to compute the "official" string ' + 'representation of\n' + ' an object. If at all possible, this should look like a ' + 'valid\n' + ' Python expression that could be used to recreate an ' + 'object with the\n' + ' same value (given an appropriate environment). If this ' + 'is not\n' + ' possible, a string of the form "<...some useful ' + 'description...>"\n' + ' should be returned. The return value must be a string ' + 'object. If a\n' + ' class defines "__repr__()" but not "__str__()", then ' + '"__repr__()"\n' + ' is also used when an "informal" string representation ' + 'of instances\n' + ' of that class is required.\n' + '\n' + ' This is typically used for debugging, so it is ' + 'important that the\n' + ' representation is information-rich and unambiguous.\n' + '\n' + 'object.__str__(self)\n' + '\n' + ' Called by the "str()" built-in function and by the ' + '"print"\n' + ' statement to compute the "informal" string ' + 'representation of an\n' + ' object. This differs from "__repr__()" in that it does ' + 'not have to\n' + ' be a valid Python expression: a more convenient or ' + 'concise\n' + ' representation may be used instead. The return value ' + 'must be a\n' + ' string object.\n' + '\n' + 'object.__lt__(self, other)\n' + 'object.__le__(self, other)\n' + 'object.__eq__(self, other)\n' + 'object.__ne__(self, other)\n' + 'object.__gt__(self, other)\n' + 'object.__ge__(self, other)\n' + '\n' + ' New in version 2.1.\n' + '\n' + ' These are the so-called "rich comparison" methods, and ' + 'are called\n' + ' for comparison operators in preference to "__cmp__()" ' + 'below. The\n' + ' correspondence between operator symbols and method ' + 'names is as\n' + ' follows: "xy" call ' + '"x.__ne__(y)",\n' + ' "x>y" calls "x.__gt__(y)", and "x>=y" calls ' + '"x.__ge__(y)".\n' + '\n' + ' A rich comparison method may return the singleton ' + '"NotImplemented"\n' + ' if it does not implement the operation for a given pair ' + 'of\n' + ' arguments. By convention, "False" and "True" are ' + 'returned for a\n' + ' successful comparison. However, these methods can ' + 'return any value,\n' + ' so if the comparison operator is used in a Boolean ' + 'context (e.g.,\n' + ' in the condition of an "if" statement), Python will ' + 'call "bool()"\n' + ' on the value to determine if the result is true or ' + 'false.\n' + '\n' + ' There are no implied relationships among the comparison ' + 'operators.\n' + ' The truth of "x==y" does not imply that "x!=y" is ' + 'false.\n' + ' Accordingly, when defining "__eq__()", one should also ' + 'define\n' + ' "__ne__()" so that the operators will behave as ' + 'expected. See the\n' + ' paragraph on "__hash__()" for some important notes on ' + 'creating\n' + ' *hashable* objects which support custom comparison ' + 'operations and\n' + ' are usable as dictionary keys.\n' + '\n' + ' There are no swapped-argument versions of these methods ' + '(to be used\n' + ' when the left argument does not support the operation ' + 'but the right\n' + ' argument does); rather, "__lt__()" and "__gt__()" are ' + "each other's\n" + ' reflection, "__le__()" and "__ge__()" are each other\'s ' + 'reflection,\n' + ' and "__eq__()" and "__ne__()" are their own ' + 'reflection.\n' + '\n' + ' Arguments to rich comparison methods are never ' + 'coerced.\n' + '\n' + ' To automatically generate ordering operations from a ' + 'single root\n' + ' operation, see "functools.total_ordering()".\n' + '\n' + 'object.__cmp__(self, other)\n' + '\n' + ' Called by comparison operations if rich comparison (see ' + 'above) is\n' + ' not defined. Should return a negative integer if "self ' + '< other",\n' + ' zero if "self == other", a positive integer if "self > ' + 'other". If\n' + ' no "__cmp__()", "__eq__()" or "__ne__()" operation is ' + 'defined,\n' + ' class instances are compared by object identity ' + '("address"). See\n' + ' also the description of "__hash__()" for some important ' + 'notes on\n' + ' creating *hashable* objects which support custom ' + 'comparison\n' + ' operations and are usable as dictionary keys. (Note: ' + 'the\n' + ' restriction that exceptions are not propagated by ' + '"__cmp__()" has\n' + ' been removed since Python 1.5.)\n' + '\n' + 'object.__rcmp__(self, other)\n' + '\n' + ' Changed in version 2.1: No longer supported.\n' + '\n' + 'object.__hash__(self)\n' + '\n' + ' Called by built-in function "hash()" and for operations ' + 'on members\n' + ' of hashed collections including "set", "frozenset", and ' + '"dict".\n' + ' "__hash__()" should return an integer. The only ' + 'required property\n' + ' is that objects which compare equal have the same hash ' + 'value; it is\n' + ' advised to somehow mix together (e.g. using exclusive ' + 'or) the hash\n' + ' values for the components of the object that also play ' + 'a part in\n' + ' comparison of objects.\n' + '\n' + ' If a class does not define a "__cmp__()" or "__eq__()" ' + 'method it\n' + ' should not define a "__hash__()" operation either; if ' + 'it defines\n' + ' "__cmp__()" or "__eq__()" but not "__hash__()", its ' + 'instances will\n' + ' not be usable in hashed collections. If a class ' + 'defines mutable\n' + ' objects and implements a "__cmp__()" or "__eq__()" ' + 'method, it\n' + ' should not implement "__hash__()", since hashable ' + 'collection\n' + " implementations require that a object's hash value is " + 'immutable (if\n' + " the object's hash value changes, it will be in the " + 'wrong hash\n' + ' bucket).\n' + '\n' + ' User-defined classes have "__cmp__()" and "__hash__()" ' + 'methods by\n' + ' default; with them, all objects compare unequal (except ' + 'with\n' + ' themselves) and "x.__hash__()" returns a result derived ' + 'from\n' + ' "id(x)".\n' + '\n' + ' Classes which inherit a "__hash__()" method from a ' + 'parent class but\n' + ' change the meaning of "__cmp__()" or "__eq__()" such ' + 'that the hash\n' + ' value returned is no longer appropriate (e.g. by ' + 'switching to a\n' + ' value-based concept of equality instead of the default ' + 'identity\n' + ' based equality) can explicitly flag themselves as being ' + 'unhashable\n' + ' by setting "__hash__ = None" in the class definition. ' + 'Doing so\n' + ' means that not only will instances of the class raise ' + 'an\n' + ' appropriate "TypeError" when a program attempts to ' + 'retrieve their\n' + ' hash value, but they will also be correctly identified ' + 'as\n' + ' unhashable when checking "isinstance(obj, ' + 'collections.Hashable)"\n' + ' (unlike classes which define their own "__hash__()" to ' + 'explicitly\n' + ' raise "TypeError").\n' + '\n' + ' Changed in version 2.5: "__hash__()" may now also ' + 'return a long\n' + ' integer object; the 32-bit integer is then derived from ' + 'the hash of\n' + ' that object.\n' + '\n' + ' Changed in version 2.6: "__hash__" may now be set to ' + '"None" to\n' + ' explicitly flag instances of a class as unhashable.\n' + '\n' + 'object.__nonzero__(self)\n' + '\n' + ' Called to implement truth value testing and the ' + 'built-in operation\n' + ' "bool()"; should return "False" or "True", or their ' + 'integer\n' + ' equivalents "0" or "1". When this method is not ' + 'defined,\n' + ' "__len__()" is called, if it is defined, and the object ' + 'is\n' + ' considered true if its result is nonzero. If a class ' + 'defines\n' + ' neither "__len__()" nor "__nonzero__()", all its ' + 'instances are\n' + ' considered true.\n' + '\n' + 'object.__unicode__(self)\n' + '\n' + ' Called to implement "unicode()" built-in; should return ' + 'a Unicode\n' + ' object. When this method is not defined, string ' + 'conversion is\n' + ' attempted, and the result of string conversion is ' + 'converted to\n' + ' Unicode using the system default encoding.\n' + '\n' + '\n' + 'Customizing attribute access\n' + '============================\n' + '\n' + 'The following methods can be defined to customize the ' + 'meaning of\n' + 'attribute access (use of, assignment to, or deletion of ' + '"x.name") for\n' + 'class instances.\n' + '\n' + 'object.__getattr__(self, name)\n' + '\n' + ' Called when an attribute lookup has not found the ' + 'attribute in the\n' + ' usual places (i.e. it is not an instance attribute nor ' + 'is it found\n' + ' in the class tree for "self"). "name" is the attribute ' + 'name. This\n' + ' method should return the (computed) attribute value or ' + 'raise an\n' + ' "AttributeError" exception.\n' + '\n' + ' Note that if the attribute is found through the normal ' + 'mechanism,\n' + ' "__getattr__()" is not called. (This is an intentional ' + 'asymmetry\n' + ' between "__getattr__()" and "__setattr__()".) This is ' + 'done both for\n' + ' efficiency reasons and because otherwise ' + '"__getattr__()" would have\n' + ' no way to access other attributes of the instance. ' + 'Note that at\n' + ' least for instance variables, you can fake total ' + 'control by not\n' + ' inserting any values in the instance attribute ' + 'dictionary (but\n' + ' instead inserting them in another object). See the\n' + ' "__getattribute__()" method below for a way to actually ' + 'get total\n' + ' control in new-style classes.\n' + '\n' + 'object.__setattr__(self, name, value)\n' + '\n' + ' Called when an attribute assignment is attempted. This ' + 'is called\n' + ' instead of the normal mechanism (i.e. store the value ' + 'in the\n' + ' instance dictionary). *name* is the attribute name, ' + '*value* is the\n' + ' value to be assigned to it.\n' + '\n' + ' If "__setattr__()" wants to assign to an instance ' + 'attribute, it\n' + ' should not simply execute "self.name = value" --- this ' + 'would cause\n' + ' a recursive call to itself. Instead, it should insert ' + 'the value in\n' + ' the dictionary of instance attributes, e.g., ' + '"self.__dict__[name] =\n' + ' value". For new-style classes, rather than accessing ' + 'the instance\n' + ' dictionary, it should call the base class method with ' + 'the same\n' + ' name, for example, "object.__setattr__(self, name, ' + 'value)".\n' + '\n' + 'object.__delattr__(self, name)\n' + '\n' + ' Like "__setattr__()" but for attribute deletion instead ' + 'of\n' + ' assignment. This should only be implemented if "del ' + 'obj.name" is\n' + ' meaningful for the object.\n' + '\n' + '\n' + 'More attribute access for new-style classes\n' + '-------------------------------------------\n' + '\n' + 'The following methods only apply to new-style classes.\n' + '\n' + 'object.__getattribute__(self, name)\n' + '\n' + ' Called unconditionally to implement attribute accesses ' + 'for\n' + ' instances of the class. If the class also defines ' + '"__getattr__()",\n' + ' the latter will not be called unless ' + '"__getattribute__()" either\n' + ' calls it explicitly or raises an "AttributeError". This ' + 'method\n' + ' should return the (computed) attribute value or raise ' + 'an\n' + ' "AttributeError" exception. In order to avoid infinite ' + 'recursion in\n' + ' this method, its implementation should always call the ' + 'base class\n' + ' method with the same name to access any attributes it ' + 'needs, for\n' + ' example, "object.__getattribute__(self, name)".\n' + '\n' + ' Note: This method may still be bypassed when looking up ' + 'special\n' + ' methods as the result of implicit invocation via ' + 'language syntax\n' + ' or built-in functions. See Special method lookup for ' + 'new-style\n' + ' classes.\n' + '\n' + '\n' + 'Implementing Descriptors\n' + '------------------------\n' + '\n' + 'The following methods only apply when an instance of the ' + 'class\n' + 'containing the method (a so-called *descriptor* class) ' + 'appears in an\n' + '*owner* class (the descriptor must be in either the ' + "owner's class\n" + 'dictionary or in the class dictionary for one of its ' + 'parents). In the\n' + 'examples below, "the attribute" refers to the attribute ' + 'whose name is\n' + 'the key of the property in the owner class\' "__dict__".\n' + '\n' + 'object.__get__(self, instance, owner)\n' + '\n' + ' Called to get the attribute of the owner class (class ' + 'attribute\n' + ' access) or of an instance of that class (instance ' + 'attribute\n' + ' access). *owner* is always the owner class, while ' + '*instance* is the\n' + ' instance that the attribute was accessed through, or ' + '"None" when\n' + ' the attribute is accessed through the *owner*. This ' + 'method should\n' + ' return the (computed) attribute value or raise an ' + '"AttributeError"\n' + ' exception.\n' + '\n' + 'object.__set__(self, instance, value)\n' + '\n' + ' Called to set the attribute on an instance *instance* ' + 'of the owner\n' + ' class to a new value, *value*.\n' + '\n' + 'object.__delete__(self, instance)\n' + '\n' + ' Called to delete the attribute on an instance ' + '*instance* of the\n' + ' owner class.\n' + '\n' + '\n' + 'Invoking Descriptors\n' + '--------------------\n' + '\n' + 'In general, a descriptor is an object attribute with ' + '"binding\n' + 'behavior", one whose attribute access has been overridden ' + 'by methods\n' + 'in the descriptor protocol: "__get__()", "__set__()", ' + 'and\n' + '"__delete__()". If any of those methods are defined for an ' + 'object, it\n' + 'is said to be a descriptor.\n' + '\n' + 'The default behavior for attribute access is to get, set, ' + 'or delete\n' + "the attribute from an object's dictionary. For instance, " + '"a.x" has a\n' + 'lookup chain starting with "a.__dict__[\'x\']", then\n' + '"type(a).__dict__[\'x\']", and continuing through the base ' + 'classes of\n' + '"type(a)" excluding metaclasses.\n' + '\n' + 'However, if the looked-up value is an object defining one ' + 'of the\n' + 'descriptor methods, then Python may override the default ' + 'behavior and\n' + 'invoke the descriptor method instead. Where this occurs ' + 'in the\n' + 'precedence chain depends on which descriptor methods were ' + 'defined and\n' + 'how they were called. Note that descriptors are only ' + 'invoked for new\n' + 'style objects or classes (ones that subclass "object()" or ' + '"type()").\n' + '\n' + 'The starting point for descriptor invocation is a binding, ' + '"a.x". How\n' + 'the arguments are assembled depends on "a":\n' + '\n' + 'Direct Call\n' + ' The simplest and least common call is when user code ' + 'directly\n' + ' invokes a descriptor method: "x.__get__(a)".\n' + '\n' + 'Instance Binding\n' + ' If binding to a new-style object instance, "a.x" is ' + 'transformed\n' + ' into the call: "type(a).__dict__[\'x\'].__get__(a, ' + 'type(a))".\n' + '\n' + 'Class Binding\n' + ' If binding to a new-style class, "A.x" is transformed ' + 'into the\n' + ' call: "A.__dict__[\'x\'].__get__(None, A)".\n' + '\n' + 'Super Binding\n' + ' If "a" is an instance of "super", then the binding ' + '"super(B,\n' + ' obj).m()" searches "obj.__class__.__mro__" for the base ' + 'class "A"\n' + ' immediately preceding "B" and then invokes the ' + 'descriptor with the\n' + ' call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n' + '\n' + 'For instance bindings, the precedence of descriptor ' + 'invocation depends\n' + 'on the which descriptor methods are defined. A descriptor ' + 'can define\n' + 'any combination of "__get__()", "__set__()" and ' + '"__delete__()". If it\n' + 'does not define "__get__()", then accessing the attribute ' + 'will return\n' + 'the descriptor object itself unless there is a value in ' + "the object's\n" + 'instance dictionary. If the descriptor defines ' + '"__set__()" and/or\n' + '"__delete__()", it is a data descriptor; if it defines ' + 'neither, it is\n' + 'a non-data descriptor. Normally, data descriptors define ' + 'both\n' + '"__get__()" and "__set__()", while non-data descriptors ' + 'have just the\n' + '"__get__()" method. Data descriptors with "__set__()" and ' + '"__get__()"\n' + 'defined always override a redefinition in an instance ' + 'dictionary. In\n' + 'contrast, non-data descriptors can be overridden by ' + 'instances.\n' + '\n' + 'Python methods (including "staticmethod()" and ' + '"classmethod()") are\n' + 'implemented as non-data descriptors. Accordingly, ' + 'instances can\n' + 'redefine and override methods. This allows individual ' + 'instances to\n' + 'acquire behaviors that differ from other instances of the ' + 'same class.\n' + '\n' + 'The "property()" function is implemented as a data ' + 'descriptor.\n' + 'Accordingly, instances cannot override the behavior of a ' + 'property.\n' + '\n' + '\n' + '__slots__\n' + '---------\n' + '\n' + 'By default, instances of both old and new-style classes ' + 'have a\n' + 'dictionary for attribute storage. This wastes space for ' + 'objects\n' + 'having very few instance variables. The space consumption ' + 'can become\n' + 'acute when creating large numbers of instances.\n' + '\n' + 'The default can be overridden by defining *__slots__* in a ' + 'new-style\n' + 'class definition. The *__slots__* declaration takes a ' + 'sequence of\n' + 'instance variables and reserves just enough space in each ' + 'instance to\n' + 'hold a value for each variable. Space is saved because ' + '*__dict__* is\n' + 'not created for each instance.\n' + '\n' + '__slots__\n' + '\n' + ' This class variable can be assigned a string, iterable, ' + 'or sequence\n' + ' of strings with variable names used by instances. If ' + 'defined in a\n' + ' new-style class, *__slots__* reserves space for the ' + 'declared\n' + ' variables and prevents the automatic creation of ' + '*__dict__* and\n' + ' *__weakref__* for each instance.\n' + '\n' + ' New in version 2.2.\n' + '\n' + 'Notes on using *__slots__*\n' + '\n' + '* When inheriting from a class without *__slots__*, the ' + '*__dict__*\n' + ' attribute of that class will always be accessible, so a ' + '*__slots__*\n' + ' definition in the subclass is meaningless.\n' + '\n' + '* Without a *__dict__* variable, instances cannot be ' + 'assigned new\n' + ' variables not listed in the *__slots__* definition. ' + 'Attempts to\n' + ' assign to an unlisted variable name raises ' + '"AttributeError". If\n' + ' dynamic assignment of new variables is desired, then ' + 'add\n' + ' "\'__dict__\'" to the sequence of strings in the ' + '*__slots__*\n' + ' declaration.\n' + '\n' + ' Changed in version 2.3: Previously, adding ' + '"\'__dict__\'" to the\n' + ' *__slots__* declaration would not enable the assignment ' + 'of new\n' + ' attributes not specifically listed in the sequence of ' + 'instance\n' + ' variable names.\n' + '\n' + '* Without a *__weakref__* variable for each instance, ' + 'classes\n' + ' defining *__slots__* do not support weak references to ' + 'its\n' + ' instances. If weak reference support is needed, then ' + 'add\n' + ' "\'__weakref__\'" to the sequence of strings in the ' + '*__slots__*\n' + ' declaration.\n' + '\n' + ' Changed in version 2.3: Previously, adding ' + '"\'__weakref__\'" to the\n' + ' *__slots__* declaration would not enable support for ' + 'weak\n' + ' references.\n' + '\n' + '* *__slots__* are implemented at the class level by ' + 'creating\n' + ' descriptors (Implementing Descriptors) for each variable ' + 'name. As a\n' + ' result, class attributes cannot be used to set default ' + 'values for\n' + ' instance variables defined by *__slots__*; otherwise, ' + 'the class\n' + ' attribute would overwrite the descriptor assignment.\n' + '\n' + '* The action of a *__slots__* declaration is limited to ' + 'the class\n' + ' where it is defined. As a result, subclasses will have ' + 'a *__dict__*\n' + ' unless they also define *__slots__* (which must only ' + 'contain names\n' + ' of any *additional* slots).\n' + '\n' + '* If a class defines a slot also defined in a base class, ' + 'the\n' + ' instance variable defined by the base class slot is ' + 'inaccessible\n' + ' (except by retrieving its descriptor directly from the ' + 'base class).\n' + ' This renders the meaning of the program undefined. In ' + 'the future, a\n' + ' check may be added to prevent this.\n' + '\n' + '* Nonempty *__slots__* does not work for classes derived ' + 'from\n' + ' "variable-length" built-in types such as "long", "str" ' + 'and "tuple".\n' + '\n' + '* Any non-string iterable may be assigned to *__slots__*. ' + 'Mappings\n' + ' may also be used; however, in the future, special ' + 'meaning may be\n' + ' assigned to the values corresponding to each key.\n' + '\n' + '* *__class__* assignment works only if both classes have ' + 'the same\n' + ' *__slots__*.\n' + '\n' + ' Changed in version 2.6: Previously, *__class__* ' + 'assignment raised an\n' + ' error if either new or old class had *__slots__*.\n' + '\n' + '\n' + 'Customizing class creation\n' + '==========================\n' + '\n' + 'By default, new-style classes are constructed using ' + '"type()". A class\n' + 'definition is read into a separate namespace and the value ' + 'of class\n' + 'name is bound to the result of "type(name, bases, dict)".\n' + '\n' + 'When the class definition is read, if *__metaclass__* is ' + 'defined then\n' + 'the callable assigned to it will be called instead of ' + '"type()". This\n' + 'allows classes or functions to be written which monitor or ' + 'alter the\n' + 'class creation process:\n' + '\n' + '* Modifying the class dictionary prior to the class being ' + 'created.\n' + '\n' + '* Returning an instance of another class -- essentially ' + 'performing\n' + ' the role of a factory function.\n' + '\n' + "These steps will have to be performed in the metaclass's " + '"__new__()"\n' + 'method -- "type.__new__()" can then be called from this ' + 'method to\n' + 'create a class with different properties. This example ' + 'adds a new\n' + 'element to the class dictionary before creating the ' + 'class:\n' + '\n' + ' class metacls(type):\n' + ' def __new__(mcs, name, bases, dict):\n' + " dict['foo'] = 'metacls was here'\n" + ' return type.__new__(mcs, name, bases, dict)\n' + '\n' + 'You can of course also override other class methods (or ' + 'add new\n' + 'methods); for example defining a custom "__call__()" ' + 'method in the\n' + 'metaclass allows custom behavior when the class is called, ' + 'e.g. not\n' + 'always creating a new instance.\n' + '\n' + '__metaclass__\n' + '\n' + ' This variable can be any callable accepting arguments ' + 'for "name",\n' + ' "bases", and "dict". Upon class creation, the callable ' + 'is used\n' + ' instead of the built-in "type()".\n' + '\n' + ' New in version 2.2.\n' + '\n' + 'The appropriate metaclass is determined by the following ' + 'precedence\n' + 'rules:\n' + '\n' + '* If "dict[\'__metaclass__\']" exists, it is used.\n' + '\n' + '* Otherwise, if there is at least one base class, its ' + 'metaclass is\n' + ' used (this looks for a *__class__* attribute first and ' + 'if not found,\n' + ' uses its type).\n' + '\n' + '* Otherwise, if a global variable named __metaclass__ ' + 'exists, it is\n' + ' used.\n' + '\n' + '* Otherwise, the old-style, classic metaclass ' + '(types.ClassType) is\n' + ' used.\n' + '\n' + 'The potential uses for metaclasses are boundless. Some ' + 'ideas that have\n' + 'been explored including logging, interface checking, ' + 'automatic\n' + 'delegation, automatic property creation, proxies, ' + 'frameworks, and\n' + 'automatic resource locking/synchronization.\n' + '\n' + '\n' + 'Customizing instance and subclass checks\n' + '========================================\n' + '\n' + 'New in version 2.6.\n' + '\n' + 'The following methods are used to override the default ' + 'behavior of the\n' + '"isinstance()" and "issubclass()" built-in functions.\n' + '\n' + 'In particular, the metaclass "abc.ABCMeta" implements ' + 'these methods in\n' + 'order to allow the addition of Abstract Base Classes ' + '(ABCs) as\n' + '"virtual base classes" to any class or type (including ' + 'built-in\n' + 'types), including other ABCs.\n' + '\n' + 'class.__instancecheck__(self, instance)\n' + '\n' + ' Return true if *instance* should be considered a ' + '(direct or\n' + ' indirect) instance of *class*. If defined, called to ' + 'implement\n' + ' "isinstance(instance, class)".\n' + '\n' + 'class.__subclasscheck__(self, subclass)\n' + '\n' + ' Return true if *subclass* should be considered a ' + '(direct or\n' + ' indirect) subclass of *class*. If defined, called to ' + 'implement\n' + ' "issubclass(subclass, class)".\n' + '\n' + 'Note that these methods are looked up on the type ' + '(metaclass) of a\n' + 'class. They cannot be defined as class methods in the ' + 'actual class.\n' + 'This is consistent with the lookup of special methods that ' + 'are called\n' + 'on instances, only in this case the instance is itself a ' + 'class.\n' + '\n' + 'See also: **PEP 3119** - Introducing Abstract Base ' + 'Classes\n' + '\n' + ' Includes the specification for customizing ' + '"isinstance()" and\n' + ' "issubclass()" behavior through "__instancecheck__()" ' + 'and\n' + ' "__subclasscheck__()", with motivation for this ' + 'functionality in\n' + ' the context of adding Abstract Base Classes (see the ' + '"abc"\n' + ' module) to the language.\n' + '\n' + '\n' + 'Emulating callable objects\n' + '==========================\n' + '\n' + 'object.__call__(self[, args...])\n' + '\n' + ' Called when the instance is "called" as a function; if ' + 'this method\n' + ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' + ' "x.__call__(arg1, arg2, ...)".\n' + '\n' + '\n' + 'Emulating container types\n' + '=========================\n' + '\n' + 'The following methods can be defined to implement ' + 'container objects.\n' + 'Containers usually are sequences (such as lists or tuples) ' + 'or mappings\n' + '(like dictionaries), but can represent other containers as ' + 'well. The\n' + 'first set of methods is used either to emulate a sequence ' + 'or to\n' + 'emulate a mapping; the difference is that for a sequence, ' + 'the\n' + 'allowable keys should be the integers *k* for which "0 <= ' + 'k < N" where\n' + '*N* is the length of the sequence, or slice objects, which ' + 'define a\n' + 'range of items. (For backwards compatibility, the method\n' + '"__getslice__()" (see below) can also be defined to handle ' + 'simple, but\n' + 'not extended slices.) It is also recommended that mappings ' + 'provide the\n' + 'methods "keys()", "values()", "items()", "has_key()", ' + '"get()",\n' + '"clear()", "setdefault()", "iterkeys()", "itervalues()",\n' + '"iteritems()", "pop()", "popitem()", "copy()", and ' + '"update()" behaving\n' + "similar to those for Python's standard dictionary " + 'objects. The\n' + '"UserDict" module provides a "DictMixin" class to help ' + 'create those\n' + 'methods from a base set of "__getitem__()", ' + '"__setitem__()",\n' + '"__delitem__()", and "keys()". Mutable sequences should ' + 'provide\n' + 'methods "append()", "count()", "index()", "extend()", ' + '"insert()",\n' + '"pop()", "remove()", "reverse()" and "sort()", like Python ' + 'standard\n' + 'list objects. Finally, sequence types should implement ' + 'addition\n' + '(meaning concatenation) and multiplication (meaning ' + 'repetition) by\n' + 'defining the methods "__add__()", "__radd__()", ' + '"__iadd__()",\n' + '"__mul__()", "__rmul__()" and "__imul__()" described ' + 'below; they\n' + 'should not define "__coerce__()" or other numerical ' + 'operators. It is\n' + 'recommended that both mappings and sequences implement ' + 'the\n' + '"__contains__()" method to allow efficient use of the "in" ' + 'operator;\n' + 'for mappings, "in" should be equivalent of "has_key()"; ' + 'for sequences,\n' + 'it should search through the values. It is further ' + 'recommended that\n' + 'both mappings and sequences implement the "__iter__()" ' + 'method to allow\n' + 'efficient iteration through the container; for mappings, ' + '"__iter__()"\n' + 'should be the same as "iterkeys()"; for sequences, it ' + 'should iterate\n' + 'through the values.\n' + '\n' + 'object.__len__(self)\n' + '\n' + ' Called to implement the built-in function "len()". ' + 'Should return\n' + ' the length of the object, an integer ">=" 0. Also, an ' + 'object that\n' + ' doesn\'t define a "__nonzero__()" method and whose ' + '"__len__()"\n' + ' method returns zero is considered to be false in a ' + 'Boolean context.\n' + '\n' + 'object.__getitem__(self, key)\n' + '\n' + ' Called to implement evaluation of "self[key]". For ' + 'sequence types,\n' + ' the accepted keys should be integers and slice ' + 'objects. Note that\n' + ' the special interpretation of negative indexes (if the ' + 'class wishes\n' + ' to emulate a sequence type) is up to the ' + '"__getitem__()" method. If\n' + ' *key* is of an inappropriate type, "TypeError" may be ' + 'raised; if of\n' + ' a value outside the set of indexes for the sequence ' + '(after any\n' + ' special interpretation of negative values), ' + '"IndexError" should be\n' + ' raised. For mapping types, if *key* is missing (not in ' + 'the\n' + ' container), "KeyError" should be raised.\n' + '\n' + ' Note: "for" loops expect that an "IndexError" will be ' + 'raised for\n' + ' illegal indexes to allow proper detection of the end ' + 'of the\n' + ' sequence.\n' + '\n' + 'object.__missing__(self, key)\n' + '\n' + ' Called by "dict"."__getitem__()" to implement ' + '"self[key]" for dict\n' + ' subclasses when key is not in the dictionary.\n' + '\n' + 'object.__setitem__(self, key, value)\n' + '\n' + ' Called to implement assignment to "self[key]". Same ' + 'note as for\n' + ' "__getitem__()". This should only be implemented for ' + 'mappings if\n' + ' the objects support changes to the values for keys, or ' + 'if new keys\n' + ' can be added, or for sequences if elements can be ' + 'replaced. The\n' + ' same exceptions should be raised for improper *key* ' + 'values as for\n' + ' the "__getitem__()" method.\n' + '\n' + 'object.__delitem__(self, key)\n' + '\n' + ' Called to implement deletion of "self[key]". Same note ' + 'as for\n' + ' "__getitem__()". This should only be implemented for ' + 'mappings if\n' + ' the objects support removal of keys, or for sequences ' + 'if elements\n' + ' can be removed from the sequence. The same exceptions ' + 'should be\n' + ' raised for improper *key* values as for the ' + '"__getitem__()" method.\n' + '\n' + 'object.__iter__(self)\n' + '\n' + ' This method is called when an iterator is required for ' + 'a container.\n' + ' This method should return a new iterator object that ' + 'can iterate\n' + ' over all the objects in the container. For mappings, ' + 'it should\n' + ' iterate over the keys of the container, and should also ' + 'be made\n' + ' available as the method "iterkeys()".\n' + '\n' + ' Iterator objects also need to implement this method; ' + 'they are\n' + ' required to return themselves. For more information on ' + 'iterator\n' + ' objects, see Iterator Types.\n' + '\n' + 'object.__reversed__(self)\n' + '\n' + ' Called (if present) by the "reversed()" built-in to ' + 'implement\n' + ' reverse iteration. It should return a new iterator ' + 'object that\n' + ' iterates over all the objects in the container in ' + 'reverse order.\n' + '\n' + ' If the "__reversed__()" method is not provided, the ' + '"reversed()"\n' + ' built-in will fall back to using the sequence protocol ' + '("__len__()"\n' + ' and "__getitem__()"). Objects that support the ' + 'sequence protocol\n' + ' should only provide "__reversed__()" if they can ' + 'provide an\n' + ' implementation that is more efficient than the one ' + 'provided by\n' + ' "reversed()".\n' + '\n' + ' New in version 2.6.\n' + '\n' + 'The membership test operators ("in" and "not in") are ' + 'normally\n' + 'implemented as an iteration through a sequence. However, ' + 'container\n' + 'objects can supply the following special method with a ' + 'more efficient\n' + 'implementation, which also does not require the object be ' + 'a sequence.\n' + '\n' + 'object.__contains__(self, item)\n' + '\n' + ' Called to implement membership test operators. Should ' + 'return true\n' + ' if *item* is in *self*, false otherwise. For mapping ' + 'objects, this\n' + ' should consider the keys of the mapping rather than the ' + 'values or\n' + ' the key-item pairs.\n' + '\n' + ' For objects that don\'t define "__contains__()", the ' + 'membership test\n' + ' first tries iteration via "__iter__()", then the old ' + 'sequence\n' + ' iteration protocol via "__getitem__()", see this ' + 'section in the\n' + ' language reference.\n' + '\n' + '\n' + 'Additional methods for emulation of sequence types\n' + '==================================================\n' + '\n' + 'The following optional methods can be defined to further ' + 'emulate\n' + 'sequence objects. Immutable sequences methods should at ' + 'most only\n' + 'define "__getslice__()"; mutable sequences might define ' + 'all three\n' + 'methods.\n' + '\n' + 'object.__getslice__(self, i, j)\n' + '\n' + ' Deprecated since version 2.0: Support slice objects as ' + 'parameters\n' + ' to the "__getitem__()" method. (However, built-in types ' + 'in CPython\n' + ' currently still implement "__getslice__()". Therefore, ' + 'you have to\n' + ' override it in derived classes when implementing ' + 'slicing.)\n' + '\n' + ' Called to implement evaluation of "self[i:j]". The ' + 'returned object\n' + ' should be of the same type as *self*. Note that ' + 'missing *i* or *j*\n' + ' in the slice expression are replaced by zero or ' + '"sys.maxsize",\n' + ' respectively. If negative indexes are used in the ' + 'slice, the\n' + ' length of the sequence is added to that index. If the ' + 'instance does\n' + ' not implement the "__len__()" method, an ' + '"AttributeError" is\n' + ' raised. No guarantee is made that indexes adjusted this ' + 'way are not\n' + ' still negative. Indexes which are greater than the ' + 'length of the\n' + ' sequence are not modified. If no "__getslice__()" is ' + 'found, a slice\n' + ' object is created instead, and passed to ' + '"__getitem__()" instead.\n' + '\n' + 'object.__setslice__(self, i, j, sequence)\n' + '\n' + ' Called to implement assignment to "self[i:j]". Same ' + 'notes for *i*\n' + ' and *j* as for "__getslice__()".\n' + '\n' + ' This method is deprecated. If no "__setslice__()" is ' + 'found, or for\n' + ' extended slicing of the form "self[i:j:k]", a slice ' + 'object is\n' + ' created, and passed to "__setitem__()", instead of ' + '"__setslice__()"\n' + ' being called.\n' + '\n' + 'object.__delslice__(self, i, j)\n' + '\n' + ' Called to implement deletion of "self[i:j]". Same notes ' + 'for *i* and\n' + ' *j* as for "__getslice__()". This method is deprecated. ' + 'If no\n' + ' "__delslice__()" is found, or for extended slicing of ' + 'the form\n' + ' "self[i:j:k]", a slice object is created, and passed ' + 'to\n' + ' "__delitem__()", instead of "__delslice__()" being ' + 'called.\n' + '\n' + 'Notice that these methods are only invoked when a single ' + 'slice with a\n' + 'single colon is used, and the slice method is available. ' + 'For slice\n' + 'operations involving extended slice notation, or in ' + 'absence of the\n' + 'slice methods, "__getitem__()", "__setitem__()" or ' + '"__delitem__()" is\n' + 'called with a slice object as argument.\n' + '\n' + 'The following example demonstrate how to make your program ' + 'or module\n' + 'compatible with earlier versions of Python (assuming that ' + 'methods\n' + '"__getitem__()", "__setitem__()" and "__delitem__()" ' + 'support slice\n' + 'objects as arguments):\n' + '\n' + ' class MyClass:\n' + ' ...\n' + ' def __getitem__(self, index):\n' + ' ...\n' + ' def __setitem__(self, index, value):\n' + ' ...\n' + ' def __delitem__(self, index):\n' + ' ...\n' + '\n' + ' if sys.version_info < (2, 0):\n' + " # They won't be defined if version is at least " + '2.0 final\n' + '\n' + ' def __getslice__(self, i, j):\n' + ' return self[max(0, i):max(0, j):]\n' + ' def __setslice__(self, i, j, seq):\n' + ' self[max(0, i):max(0, j):] = seq\n' + ' def __delslice__(self, i, j):\n' + ' del self[max(0, i):max(0, j):]\n' + ' ...\n' + '\n' + 'Note the calls to "max()"; these are necessary because of ' + 'the handling\n' + 'of negative indices before the "__*slice__()" methods are ' + 'called.\n' + 'When negative indexes are used, the "__*item__()" methods ' + 'receive them\n' + 'as provided, but the "__*slice__()" methods get a "cooked" ' + 'form of the\n' + 'index values. For each negative index value, the length ' + 'of the\n' + 'sequence is added to the index before calling the method ' + '(which may\n' + 'still result in a negative index); this is the customary ' + 'handling of\n' + 'negative indexes by the built-in sequence types, and the ' + '"__*item__()"\n' + 'methods are expected to do this as well. However, since ' + 'they should\n' + 'already be doing that, negative indexes cannot be passed ' + 'in; they must\n' + 'be constrained to the bounds of the sequence before being ' + 'passed to\n' + 'the "__*item__()" methods. Calling "max(0, i)" ' + 'conveniently returns\n' + 'the proper value.\n' + '\n' + '\n' + 'Emulating numeric types\n' + '=======================\n' + '\n' + 'The following methods can be defined to emulate numeric ' + 'objects.\n' + 'Methods corresponding to operations that are not supported ' + 'by the\n' + 'particular kind of number implemented (e.g., bitwise ' + 'operations for\n' + 'non-integral numbers) should be left undefined.\n' + '\n' + 'object.__add__(self, other)\n' + 'object.__sub__(self, other)\n' + 'object.__mul__(self, other)\n' + 'object.__floordiv__(self, other)\n' + 'object.__mod__(self, other)\n' + 'object.__divmod__(self, other)\n' + 'object.__pow__(self, other[, modulo])\n' + 'object.__lshift__(self, other)\n' + 'object.__rshift__(self, other)\n' + 'object.__and__(self, other)\n' + 'object.__xor__(self, other)\n' + 'object.__or__(self, other)\n' + '\n' + ' These methods are called to implement the binary ' + 'arithmetic\n' + ' operations ("+", "-", "*", "//", "%", "divmod()", ' + '"pow()", "**",\n' + ' "<<", ">>", "&", "^", "|"). For instance, to evaluate ' + 'the\n' + ' expression "x + y", where *x* is an instance of a class ' + 'that has an\n' + ' "__add__()" method, "x.__add__(y)" is called. The ' + '"__divmod__()"\n' + ' method should be the equivalent to using ' + '"__floordiv__()" and\n' + ' "__mod__()"; it should not be related to ' + '"__truediv__()" (described\n' + ' below). Note that "__pow__()" should be defined to ' + 'accept an\n' + ' optional third argument if the ternary version of the ' + 'built-in\n' + ' "pow()" function is to be supported.\n' + '\n' + ' If one of those methods does not support the operation ' + 'with the\n' + ' supplied arguments, it should return "NotImplemented".\n' + '\n' + 'object.__div__(self, other)\n' + 'object.__truediv__(self, other)\n' + '\n' + ' The division operator ("/") is implemented by these ' + 'methods. The\n' + ' "__truediv__()" method is used when ' + '"__future__.division" is in\n' + ' effect, otherwise "__div__()" is used. If only one of ' + 'these two\n' + ' methods is defined, the object will not support ' + 'division in the\n' + ' alternate context; "TypeError" will be raised instead.\n' + '\n' + 'object.__radd__(self, other)\n' + 'object.__rsub__(self, other)\n' + 'object.__rmul__(self, other)\n' + 'object.__rdiv__(self, other)\n' + 'object.__rtruediv__(self, other)\n' + 'object.__rfloordiv__(self, other)\n' + 'object.__rmod__(self, other)\n' + 'object.__rdivmod__(self, other)\n' + 'object.__rpow__(self, other)\n' + 'object.__rlshift__(self, other)\n' + 'object.__rrshift__(self, other)\n' + 'object.__rand__(self, other)\n' + 'object.__rxor__(self, other)\n' + 'object.__ror__(self, other)\n' + '\n' + ' These methods are called to implement the binary ' + 'arithmetic\n' + ' operations ("+", "-", "*", "/", "%", "divmod()", ' + '"pow()", "**",\n' + ' "<<", ">>", "&", "^", "|") with reflected (swapped) ' + 'operands.\n' + ' These functions are only called if the left operand ' + 'does not\n' + ' support the corresponding operation and the operands ' + 'are of\n' + ' different types. [2] For instance, to evaluate the ' + 'expression "x -\n' + ' y", where *y* is an instance of a class that has an ' + '"__rsub__()"\n' + ' method, "y.__rsub__(x)" is called if "x.__sub__(y)" ' + 'returns\n' + ' *NotImplemented*.\n' + '\n' + ' Note that ternary "pow()" will not try calling ' + '"__rpow__()" (the\n' + ' coercion rules would become too complicated).\n' + '\n' + " Note: If the right operand's type is a subclass of the " + 'left\n' + " operand's type and that subclass provides the " + 'reflected method\n' + ' for the operation, this method will be called before ' + 'the left\n' + " operand's non-reflected method. This behavior allows " + 'subclasses\n' + " to override their ancestors' operations.\n" + '\n' + 'object.__iadd__(self, other)\n' + 'object.__isub__(self, other)\n' + 'object.__imul__(self, other)\n' + 'object.__idiv__(self, other)\n' + 'object.__itruediv__(self, other)\n' + 'object.__ifloordiv__(self, other)\n' + 'object.__imod__(self, other)\n' + 'object.__ipow__(self, other[, modulo])\n' + 'object.__ilshift__(self, other)\n' + 'object.__irshift__(self, other)\n' + 'object.__iand__(self, other)\n' + 'object.__ixor__(self, other)\n' + 'object.__ior__(self, other)\n' + '\n' + ' These methods are called to implement the augmented ' + 'arithmetic\n' + ' assignments ("+=", "-=", "*=", "/=", "//=", "%=", ' + '"**=", "<<=",\n' + ' ">>=", "&=", "^=", "|="). These methods should attempt ' + 'to do the\n' + ' operation in-place (modifying *self*) and return the ' + 'result (which\n' + ' could be, but does not have to be, *self*). If a ' + 'specific method\n' + ' is not defined, the augmented assignment falls back to ' + 'the normal\n' + ' methods. For instance, to execute the statement "x += ' + 'y", where\n' + ' *x* is an instance of a class that has an "__iadd__()" ' + 'method,\n' + ' "x.__iadd__(y)" is called. If *x* is an instance of a ' + 'class that\n' + ' does not define a "__iadd__()" method, "x.__add__(y)" ' + 'and\n' + ' "y.__radd__(x)" are considered, as with the evaluation ' + 'of "x + y".\n' + '\n' + 'object.__neg__(self)\n' + 'object.__pos__(self)\n' + 'object.__abs__(self)\n' + 'object.__invert__(self)\n' + '\n' + ' Called to implement the unary arithmetic operations ' + '("-", "+",\n' + ' "abs()" and "~").\n' + '\n' + 'object.__complex__(self)\n' + 'object.__int__(self)\n' + 'object.__long__(self)\n' + 'object.__float__(self)\n' + '\n' + ' Called to implement the built-in functions "complex()", ' + '"int()",\n' + ' "long()", and "float()". Should return a value of the ' + 'appropriate\n' + ' type.\n' + '\n' + 'object.__oct__(self)\n' + 'object.__hex__(self)\n' + '\n' + ' Called to implement the built-in functions "oct()" and ' + '"hex()".\n' + ' Should return a string value.\n' + '\n' + 'object.__index__(self)\n' + '\n' + ' Called to implement "operator.index()". Also called ' + 'whenever\n' + ' Python needs an integer object (such as in slicing). ' + 'Must return\n' + ' an integer (int or long).\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'object.__coerce__(self, other)\n' + '\n' + ' Called to implement "mixed-mode" numeric arithmetic. ' + 'Should either\n' + ' return a 2-tuple containing *self* and *other* ' + 'converted to a\n' + ' common numeric type, or "None" if conversion is ' + 'impossible. When\n' + ' the common type would be the type of "other", it is ' + 'sufficient to\n' + ' return "None", since the interpreter will also ask the ' + 'other object\n' + ' to attempt a coercion (but sometimes, if the ' + 'implementation of the\n' + ' other type cannot be changed, it is useful to do the ' + 'conversion to\n' + ' the other type here). A return value of ' + '"NotImplemented" is\n' + ' equivalent to returning "None".\n' + '\n' + '\n' + 'Coercion rules\n' + '==============\n' + '\n' + 'This section used to document the rules for coercion. As ' + 'the language\n' + 'has evolved, the coercion rules have become hard to ' + 'document\n' + 'precisely; documenting what one version of one particular\n' + 'implementation does is undesirable. Instead, here are ' + 'some informal\n' + 'guidelines regarding coercion. In Python 3, coercion will ' + 'not be\n' + 'supported.\n' + '\n' + '* If the left operand of a % operator is a string or ' + 'Unicode object,\n' + ' no coercion takes place and the string formatting ' + 'operation is\n' + ' invoked instead.\n' + '\n' + '* It is no longer recommended to define a coercion ' + 'operation. Mixed-\n' + " mode operations on types that don't define coercion pass " + 'the\n' + ' original arguments to the operation.\n' + '\n' + '* New-style classes (those derived from "object") never ' + 'invoke the\n' + ' "__coerce__()" method in response to a binary operator; ' + 'the only\n' + ' time "__coerce__()" is invoked is when the built-in ' + 'function\n' + ' "coerce()" is called.\n' + '\n' + '* For most intents and purposes, an operator that returns\n' + ' "NotImplemented" is treated the same as one that is not ' + 'implemented\n' + ' at all.\n' + '\n' + '* Below, "__op__()" and "__rop__()" are used to signify ' + 'the generic\n' + ' method names corresponding to an operator; "__iop__()" ' + 'is used for\n' + ' the corresponding in-place operator. For example, for ' + 'the operator\n' + ' \'"+"\', "__add__()" and "__radd__()" are used for the ' + 'left and right\n' + ' variant of the binary operator, and "__iadd__()" for the ' + 'in-place\n' + ' variant.\n' + '\n' + '* For objects *x* and *y*, first "x.__op__(y)" is tried. ' + 'If this is\n' + ' not implemented or returns "NotImplemented", ' + '"y.__rop__(x)" is\n' + ' tried. If this is also not implemented or returns ' + '"NotImplemented",\n' + ' a "TypeError" exception is raised. But see the ' + 'following exception:\n' + '\n' + '* Exception to the previous item: if the left operand is ' + 'an instance\n' + ' of a built-in type or a new-style class, and the right ' + 'operand is an\n' + ' instance of a proper subclass of that type or class and ' + 'overrides\n' + ' the base\'s "__rop__()" method, the right operand\'s ' + '"__rop__()"\n' + ' method is tried *before* the left operand\'s "__op__()" ' + 'method.\n' + '\n' + ' This is done so that a subclass can completely override ' + 'binary\n' + ' operators. Otherwise, the left operand\'s "__op__()" ' + 'method would\n' + ' always accept the right operand: when an instance of a ' + 'given class\n' + ' is expected, an instance of a subclass of that class is ' + 'always\n' + ' acceptable.\n' + '\n' + '* When either operand type defines a coercion, this ' + 'coercion is\n' + ' called before that type\'s "__op__()" or "__rop__()" ' + 'method is\n' + ' called, but no sooner. If the coercion returns an ' + 'object of a\n' + ' different type for the operand whose coercion is ' + 'invoked, part of\n' + ' the process is redone using the new object.\n' + '\n' + '* When an in-place operator (like \'"+="\') is used, if ' + 'the left\n' + ' operand implements "__iop__()", it is invoked without ' + 'any coercion.\n' + ' When the operation falls back to "__op__()" and/or ' + '"__rop__()", the\n' + ' normal coercion rules apply.\n' + '\n' + '* In "x + y", if *x* is a sequence that implements ' + 'sequence\n' + ' concatenation, sequence concatenation is invoked.\n' + '\n' + '* In "x * y", if one operand is a sequence that implements ' + 'sequence\n' + ' repetition, and the other is an integer ("int" or ' + '"long"), sequence\n' + ' repetition is invoked.\n' + '\n' + '* Rich comparisons (implemented by methods "__eq__()" and ' + 'so on)\n' + ' never use coercion. Three-way comparison (implemented ' + 'by\n' + ' "__cmp__()") does use coercion under the same conditions ' + 'as other\n' + ' binary operations use it.\n' + '\n' + '* In the current implementation, the built-in numeric ' + 'types "int",\n' + ' "long", "float", and "complex" do not use coercion. All ' + 'these types\n' + ' implement a "__coerce__()" method, for use by the ' + 'built-in\n' + ' "coerce()" function.\n' + '\n' + ' Changed in version 2.7: The complex type no longer makes ' + 'implicit\n' + ' calls to the "__coerce__()" method for mixed-type binary ' + 'arithmetic\n' + ' operations.\n' + '\n' + '\n' + 'With Statement Context Managers\n' + '===============================\n' + '\n' + 'New in version 2.5.\n' + '\n' + 'A *context manager* is an object that defines the runtime ' + 'context to\n' + 'be established when executing a "with" statement. The ' + 'context manager\n' + 'handles the entry into, and the exit from, the desired ' + 'runtime context\n' + 'for the execution of the block of code. Context managers ' + 'are normally\n' + 'invoked using the "with" statement (described in section ' + 'The with\n' + 'statement), but can also be used by directly invoking ' + 'their methods.\n' + '\n' + 'Typical uses of context managers include saving and ' + 'restoring various\n' + 'kinds of global state, locking and unlocking resources, ' + 'closing opened\n' + 'files, etc.\n' + '\n' + 'For more information on context managers, see Context ' + 'Manager Types.\n' + '\n' + 'object.__enter__(self)\n' + '\n' + ' Enter the runtime context related to this object. The ' + '"with"\n' + " statement will bind this method's return value to the " + 'target(s)\n' + ' specified in the "as" clause of the statement, if any.\n' + '\n' + 'object.__exit__(self, exc_type, exc_value, traceback)\n' + '\n' + ' Exit the runtime context related to this object. The ' + 'parameters\n' + ' describe the exception that caused the context to be ' + 'exited. If the\n' + ' context was exited without an exception, all three ' + 'arguments will\n' + ' be "None".\n' + '\n' + ' If an exception is supplied, and the method wishes to ' + 'suppress the\n' + ' exception (i.e., prevent it from being propagated), it ' + 'should\n' + ' return a true value. Otherwise, the exception will be ' + 'processed\n' + ' normally upon exit from this method.\n' + '\n' + ' Note that "__exit__()" methods should not reraise the ' + 'passed-in\n' + " exception; this is the caller's responsibility.\n" + '\n' + 'See also: **PEP 0343** - The "with" statement\n' + '\n' + ' The specification, background, and examples for the ' + 'Python "with"\n' + ' statement.\n' + '\n' + '\n' + 'Special method lookup for old-style classes\n' + '===========================================\n' + '\n' + 'For old-style classes, special methods are always looked ' + 'up in exactly\n' + 'the same way as any other method or attribute. This is the ' + 'case\n' + 'regardless of whether the method is being looked up ' + 'explicitly as in\n' + '"x.__getitem__(i)" or implicitly as in "x[i]".\n' + '\n' + 'This behaviour means that special methods may exhibit ' + 'different\n' + 'behaviour for different instances of a single old-style ' + 'class if the\n' + 'appropriate special attributes are set differently:\n' + '\n' + ' >>> class C:\n' + ' ... pass\n' + ' ...\n' + ' >>> c1 = C()\n' + ' >>> c2 = C()\n' + ' >>> c1.__len__ = lambda: 5\n' + ' >>> c2.__len__ = lambda: 9\n' + ' >>> len(c1)\n' + ' 5\n' + ' >>> len(c2)\n' + ' 9\n' + '\n' + '\n' + 'Special method lookup for new-style classes\n' + '===========================================\n' + '\n' + 'For new-style classes, implicit invocations of special ' + 'methods are\n' + 'only guaranteed to work correctly if defined on an ' + "object's type, not\n" + "in the object's instance dictionary. That behaviour is " + 'the reason why\n' + 'the following code raises an exception (unlike the ' + 'equivalent example\n' + 'with old-style classes):\n' + '\n' + ' >>> class C(object):\n' + ' ... pass\n' + ' ...\n' + ' >>> c = C()\n' + ' >>> c.__len__ = lambda: 5\n' + ' >>> len(c)\n' + ' Traceback (most recent call last):\n' + ' File "", line 1, in \n' + " TypeError: object of type 'C' has no len()\n" + '\n' + 'The rationale behind this behaviour lies with a number of ' + 'special\n' + 'methods such as "__hash__()" and "__repr__()" that are ' + 'implemented by\n' + 'all objects, including type objects. If the implicit ' + 'lookup of these\n' + 'methods used the conventional lookup process, they would ' + 'fail when\n' + 'invoked on the type object itself:\n' + '\n' + ' >>> 1 .__hash__() == hash(1)\n' + ' True\n' + ' >>> int.__hash__() == hash(int)\n' + ' Traceback (most recent call last):\n' + ' File "", line 1, in \n' + " TypeError: descriptor '__hash__' of 'int' object needs " + 'an argument\n' + '\n' + 'Incorrectly attempting to invoke an unbound method of a ' + 'class in this\n' + "way is sometimes referred to as 'metaclass confusion', and " + 'is avoided\n' + 'by bypassing the instance when looking up special ' + 'methods:\n' + '\n' + ' >>> type(1).__hash__(1) == hash(1)\n' + ' True\n' + ' >>> type(int).__hash__(int) == hash(int)\n' + ' True\n' + '\n' + 'In addition to bypassing any instance attributes in the ' + 'interest of\n' + 'correctness, implicit special method lookup generally also ' + 'bypasses\n' + 'the "__getattribute__()" method even of the object\'s ' + 'metaclass:\n' + '\n' + ' >>> class Meta(type):\n' + ' ... def __getattribute__(*args):\n' + ' ... print "Metaclass getattribute invoked"\n' + ' ... return type.__getattribute__(*args)\n' + ' ...\n' + ' >>> class C(object):\n' + ' ... __metaclass__ = Meta\n' + ' ... def __len__(self):\n' + ' ... return 10\n' + ' ... def __getattribute__(*args):\n' + ' ... print "Class getattribute invoked"\n' + ' ... return object.__getattribute__(*args)\n' + ' ...\n' + ' >>> c = C()\n' + ' >>> c.__len__() # Explicit lookup via ' + 'instance\n' + ' Class getattribute invoked\n' + ' 10\n' + ' >>> type(c).__len__(c) # Explicit lookup via ' + 'type\n' + ' Metaclass getattribute invoked\n' + ' 10\n' + ' >>> len(c) # Implicit lookup\n' + ' 10\n' + '\n' + 'Bypassing the "__getattribute__()" machinery in this ' + 'fashion provides\n' + 'significant scope for speed optimisations within the ' + 'interpreter, at\n' + 'the cost of some flexibility in the handling of special ' + 'methods (the\n' + 'special method *must* be set on the class object itself in ' + 'order to be\n' + 'consistently invoked by the interpreter).\n' + '\n' + '-[ Footnotes ]-\n' + '\n' + "[1] It *is* possible in some cases to change an object's " + 'type,\n' + ' under certain controlled conditions. It generally ' + "isn't a good\n" + ' idea though, since it can lead to some very strange ' + 'behaviour if\n' + ' it is handled incorrectly.\n' + '\n' + '[2] For operands of the same type, it is assumed that if ' + 'the non-\n' + ' reflected method (such as "__add__()") fails the ' + 'operation is not\n' + ' supported, which is why the reflected method is not ' + 'called.\n', + 'string-methods': '\n' + 'String Methods\n' + '**************\n' + '\n' + 'Below are listed the string methods which both 8-bit ' + 'strings and\n' + 'Unicode objects support. Some of them are also ' + 'available on\n' + '"bytearray" objects.\n' + '\n' + "In addition, Python's strings support the sequence type " + 'methods\n' + 'described in the Sequence Types --- str, unicode, list, ' + 'tuple,\n' + 'bytearray, buffer, xrange section. To output formatted ' + 'strings use\n' + 'template strings or the "%" operator described in the ' + 'String\n' + 'Formatting Operations section. Also, see the "re" module ' + 'for string\n' + 'functions based on regular expressions.\n' + '\n' + 'str.capitalize()\n' + '\n' + ' Return a copy of the string with its first character ' + 'capitalized\n' + ' and the rest lowercased.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.center(width[, fillchar])\n' + '\n' + ' Return centered in a string of length *width*. ' + 'Padding is done\n' + ' using the specified *fillchar* (default is a space).\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.count(sub[, start[, end]])\n' + '\n' + ' Return the number of non-overlapping occurrences of ' + 'substring *sub*\n' + ' in the range [*start*, *end*]. Optional arguments ' + '*start* and\n' + ' *end* are interpreted as in slice notation.\n' + '\n' + 'str.decode([encoding[, errors]])\n' + '\n' + ' Decodes the string using the codec registered for ' + '*encoding*.\n' + ' *encoding* defaults to the default string encoding. ' + '*errors* may\n' + ' be given to set a different error handling scheme. ' + 'The default is\n' + ' "\'strict\'", meaning that encoding errors raise ' + '"UnicodeError".\n' + ' Other possible values are "\'ignore\'", "\'replace\'" ' + 'and any other\n' + ' name registered via "codecs.register_error()", see ' + 'section Codec\n' + ' Base Classes.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' Changed in version 2.3: Support for other error ' + 'handling schemes\n' + ' added.\n' + '\n' + ' Changed in version 2.7: Support for keyword arguments ' + 'added.\n' + '\n' + 'str.encode([encoding[, errors]])\n' + '\n' + ' Return an encoded version of the string. Default ' + 'encoding is the\n' + ' current default string encoding. *errors* may be ' + 'given to set a\n' + ' different error handling scheme. The default for ' + '*errors* is\n' + ' "\'strict\'", meaning that encoding errors raise a ' + '"UnicodeError".\n' + ' Other possible values are "\'ignore\'", ' + '"\'replace\'",\n' + ' "\'xmlcharrefreplace\'", "\'backslashreplace\'" and ' + 'any other name\n' + ' registered via "codecs.register_error()", see section ' + 'Codec Base\n' + ' Classes. For a list of possible encodings, see ' + 'section Standard\n' + ' Encodings.\n' + '\n' + ' New in version 2.0.\n' + '\n' + ' Changed in version 2.3: Support for ' + '"\'xmlcharrefreplace\'" and\n' + ' "\'backslashreplace\'" and other error handling ' + 'schemes added.\n' + '\n' + ' Changed in version 2.7: Support for keyword arguments ' + 'added.\n' + '\n' + 'str.endswith(suffix[, start[, end]])\n' + '\n' + ' Return "True" if the string ends with the specified ' + '*suffix*,\n' + ' otherwise return "False". *suffix* can also be a ' + 'tuple of suffixes\n' + ' to look for. With optional *start*, test beginning ' + 'at that\n' + ' position. With optional *end*, stop comparing at ' + 'that position.\n' + '\n' + ' Changed in version 2.5: Accept tuples as *suffix*.\n' + '\n' + 'str.expandtabs([tabsize])\n' + '\n' + ' Return a copy of the string where all tab characters ' + 'are replaced\n' + ' by one or more spaces, depending on the current ' + 'column and the\n' + ' given tab size. Tab positions occur every *tabsize* ' + 'characters\n' + ' (default is 8, giving tab positions at columns 0, 8, ' + '16 and so on).\n' + ' To expand the string, the current column is set to ' + 'zero and the\n' + ' string is examined character by character. If the ' + 'character is a\n' + ' tab ("\\t"), one or more space characters are ' + 'inserted in the result\n' + ' until the current column is equal to the next tab ' + 'position. (The\n' + ' tab character itself is not copied.) If the ' + 'character is a newline\n' + ' ("\\n") or return ("\\r"), it is copied and the ' + 'current column is\n' + ' reset to zero. Any other character is copied ' + 'unchanged and the\n' + ' current column is incremented by one regardless of ' + 'how the\n' + ' character is represented when printed.\n' + '\n' + " >>> '01\\t012\\t0123\\t01234'.expandtabs()\n" + " '01 012 0123 01234'\n" + " >>> '01\\t012\\t0123\\t01234'.expandtabs(4)\n" + " '01 012 0123 01234'\n" + '\n' + 'str.find(sub[, start[, end]])\n' + '\n' + ' Return the lowest index in the string where substring ' + '*sub* is\n' + ' found, such that *sub* is contained in the slice ' + '"s[start:end]".\n' + ' Optional arguments *start* and *end* are interpreted ' + 'as in slice\n' + ' notation. Return "-1" if *sub* is not found.\n' + '\n' + ' Note: The "find()" method should be used only if you ' + 'need to know\n' + ' the position of *sub*. To check if *sub* is a ' + 'substring or not,\n' + ' use the "in" operator:\n' + '\n' + " >>> 'Py' in 'Python'\n" + ' True\n' + '\n' + 'str.format(*args, **kwargs)\n' + '\n' + ' Perform a string formatting operation. The string on ' + 'which this\n' + ' method is called can contain literal text or ' + 'replacement fields\n' + ' delimited by braces "{}". Each replacement field ' + 'contains either\n' + ' the numeric index of a positional argument, or the ' + 'name of a\n' + ' keyword argument. Returns a copy of the string where ' + 'each\n' + ' replacement field is replaced with the string value ' + 'of the\n' + ' corresponding argument.\n' + '\n' + ' >>> "The sum of 1 + 2 is {0}".format(1+2)\n' + " 'The sum of 1 + 2 is 3'\n" + '\n' + ' See Format String Syntax for a description of the ' + 'various\n' + ' formatting options that can be specified in format ' + 'strings.\n' + '\n' + ' This method of string formatting is the new standard ' + 'in Python 3,\n' + ' and should be preferred to the "%" formatting ' + 'described in String\n' + ' Formatting Operations in new code.\n' + '\n' + ' New in version 2.6.\n' + '\n' + 'str.index(sub[, start[, end]])\n' + '\n' + ' Like "find()", but raise "ValueError" when the ' + 'substring is not\n' + ' found.\n' + '\n' + 'str.isalnum()\n' + '\n' + ' Return true if all characters in the string are ' + 'alphanumeric and\n' + ' there is at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isalpha()\n' + '\n' + ' Return true if all characters in the string are ' + 'alphabetic and\n' + ' there is at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isdigit()\n' + '\n' + ' Return true if all characters in the string are ' + 'digits and there is\n' + ' at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.islower()\n' + '\n' + ' Return true if all cased characters [4] in the string ' + 'are lowercase\n' + ' and there is at least one cased character, false ' + 'otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isspace()\n' + '\n' + ' Return true if there are only whitespace characters ' + 'in the string\n' + ' and there is at least one character, false ' + 'otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.istitle()\n' + '\n' + ' Return true if the string is a titlecased string and ' + 'there is at\n' + ' least one character, for example uppercase characters ' + 'may only\n' + ' follow uncased characters and lowercase characters ' + 'only cased ones.\n' + ' Return false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isupper()\n' + '\n' + ' Return true if all cased characters [4] in the string ' + 'are uppercase\n' + ' and there is at least one cased character, false ' + 'otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.join(iterable)\n' + '\n' + ' Return a string which is the concatenation of the ' + 'strings in the\n' + ' *iterable* *iterable*. The separator between ' + 'elements is the\n' + ' string providing this method.\n' + '\n' + 'str.ljust(width[, fillchar])\n' + '\n' + ' Return the string left justified in a string of ' + 'length *width*.\n' + ' Padding is done using the specified *fillchar* ' + '(default is a\n' + ' space). The original string is returned if *width* ' + 'is less than or\n' + ' equal to "len(s)".\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.lower()\n' + '\n' + ' Return a copy of the string with all the cased ' + 'characters [4]\n' + ' converted to lowercase.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.lstrip([chars])\n' + '\n' + ' Return a copy of the string with leading characters ' + 'removed. The\n' + ' *chars* argument is a string specifying the set of ' + 'characters to be\n' + ' removed. If omitted or "None", the *chars* argument ' + 'defaults to\n' + ' removing whitespace. The *chars* argument is not a ' + 'prefix; rather,\n' + ' all combinations of its values are stripped:\n' + '\n' + " >>> ' spacious '.lstrip()\n" + " 'spacious '\n" + " >>> 'www.example.com'.lstrip('cmowz.')\n" + " 'example.com'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.partition(sep)\n' + '\n' + ' Split the string at the first occurrence of *sep*, ' + 'and return a\n' + ' 3-tuple containing the part before the separator, the ' + 'separator\n' + ' itself, and the part after the separator. If the ' + 'separator is not\n' + ' found, return a 3-tuple containing the string itself, ' + 'followed by\n' + ' two empty strings.\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'str.replace(old, new[, count])\n' + '\n' + ' Return a copy of the string with all occurrences of ' + 'substring *old*\n' + ' replaced by *new*. If the optional argument *count* ' + 'is given, only\n' + ' the first *count* occurrences are replaced.\n' + '\n' + 'str.rfind(sub[, start[, end]])\n' + '\n' + ' Return the highest index in the string where ' + 'substring *sub* is\n' + ' found, such that *sub* is contained within ' + '"s[start:end]".\n' + ' Optional arguments *start* and *end* are interpreted ' + 'as in slice\n' + ' notation. Return "-1" on failure.\n' + '\n' + 'str.rindex(sub[, start[, end]])\n' + '\n' + ' Like "rfind()" but raises "ValueError" when the ' + 'substring *sub* is\n' + ' not found.\n' + '\n' + 'str.rjust(width[, fillchar])\n' + '\n' + ' Return the string right justified in a string of ' + 'length *width*.\n' + ' Padding is done using the specified *fillchar* ' + '(default is a\n' + ' space). The original string is returned if *width* is ' + 'less than or\n' + ' equal to "len(s)".\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.rpartition(sep)\n' + '\n' + ' Split the string at the last occurrence of *sep*, and ' + 'return a\n' + ' 3-tuple containing the part before the separator, the ' + 'separator\n' + ' itself, and the part after the separator. If the ' + 'separator is not\n' + ' found, return a 3-tuple containing two empty strings, ' + 'followed by\n' + ' the string itself.\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'str.rsplit([sep[, maxsplit]])\n' + '\n' + ' Return a list of the words in the string, using *sep* ' + 'as the\n' + ' delimiter string. If *maxsplit* is given, at most ' + '*maxsplit* splits\n' + ' are done, the *rightmost* ones. If *sep* is not ' + 'specified or\n' + ' "None", any whitespace string is a separator. Except ' + 'for splitting\n' + ' from the right, "rsplit()" behaves like "split()" ' + 'which is\n' + ' described in detail below.\n' + '\n' + ' New in version 2.4.\n' + '\n' + 'str.rstrip([chars])\n' + '\n' + ' Return a copy of the string with trailing characters ' + 'removed. The\n' + ' *chars* argument is a string specifying the set of ' + 'characters to be\n' + ' removed. If omitted or "None", the *chars* argument ' + 'defaults to\n' + ' removing whitespace. The *chars* argument is not a ' + 'suffix; rather,\n' + ' all combinations of its values are stripped:\n' + '\n' + " >>> ' spacious '.rstrip()\n" + " ' spacious'\n" + " >>> 'mississippi'.rstrip('ipz')\n" + " 'mississ'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.split([sep[, maxsplit]])\n' + '\n' + ' Return a list of the words in the string, using *sep* ' + 'as the\n' + ' delimiter string. If *maxsplit* is given, at most ' + '*maxsplit*\n' + ' splits are done (thus, the list will have at most ' + '"maxsplit+1"\n' + ' elements). If *maxsplit* is not specified or "-1", ' + 'then there is\n' + ' no limit on the number of splits (all possible splits ' + 'are made).\n' + '\n' + ' If *sep* is given, consecutive delimiters are not ' + 'grouped together\n' + ' and are deemed to delimit empty strings (for ' + 'example,\n' + ' "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', ' + '\'2\']"). The *sep* argument\n' + ' may consist of multiple characters (for example,\n' + ' "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', ' + '\'3\']"). Splitting an\n' + ' empty string with a specified separator returns ' + '"[\'\']".\n' + '\n' + ' If *sep* is not specified or is "None", a different ' + 'splitting\n' + ' algorithm is applied: runs of consecutive whitespace ' + 'are regarded\n' + ' as a single separator, and the result will contain no ' + 'empty strings\n' + ' at the start or end if the string has leading or ' + 'trailing\n' + ' whitespace. Consequently, splitting an empty string ' + 'or a string\n' + ' consisting of just whitespace with a "None" separator ' + 'returns "[]".\n' + '\n' + ' For example, "\' 1 2 3 \'.split()" returns ' + '"[\'1\', \'2\', \'3\']", and\n' + ' "\' 1 2 3 \'.split(None, 1)" returns "[\'1\', ' + '\'2 3 \']".\n' + '\n' + 'str.splitlines([keepends])\n' + '\n' + ' Return a list of the lines in the string, breaking at ' + 'line\n' + ' boundaries. This method uses the *universal newlines* ' + 'approach to\n' + ' splitting lines. Line breaks are not included in the ' + 'resulting list\n' + ' unless *keepends* is given and true.\n' + '\n' + ' For example, "\'ab c\\n\\nde ' + 'fg\\rkl\\r\\n\'.splitlines()" returns "[\'ab\n' + ' c\', \'\', \'de fg\', \'kl\']", while the same call ' + 'with\n' + ' "splitlines(True)" returns "[\'ab c\\n\', \'\\n\', ' + '\'de fg\\r\', \'kl\\r\\n\']".\n' + '\n' + ' Unlike "split()" when a delimiter string *sep* is ' + 'given, this\n' + ' method returns an empty list for the empty string, ' + 'and a terminal\n' + ' line break does not result in an extra line.\n' + '\n' + 'str.startswith(prefix[, start[, end]])\n' + '\n' + ' Return "True" if string starts with the *prefix*, ' + 'otherwise return\n' + ' "False". *prefix* can also be a tuple of prefixes to ' + 'look for.\n' + ' With optional *start*, test string beginning at that ' + 'position.\n' + ' With optional *end*, stop comparing string at that ' + 'position.\n' + '\n' + ' Changed in version 2.5: Accept tuples as *prefix*.\n' + '\n' + 'str.strip([chars])\n' + '\n' + ' Return a copy of the string with the leading and ' + 'trailing\n' + ' characters removed. The *chars* argument is a string ' + 'specifying the\n' + ' set of characters to be removed. If omitted or ' + '"None", the *chars*\n' + ' argument defaults to removing whitespace. The *chars* ' + 'argument is\n' + ' not a prefix or suffix; rather, all combinations of ' + 'its values are\n' + ' stripped:\n' + '\n' + " >>> ' spacious '.strip()\n" + " 'spacious'\n" + " >>> 'www.example.com'.strip('cmowz.')\n" + " 'example'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.swapcase()\n' + '\n' + ' Return a copy of the string with uppercase characters ' + 'converted to\n' + ' lowercase and vice versa.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.title()\n' + '\n' + ' Return a titlecased version of the string where words ' + 'start with an\n' + ' uppercase character and the remaining characters are ' + 'lowercase.\n' + '\n' + ' The algorithm uses a simple language-independent ' + 'definition of a\n' + ' word as groups of consecutive letters. The ' + 'definition works in\n' + ' many contexts but it means that apostrophes in ' + 'contractions and\n' + ' possessives form word boundaries, which may not be ' + 'the desired\n' + ' result:\n' + '\n' + ' >>> "they\'re bill\'s friends from the ' + 'UK".title()\n' + ' "They\'Re Bill\'S Friends From The Uk"\n' + '\n' + ' A workaround for apostrophes can be constructed using ' + 'regular\n' + ' expressions:\n' + '\n' + ' >>> import re\n' + ' >>> def titlecase(s):\n' + ' ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n' + ' ... lambda mo: ' + 'mo.group(0)[0].upper() +\n' + ' ... ' + 'mo.group(0)[1:].lower(),\n' + ' ... s)\n' + ' ...\n' + ' >>> titlecase("they\'re bill\'s friends.")\n' + ' "They\'re Bill\'s Friends."\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.translate(table[, deletechars])\n' + '\n' + ' Return a copy of the string where all characters ' + 'occurring in the\n' + ' optional argument *deletechars* are removed, and the ' + 'remaining\n' + ' characters have been mapped through the given ' + 'translation table,\n' + ' which must be a string of length 256.\n' + '\n' + ' You can use the "maketrans()" helper function in the ' + '"string"\n' + ' module to create a translation table. For string ' + 'objects, set the\n' + ' *table* argument to "None" for translations that only ' + 'delete\n' + ' characters:\n' + '\n' + " >>> 'read this short text'.translate(None, 'aeiou')\n" + " 'rd ths shrt txt'\n" + '\n' + ' New in version 2.6: Support for a "None" *table* ' + 'argument.\n' + '\n' + ' For Unicode objects, the "translate()" method does ' + 'not accept the\n' + ' optional *deletechars* argument. Instead, it returns ' + 'a copy of the\n' + ' *s* where all characters have been mapped through the ' + 'given\n' + ' translation table which must be a mapping of Unicode ' + 'ordinals to\n' + ' Unicode ordinals, Unicode strings or "None". Unmapped ' + 'characters\n' + ' are left untouched. Characters mapped to "None" are ' + 'deleted. Note,\n' + ' a more flexible approach is to create a custom ' + 'character mapping\n' + ' codec using the "codecs" module (see ' + '"encodings.cp1251" for an\n' + ' example).\n' + '\n' + 'str.upper()\n' + '\n' + ' Return a copy of the string with all the cased ' + 'characters [4]\n' + ' converted to uppercase. Note that ' + '"str.upper().isupper()" might be\n' + ' "False" if "s" contains uncased characters or if the ' + 'Unicode\n' + ' category of the resulting character(s) is not "Lu" ' + '(Letter,\n' + ' uppercase), but e.g. "Lt" (Letter, titlecase).\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.zfill(width)\n' + '\n' + ' Return the numeric string left filled with zeros in a ' + 'string of\n' + ' length *width*. A sign prefix is handled correctly. ' + 'The original\n' + ' string is returned if *width* is less than or equal ' + 'to "len(s)".\n' + '\n' + ' New in version 2.2.2.\n' + '\n' + 'The following methods are present only on unicode ' + 'objects:\n' + '\n' + 'unicode.isnumeric()\n' + '\n' + ' Return "True" if there are only numeric characters in ' + 'S, "False"\n' + ' otherwise. Numeric characters include digit ' + 'characters, and all\n' + ' characters that have the Unicode numeric value ' + 'property, e.g.\n' + ' U+2155, VULGAR FRACTION ONE FIFTH.\n' + '\n' + 'unicode.isdecimal()\n' + '\n' + ' Return "True" if there are only decimal characters in ' + 'S, "False"\n' + ' otherwise. Decimal characters include digit ' + 'characters, and all\n' + ' characters that can be used to form decimal-radix ' + 'numbers, e.g.\n' + ' U+0660, ARABIC-INDIC DIGIT ZERO.\n', + 'strings': '\n' + 'String literals\n' + '***************\n' + '\n' + 'String literals are described by the following lexical ' + 'definitions:\n' + '\n' + ' stringliteral ::= [stringprefix](shortstring | ' + 'longstring)\n' + ' stringprefix ::= "r" | "u" | "ur" | "R" | "U" | "UR" | ' + '"Ur" | "uR"\n' + ' | "b" | "B" | "br" | "Br" | "bR" | "BR"\n' + ' shortstring ::= "\'" shortstringitem* "\'" | \'"\' ' + 'shortstringitem* \'"\'\n' + ' longstring ::= "\'\'\'" longstringitem* "\'\'\'"\n' + ' | \'"""\' longstringitem* \'"""\'\n' + ' shortstringitem ::= shortstringchar | escapeseq\n' + ' longstringitem ::= longstringchar | escapeseq\n' + ' shortstringchar ::= \n' + ' longstringchar ::= \n' + ' escapeseq ::= "\\" \n' + '\n' + 'One syntactic restriction not indicated by these productions is ' + 'that\n' + 'whitespace is not allowed between the "stringprefix" and the ' + 'rest of\n' + 'the string literal. The source character set is defined by the\n' + 'encoding declaration; it is ASCII if no encoding declaration is ' + 'given\n' + 'in the source file; see section Encoding declarations.\n' + '\n' + 'In plain English: String literals can be enclosed in matching ' + 'single\n' + 'quotes ("\'") or double quotes ("""). They can also be ' + 'enclosed in\n' + 'matching groups of three single or double quotes (these are ' + 'generally\n' + 'referred to as *triple-quoted strings*). The backslash ("\\")\n' + 'character is used to escape characters that otherwise have a ' + 'special\n' + 'meaning, such as newline, backslash itself, or the quote ' + 'character.\n' + 'String literals may optionally be prefixed with a letter ' + '"\'r\'" or\n' + '"\'R\'"; such strings are called *raw strings* and use ' + 'different rules\n' + 'for interpreting backslash escape sequences. A prefix of ' + '"\'u\'" or\n' + '"\'U\'" makes the string a Unicode string. Unicode strings use ' + 'the\n' + 'Unicode character set as defined by the Unicode Consortium and ' + 'ISO\n' + '10646. Some additional escape sequences, described below, are\n' + 'available in Unicode strings. A prefix of "\'b\'" or "\'B\'" is ' + 'ignored in\n' + 'Python 2; it indicates that the literal should become a bytes ' + 'literal\n' + 'in Python 3 (e.g. when code is automatically converted with ' + '2to3). A\n' + '"\'u\'" or "\'b\'" prefix may be followed by an "\'r\'" ' + 'prefix.\n' + '\n' + 'In triple-quoted strings, unescaped newlines and quotes are ' + 'allowed\n' + '(and are retained), except that three unescaped quotes in a ' + 'row\n' + 'terminate the string. (A "quote" is the character used to open ' + 'the\n' + 'string, i.e. either "\'" or """.)\n' + '\n' + 'Unless an "\'r\'" or "\'R\'" prefix is present, escape ' + 'sequences in\n' + 'strings are interpreted according to rules similar to those ' + 'used by\n' + 'Standard C. The recognized escape sequences are:\n' + '\n' + '+-------------------+-----------------------------------+---------+\n' + '| Escape Sequence | Meaning | ' + 'Notes |\n' + '+===================+===================================+=========+\n' + '| "\\newline" | Ignored ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\\\" | Backslash ("\\") ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\\'" | Single quote ("\'") ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\"" | Double quote (""") ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\a" | ASCII Bell (BEL) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\b" | ASCII Backspace (BS) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\f" | ASCII Formfeed (FF) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\n" | ASCII Linefeed (LF) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\N{name}" | Character named *name* in the ' + '| |\n' + '| | Unicode database (Unicode only) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\r" | ASCII Carriage Return (CR) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\t" | ASCII Horizontal Tab (TAB) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\uxxxx" | Character with 16-bit hex value | ' + '(1) |\n' + '| | *xxxx* (Unicode only) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' + '(2) |\n' + '| | *xxxxxxxx* (Unicode only) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\v" | ASCII Vertical Tab (VT) ' + '| |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\ooo" | Character with octal value *ooo* | ' + '(3,5) |\n' + '+-------------------+-----------------------------------+---------+\n' + '| "\\xhh" | Character with hex value *hh* | ' + '(4,5) |\n' + '+-------------------+-----------------------------------+---------+\n' + '\n' + 'Notes:\n' + '\n' + '1. Individual code units which form parts of a surrogate pair ' + 'can\n' + ' be encoded using this escape sequence.\n' + '\n' + '2. Any Unicode character can be encoded this way, but ' + 'characters\n' + ' outside the Basic Multilingual Plane (BMP) will be encoded ' + 'using a\n' + ' surrogate pair if Python is compiled to use 16-bit code ' + 'units (the\n' + ' default).\n' + '\n' + '3. As in Standard C, up to three octal digits are accepted.\n' + '\n' + '4. Unlike in Standard C, exactly two hex digits are required.\n' + '\n' + '5. In a string literal, hexadecimal and octal escapes denote ' + 'the\n' + ' byte with the given value; it is not necessary that the ' + 'byte\n' + ' encodes a character in the source character set. In a ' + 'Unicode\n' + ' literal, these escapes denote a Unicode character with the ' + 'given\n' + ' value.\n' + '\n' + 'Unlike Standard C, all unrecognized escape sequences are left ' + 'in the\n' + 'string unchanged, i.e., *the backslash is left in the string*. ' + '(This\n' + 'behavior is useful when debugging: if an escape sequence is ' + 'mistyped,\n' + 'the resulting output is more easily recognized as broken.) It ' + 'is also\n' + 'important to note that the escape sequences marked as "(Unicode ' + 'only)"\n' + 'in the table above fall into the category of unrecognized ' + 'escapes for\n' + 'non-Unicode string literals.\n' + '\n' + 'When an "\'r\'" or "\'R\'" prefix is present, a character ' + 'following a\n' + 'backslash is included in the string without change, and *all\n' + 'backslashes are left in the string*. For example, the string ' + 'literal\n' + '"r"\\n"" consists of two characters: a backslash and a ' + 'lowercase "\'n\'".\n' + 'String quotes can be escaped with a backslash, but the ' + 'backslash\n' + 'remains in the string; for example, "r"\\""" is a valid string ' + 'literal\n' + 'consisting of two characters: a backslash and a double quote; ' + '"r"\\""\n' + 'is not a valid string literal (even a raw string cannot end in ' + 'an odd\n' + 'number of backslashes). Specifically, *a raw string cannot end ' + 'in a\n' + 'single backslash* (since the backslash would escape the ' + 'following\n' + 'quote character). Note also that a single backslash followed ' + 'by a\n' + 'newline is interpreted as those two characters as part of the ' + 'string,\n' + '*not* as a line continuation.\n' + '\n' + 'When an "\'r\'" or "\'R\'" prefix is used in conjunction with a ' + '"\'u\'" or\n' + '"\'U\'" prefix, then the "\\uXXXX" and "\\UXXXXXXXX" escape ' + 'sequences are\n' + 'processed while *all other backslashes are left in the ' + 'string*. For\n' + 'example, the string literal "ur"\\u0062\\n"" consists of three ' + 'Unicode\n' + "characters: 'LATIN SMALL LETTER B', 'REVERSE SOLIDUS', and " + "'LATIN\n" + "SMALL LETTER N'. Backslashes can be escaped with a preceding\n" + 'backslash; however, both remain in the string. As a result, ' + '"\\uXXXX"\n' + 'escape sequences are only recognized when there are an odd ' + 'number of\n' + 'backslashes.\n', + 'subscriptions': '\n' + 'Subscriptions\n' + '*************\n' + '\n' + 'A subscription selects an item of a sequence (string, ' + 'tuple or list)\n' + 'or mapping (dictionary) object:\n' + '\n' + ' subscription ::= primary "[" expression_list "]"\n' + '\n' + 'The primary must evaluate to an object of a sequence or ' + 'mapping type.\n' + '\n' + 'If the primary is a mapping, the expression list must ' + 'evaluate to an\n' + 'object whose value is one of the keys of the mapping, and ' + 'the\n' + 'subscription selects the value in the mapping that ' + 'corresponds to that\n' + 'key. (The expression list is a tuple except if it has ' + 'exactly one\n' + 'item.)\n' + '\n' + 'If the primary is a sequence, the expression (list) must ' + 'evaluate to a\n' + 'plain integer. If this value is negative, the length of ' + 'the sequence\n' + 'is added to it (so that, e.g., "x[-1]" selects the last ' + 'item of "x".)\n' + 'The resulting value must be a nonnegative integer less ' + 'than the number\n' + 'of items in the sequence, and the subscription selects ' + 'the item whose\n' + 'index is that value (counting from zero).\n' + '\n' + "A string's items are characters. A character is not a " + 'separate data\n' + 'type but a string of exactly one character.\n', + 'truth': '\n' + 'Truth Value Testing\n' + '*******************\n' + '\n' + 'Any object can be tested for truth value, for use in an "if" or\n' + '"while" condition or as operand of the Boolean operations below. ' + 'The\n' + 'following values are considered false:\n' + '\n' + '* "None"\n' + '\n' + '* "False"\n' + '\n' + '* zero of any numeric type, for example, "0", "0L", "0.0", "0j".\n' + '\n' + '* any empty sequence, for example, "\'\'", "()", "[]".\n' + '\n' + '* any empty mapping, for example, "{}".\n' + '\n' + '* instances of user-defined classes, if the class defines a\n' + ' "__nonzero__()" or "__len__()" method, when that method returns ' + 'the\n' + ' integer zero or "bool" value "False". [1]\n' + '\n' + 'All other values are considered true --- so objects of many types ' + 'are\n' + 'always true.\n' + '\n' + 'Operations and built-in functions that have a Boolean result ' + 'always\n' + 'return "0" or "False" for false and "1" or "True" for true, ' + 'unless\n' + 'otherwise stated. (Important exception: the Boolean operations ' + '"or"\n' + 'and "and" always return one of their operands.)\n', + 'try': '\n' + 'The "try" statement\n' + '*******************\n' + '\n' + 'The "try" statement specifies exception handlers and/or cleanup ' + 'code\n' + 'for a group of statements:\n' + '\n' + ' try_stmt ::= try1_stmt | try2_stmt\n' + ' try1_stmt ::= "try" ":" suite\n' + ' ("except" [expression [("as" | ",") identifier]] ' + '":" suite)+\n' + ' ["else" ":" suite]\n' + ' ["finally" ":" suite]\n' + ' try2_stmt ::= "try" ":" suite\n' + ' "finally" ":" suite\n' + '\n' + 'Changed in version 2.5: In previous versions of Python,\n' + '"try"..."except"..."finally" did not work. "try"..."except" had to ' + 'be\n' + 'nested in "try"..."finally".\n' + '\n' + 'The "except" clause(s) specify one or more exception handlers. When ' + 'no\n' + 'exception occurs in the "try" clause, no exception handler is\n' + 'executed. When an exception occurs in the "try" suite, a search for ' + 'an\n' + 'exception handler is started. This search inspects the except ' + 'clauses\n' + 'in turn until one is found that matches the exception. An ' + 'expression-\n' + 'less except clause, if present, must be last; it matches any\n' + 'exception. For an except clause with an expression, that ' + 'expression\n' + 'is evaluated, and the clause matches the exception if the ' + 'resulting\n' + 'object is "compatible" with the exception. An object is ' + 'compatible\n' + 'with an exception if it is the class or a base class of the ' + 'exception\n' + 'object, or a tuple containing an item compatible with the ' + 'exception.\n' + '\n' + 'If no except clause matches the exception, the search for an ' + 'exception\n' + 'handler continues in the surrounding code and on the invocation ' + 'stack.\n' + '[1]\n' + '\n' + 'If the evaluation of an expression in the header of an except ' + 'clause\n' + 'raises an exception, the original search for a handler is canceled ' + 'and\n' + 'a search starts for the new exception in the surrounding code and ' + 'on\n' + 'the call stack (it is treated as if the entire "try" statement ' + 'raised\n' + 'the exception).\n' + '\n' + 'When a matching except clause is found, the exception is assigned ' + 'to\n' + 'the target specified in that except clause, if present, and the ' + 'except\n' + "clause's suite is executed. All except clauses must have an\n" + 'executable block. When the end of this block is reached, ' + 'execution\n' + 'continues normally after the entire try statement. (This means ' + 'that\n' + 'if two nested handlers exist for the same exception, and the ' + 'exception\n' + 'occurs in the try clause of the inner handler, the outer handler ' + 'will\n' + 'not handle the exception.)\n' + '\n' + "Before an except clause's suite is executed, details about the\n" + 'exception are assigned to three variables in the "sys" module:\n' + '"sys.exc_type" receives the object identifying the exception;\n' + '"sys.exc_value" receives the exception\'s parameter;\n' + '"sys.exc_traceback" receives a traceback object (see section The\n' + 'standard type hierarchy) identifying the point in the program ' + 'where\n' + 'the exception occurred. These details are also available through ' + 'the\n' + '"sys.exc_info()" function, which returns a tuple "(exc_type,\n' + 'exc_value, exc_traceback)". Use of the corresponding variables is\n' + 'deprecated in favor of this function, since their use is unsafe in ' + 'a\n' + 'threaded program. As of Python 1.5, the variables are restored to\n' + 'their previous values (before the call) when returning from a ' + 'function\n' + 'that handled an exception.\n' + '\n' + 'The optional "else" clause is executed if and when control flows ' + 'off\n' + 'the end of the "try" clause. [2] Exceptions in the "else" clause ' + 'are\n' + 'not handled by the preceding "except" clauses.\n' + '\n' + 'If "finally" is present, it specifies a \'cleanup\' handler. The ' + '"try"\n' + 'clause is executed, including any "except" and "else" clauses. If ' + 'an\n' + 'exception occurs in any of the clauses and is not handled, the\n' + 'exception is temporarily saved. The "finally" clause is executed. ' + 'If\n' + 'there is a saved exception, it is re-raised at the end of the\n' + '"finally" clause. If the "finally" clause raises another exception ' + 'or\n' + 'executes a "return" or "break" statement, the saved exception is\n' + 'discarded:\n' + '\n' + ' >>> def f():\n' + ' ... try:\n' + ' ... 1/0\n' + ' ... finally:\n' + ' ... return 42\n' + ' ...\n' + ' >>> f()\n' + ' 42\n' + '\n' + 'The exception information is not available to the program during\n' + 'execution of the "finally" clause.\n' + '\n' + 'When a "return", "break" or "continue" statement is executed in ' + 'the\n' + '"try" suite of a "try"..."finally" statement, the "finally" clause ' + 'is\n' + 'also executed \'on the way out.\' A "continue" statement is illegal ' + 'in\n' + 'the "finally" clause. (The reason is a problem with the current\n' + 'implementation --- this restriction may be lifted in the future).\n' + '\n' + 'The return value of a function is determined by the last "return"\n' + 'statement executed. Since the "finally" clause always executes, a\n' + '"return" statement executed in the "finally" clause will always be ' + 'the\n' + 'last one executed:\n' + '\n' + ' >>> def foo():\n' + ' ... try:\n' + " ... return 'try'\n" + ' ... finally:\n' + " ... return 'finally'\n" + ' ...\n' + ' >>> foo()\n' + " 'finally'\n" + '\n' + 'Additional information on exceptions can be found in section\n' + 'Exceptions, and information on using the "raise" statement to ' + 'generate\n' + 'exceptions may be found in section The raise statement.\n', + 'types': '\n' + 'The standard type hierarchy\n' + '***************************\n' + '\n' + 'Below is a list of the types that are built into Python. ' + 'Extension\n' + 'modules (written in C, Java, or other languages, depending on ' + 'the\n' + 'implementation) can define additional types. Future versions of\n' + 'Python may add types to the type hierarchy (e.g., rational ' + 'numbers,\n' + 'efficiently stored arrays of integers, etc.).\n' + '\n' + 'Some of the type descriptions below contain a paragraph listing\n' + "'special attributes.' These are attributes that provide access " + 'to the\n' + 'implementation and are not intended for general use. Their ' + 'definition\n' + 'may change in the future.\n' + '\n' + 'None\n' + ' This type has a single value. There is a single object with ' + 'this\n' + ' value. This object is accessed through the built-in name ' + '"None". It\n' + ' is used to signify the absence of a value in many situations, ' + 'e.g.,\n' + " it is returned from functions that don't explicitly return\n" + ' anything. Its truth value is false.\n' + '\n' + 'NotImplemented\n' + ' This type has a single value. There is a single object with ' + 'this\n' + ' value. This object is accessed through the built-in name\n' + ' "NotImplemented". Numeric methods and rich comparison methods ' + 'may\n' + ' return this value if they do not implement the operation for ' + 'the\n' + ' operands provided. (The interpreter will then try the ' + 'reflected\n' + ' operation, or some other fallback, depending on the ' + 'operator.) Its\n' + ' truth value is true.\n' + '\n' + 'Ellipsis\n' + ' This type has a single value. There is a single object with ' + 'this\n' + ' value. This object is accessed through the built-in name\n' + ' "Ellipsis". It is used to indicate the presence of the "..." ' + 'syntax\n' + ' in a slice. Its truth value is true.\n' + '\n' + '"numbers.Number"\n' + ' These are created by numeric literals and returned as results ' + 'by\n' + ' arithmetic operators and arithmetic built-in functions. ' + 'Numeric\n' + ' objects are immutable; once created their value never ' + 'changes.\n' + ' Python numbers are of course strongly related to mathematical\n' + ' numbers, but subject to the limitations of numerical ' + 'representation\n' + ' in computers.\n' + '\n' + ' Python distinguishes between integers, floating point numbers, ' + 'and\n' + ' complex numbers:\n' + '\n' + ' "numbers.Integral"\n' + ' These represent elements from the mathematical set of ' + 'integers\n' + ' (positive and negative).\n' + '\n' + ' There are three types of integers:\n' + '\n' + ' Plain integers\n' + ' These represent numbers in the range -2147483648 ' + 'through\n' + ' 2147483647. (The range may be larger on machines with a\n' + ' larger natural word size, but not smaller.) When the ' + 'result\n' + ' of an operation would fall outside this range, the ' + 'result is\n' + ' normally returned as a long integer (in some cases, the\n' + ' exception "OverflowError" is raised instead). For the\n' + ' purpose of shift and mask operations, integers are ' + 'assumed to\n' + " have a binary, 2's complement notation using 32 or more " + 'bits,\n' + ' and hiding no bits from the user (i.e., all 4294967296\n' + ' different bit patterns correspond to different values).\n' + '\n' + ' Long integers\n' + ' These represent numbers in an unlimited range, subject ' + 'to\n' + ' available (virtual) memory only. For the purpose of ' + 'shift\n' + ' and mask operations, a binary representation is assumed, ' + 'and\n' + " negative numbers are represented in a variant of 2's\n" + ' complement which gives the illusion of an infinite ' + 'string of\n' + ' sign bits extending to the left.\n' + '\n' + ' Booleans\n' + ' These represent the truth values False and True. The ' + 'two\n' + ' objects representing the values "False" and "True" are ' + 'the\n' + ' only Boolean objects. The Boolean type is a subtype of ' + 'plain\n' + ' integers, and Boolean values behave like the values 0 ' + 'and 1,\n' + ' respectively, in almost all contexts, the exception ' + 'being\n' + ' that when converted to a string, the strings ""False"" ' + 'or\n' + ' ""True"" are returned, respectively.\n' + '\n' + ' The rules for integer representation are intended to give ' + 'the\n' + ' most meaningful interpretation of shift and mask ' + 'operations\n' + ' involving negative integers and the least surprises when\n' + ' switching between the plain and long integer domains. Any\n' + ' operation, if it yields a result in the plain integer ' + 'domain,\n' + ' will yield the same result in the long integer domain or ' + 'when\n' + ' using mixed operands. The switch between domains is ' + 'transparent\n' + ' to the programmer.\n' + '\n' + ' "numbers.Real" ("float")\n' + ' These represent machine-level double precision floating ' + 'point\n' + ' numbers. You are at the mercy of the underlying machine\n' + ' architecture (and C or Java implementation) for the ' + 'accepted\n' + ' range and handling of overflow. Python does not support ' + 'single-\n' + ' precision floating point numbers; the savings in processor ' + 'and\n' + ' memory usage that are usually the reason for using these ' + 'are\n' + ' dwarfed by the overhead of using objects in Python, so ' + 'there is\n' + ' no reason to complicate the language with two kinds of ' + 'floating\n' + ' point numbers.\n' + '\n' + ' "numbers.Complex"\n' + ' These represent complex numbers as a pair of machine-level\n' + ' double precision floating point numbers. The same caveats ' + 'apply\n' + ' as for floating point numbers. The real and imaginary parts ' + 'of a\n' + ' complex number "z" can be retrieved through the read-only\n' + ' attributes "z.real" and "z.imag".\n' + '\n' + 'Sequences\n' + ' These represent finite ordered sets indexed by non-negative\n' + ' numbers. The built-in function "len()" returns the number of ' + 'items\n' + ' of a sequence. When the length of a sequence is *n*, the index ' + 'set\n' + ' contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence ' + '*a* is\n' + ' selected by "a[i]".\n' + '\n' + ' Sequences also support slicing: "a[i:j]" selects all items ' + 'with\n' + ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' + ' expression, a slice is a sequence of the same type. This ' + 'implies\n' + ' that the index set is renumbered so that it starts at 0.\n' + '\n' + ' Some sequences also support "extended slicing" with a third ' + '"step"\n' + ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' + 'where\n' + ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' + '\n' + ' Sequences are distinguished according to their mutability:\n' + '\n' + ' Immutable sequences\n' + ' An object of an immutable sequence type cannot change once ' + 'it is\n' + ' created. (If the object contains references to other ' + 'objects,\n' + ' these other objects may be mutable and may be changed; ' + 'however,\n' + ' the collection of objects directly referenced by an ' + 'immutable\n' + ' object cannot change.)\n' + '\n' + ' The following types are immutable sequences:\n' + '\n' + ' Strings\n' + ' The items of a string are characters. There is no ' + 'separate\n' + ' character type; a character is represented by a string ' + 'of one\n' + ' item. Characters represent (at least) 8-bit bytes. The\n' + ' built-in functions "chr()" and "ord()" convert between\n' + ' characters and nonnegative integers representing the ' + 'byte\n' + ' values. Bytes with the values 0-127 usually represent ' + 'the\n' + ' corresponding ASCII values, but the interpretation of ' + 'values\n' + ' is up to the program. The string data type is also used ' + 'to\n' + ' represent arrays of bytes, e.g., to hold data read from ' + 'a\n' + ' file.\n' + '\n' + ' (On systems whose native character set is not ASCII, ' + 'strings\n' + ' may use EBCDIC in their internal representation, ' + 'provided the\n' + ' functions "chr()" and "ord()" implement a mapping ' + 'between\n' + ' ASCII and EBCDIC, and string comparison preserves the ' + 'ASCII\n' + ' order. Or perhaps someone can propose a better rule?)\n' + '\n' + ' Unicode\n' + ' The items of a Unicode object are Unicode code units. ' + 'A\n' + ' Unicode code unit is represented by a Unicode object of ' + 'one\n' + ' item and can hold either a 16-bit or 32-bit value\n' + ' representing a Unicode ordinal (the maximum value for ' + 'the\n' + ' ordinal is given in "sys.maxunicode", and depends on ' + 'how\n' + ' Python is configured at compile time). Surrogate pairs ' + 'may\n' + ' be present in the Unicode object, and will be reported ' + 'as two\n' + ' separate items. The built-in functions "unichr()" and\n' + ' "ord()" convert between code units and nonnegative ' + 'integers\n' + ' representing the Unicode ordinals as defined in the ' + 'Unicode\n' + ' Standard 3.0. Conversion from and to other encodings ' + 'are\n' + ' possible through the Unicode method "encode()" and the ' + 'built-\n' + ' in function "unicode()".\n' + '\n' + ' Tuples\n' + ' The items of a tuple are arbitrary Python objects. ' + 'Tuples of\n' + ' two or more items are formed by comma-separated lists ' + 'of\n' + " expressions. A tuple of one item (a 'singleton') can " + 'be\n' + ' formed by affixing a comma to an expression (an ' + 'expression by\n' + ' itself does not create a tuple, since parentheses must ' + 'be\n' + ' usable for grouping of expressions). An empty tuple can ' + 'be\n' + ' formed by an empty pair of parentheses.\n' + '\n' + ' Mutable sequences\n' + ' Mutable sequences can be changed after they are created. ' + 'The\n' + ' subscription and slicing notations can be used as the ' + 'target of\n' + ' assignment and "del" (delete) statements.\n' + '\n' + ' There are currently two intrinsic mutable sequence types:\n' + '\n' + ' Lists\n' + ' The items of a list are arbitrary Python objects. Lists ' + 'are\n' + ' formed by placing a comma-separated list of expressions ' + 'in\n' + ' square brackets. (Note that there are no special cases ' + 'needed\n' + ' to form lists of length 0 or 1.)\n' + '\n' + ' Byte Arrays\n' + ' A bytearray object is a mutable array. They are created ' + 'by\n' + ' the built-in "bytearray()" constructor. Aside from ' + 'being\n' + ' mutable (and hence unhashable), byte arrays otherwise ' + 'provide\n' + ' the same interface and functionality as immutable bytes\n' + ' objects.\n' + '\n' + ' The extension module "array" provides an additional example ' + 'of a\n' + ' mutable sequence type.\n' + '\n' + 'Set types\n' + ' These represent unordered, finite sets of unique, immutable\n' + ' objects. As such, they cannot be indexed by any subscript. ' + 'However,\n' + ' they can be iterated over, and the built-in function "len()"\n' + ' returns the number of items in a set. Common uses for sets are ' + 'fast\n' + ' membership testing, removing duplicates from a sequence, and\n' + ' computing mathematical operations such as intersection, ' + 'union,\n' + ' difference, and symmetric difference.\n' + '\n' + ' For set elements, the same immutability rules apply as for\n' + ' dictionary keys. Note that numeric types obey the normal rules ' + 'for\n' + ' numeric comparison: if two numbers compare equal (e.g., "1" ' + 'and\n' + ' "1.0"), only one of them can be contained in a set.\n' + '\n' + ' There are currently two intrinsic set types:\n' + '\n' + ' Sets\n' + ' These represent a mutable set. They are created by the ' + 'built-in\n' + ' "set()" constructor and can be modified afterwards by ' + 'several\n' + ' methods, such as "add()".\n' + '\n' + ' Frozen sets\n' + ' These represent an immutable set. They are created by the\n' + ' built-in "frozenset()" constructor. As a frozenset is ' + 'immutable\n' + ' and *hashable*, it can be used again as an element of ' + 'another\n' + ' set, or as a dictionary key.\n' + '\n' + 'Mappings\n' + ' These represent finite sets of objects indexed by arbitrary ' + 'index\n' + ' sets. The subscript notation "a[k]" selects the item indexed ' + 'by "k"\n' + ' from the mapping "a"; this can be used in expressions and as ' + 'the\n' + ' target of assignments or "del" statements. The built-in ' + 'function\n' + ' "len()" returns the number of items in a mapping.\n' + '\n' + ' There is currently a single intrinsic mapping type:\n' + '\n' + ' Dictionaries\n' + ' These represent finite sets of objects indexed by nearly\n' + ' arbitrary values. The only types of values not acceptable ' + 'as\n' + ' keys are values containing lists or dictionaries or other\n' + ' mutable types that are compared by value rather than by ' + 'object\n' + ' identity, the reason being that the efficient ' + 'implementation of\n' + " dictionaries requires a key's hash value to remain " + 'constant.\n' + ' Numeric types used for keys obey the normal rules for ' + 'numeric\n' + ' comparison: if two numbers compare equal (e.g., "1" and ' + '"1.0")\n' + ' then they can be used interchangeably to index the same\n' + ' dictionary entry.\n' + '\n' + ' Dictionaries are mutable; they can be created by the ' + '"{...}"\n' + ' notation (see section Dictionary displays).\n' + '\n' + ' The extension modules "dbm", "gdbm", and "bsddb" provide\n' + ' additional examples of mapping types.\n' + '\n' + 'Callable types\n' + ' These are the types to which the function call operation (see\n' + ' section Calls) can be applied:\n' + '\n' + ' User-defined functions\n' + ' A user-defined function object is created by a function\n' + ' definition (see section Function definitions). It should ' + 'be\n' + ' called with an argument list containing the same number of ' + 'items\n' + " as the function's formal parameter list.\n" + '\n' + ' Special attributes:\n' + '\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | Attribute | Meaning ' + '| |\n' + ' ' + '+=========================+=================================+=============+\n' + ' | "__doc__" "func_doc" | The function\'s ' + 'documentation | Writable |\n' + ' | | string, or "None" if ' + '| |\n' + ' | | unavailable. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__name__" "func_name" | The function\'s ' + 'name. | Writable |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__module__" | The name of the module the ' + '| Writable |\n' + ' | | function was defined in, or ' + '| |\n' + ' | | "None" if unavailable. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__defaults__" | A tuple containing default ' + '| Writable |\n' + ' | "func_defaults" | argument values for those ' + '| |\n' + ' | | arguments that have defaults, ' + '| |\n' + ' | | or "None" if no arguments have ' + '| |\n' + ' | | a default value. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__code__" "func_code" | The code object representing ' + '| Writable |\n' + ' | | the compiled function body. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__globals__" | A reference to the dictionary ' + '| Read-only |\n' + ' | "func_globals" | that holds the ' + "function's | |\n" + ' | | global variables --- the global ' + '| |\n' + ' | | namespace of the module in ' + '| |\n' + ' | | which the function was defined. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__dict__" "func_dict" | The namespace supporting ' + '| Writable |\n' + ' | | arbitrary function attributes. ' + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + ' | "__closure__" | "None" or a tuple of cells that ' + '| Read-only |\n' + ' | "func_closure" | contain bindings for the ' + '| |\n' + " | | function's free variables. " + '| |\n' + ' ' + '+-------------------------+---------------------------------+-------------+\n' + '\n' + ' Most of the attributes labelled "Writable" check the type ' + 'of the\n' + ' assigned value.\n' + '\n' + ' Changed in version 2.4: "func_name" is now writable.\n' + '\n' + ' Changed in version 2.6: The double-underscore attributes\n' + ' "__closure__", "__code__", "__defaults__", and ' + '"__globals__"\n' + ' were introduced as aliases for the corresponding "func_*"\n' + ' attributes for forwards compatibility with Python 3.\n' + '\n' + ' Function objects also support getting and setting ' + 'arbitrary\n' + ' attributes, which can be used, for example, to attach ' + 'metadata\n' + ' to functions. Regular attribute dot-notation is used to ' + 'get and\n' + ' set such attributes. *Note that the current implementation ' + 'only\n' + ' supports function attributes on user-defined functions. ' + 'Function\n' + ' attributes on built-in functions may be supported in the\n' + ' future.*\n' + '\n' + " Additional information about a function's definition can " + 'be\n' + ' retrieved from its code object; see the description of ' + 'internal\n' + ' types below.\n' + '\n' + ' User-defined methods\n' + ' A user-defined method object combines a class, a class ' + 'instance\n' + ' (or "None") and any callable object (normally a ' + 'user-defined\n' + ' function).\n' + '\n' + ' Special read-only attributes: "im_self" is the class ' + 'instance\n' + ' object, "im_func" is the function object; "im_class" is ' + 'the\n' + ' class of "im_self" for bound methods or the class that ' + 'asked for\n' + ' the method for unbound methods; "__doc__" is the method\'s\n' + ' documentation (same as "im_func.__doc__"); "__name__" is ' + 'the\n' + ' method name (same as "im_func.__name__"); "__module__" is ' + 'the\n' + ' name of the module the method was defined in, or "None" if\n' + ' unavailable.\n' + '\n' + ' Changed in version 2.2: "im_self" used to refer to the ' + 'class\n' + ' that defined the method.\n' + '\n' + ' Changed in version 2.6: For Python 3 ' + 'forward-compatibility,\n' + ' "im_func" is also available as "__func__", and "im_self" ' + 'as\n' + ' "__self__".\n' + '\n' + ' Methods also support accessing (but not setting) the ' + 'arbitrary\n' + ' function attributes on the underlying function object.\n' + '\n' + ' User-defined method objects may be created when getting an\n' + ' attribute of a class (perhaps via an instance of that ' + 'class), if\n' + ' that attribute is a user-defined function object, an ' + 'unbound\n' + ' user-defined method object, or a class method object. When ' + 'the\n' + ' attribute is a user-defined method object, a new method ' + 'object\n' + ' is only created if the class from which it is being ' + 'retrieved is\n' + ' the same as, or a derived class of, the class stored in ' + 'the\n' + ' original method object; otherwise, the original method ' + 'object is\n' + ' used as it is.\n' + '\n' + ' When a user-defined method object is created by retrieving ' + 'a\n' + ' user-defined function object from a class, its "im_self"\n' + ' attribute is "None" and the method object is said to be ' + 'unbound.\n' + ' When one is created by retrieving a user-defined function ' + 'object\n' + ' from a class via one of its instances, its "im_self" ' + 'attribute\n' + ' is the instance, and the method object is said to be bound. ' + 'In\n' + ' either case, the new method\'s "im_class" attribute is the ' + 'class\n' + ' from which the retrieval takes place, and its "im_func"\n' + ' attribute is the original function object.\n' + '\n' + ' When a user-defined method object is created by retrieving\n' + ' another method object from a class or instance, the ' + 'behaviour is\n' + ' the same as for a function object, except that the ' + '"im_func"\n' + ' attribute of the new instance is not the original method ' + 'object\n' + ' but its "im_func" attribute.\n' + '\n' + ' When a user-defined method object is created by retrieving ' + 'a\n' + ' class method object from a class or instance, its ' + '"im_self"\n' + ' attribute is the class itself, and its "im_func" attribute ' + 'is\n' + ' the function object underlying the class method.\n' + '\n' + ' When an unbound user-defined method object is called, the\n' + ' underlying function ("im_func") is called, with the ' + 'restriction\n' + ' that the first argument must be an instance of the proper ' + 'class\n' + ' ("im_class") or of a derived class thereof.\n' + '\n' + ' When a bound user-defined method object is called, the\n' + ' underlying function ("im_func") is called, inserting the ' + 'class\n' + ' instance ("im_self") in front of the argument list. For\n' + ' instance, when "C" is a class which contains a definition ' + 'for a\n' + ' function "f()", and "x" is an instance of "C", calling ' + '"x.f(1)"\n' + ' is equivalent to calling "C.f(x, 1)".\n' + '\n' + ' When a user-defined method object is derived from a class ' + 'method\n' + ' object, the "class instance" stored in "im_self" will ' + 'actually\n' + ' be the class itself, so that calling either "x.f(1)" or ' + '"C.f(1)"\n' + ' is equivalent to calling "f(C,1)" where "f" is the ' + 'underlying\n' + ' function.\n' + '\n' + ' Note that the transformation from function object to ' + '(unbound or\n' + ' bound) method object happens each time the attribute is\n' + ' retrieved from the class or instance. In some cases, a ' + 'fruitful\n' + ' optimization is to assign the attribute to a local variable ' + 'and\n' + ' call that local variable. Also notice that this ' + 'transformation\n' + ' only happens for user-defined functions; other callable ' + 'objects\n' + ' (and all non-callable objects) are retrieved without\n' + ' transformation. It is also important to note that ' + 'user-defined\n' + ' functions which are attributes of a class instance are not\n' + ' converted to bound methods; this *only* happens when the\n' + ' function is an attribute of the class.\n' + '\n' + ' Generator functions\n' + ' A function or method which uses the "yield" statement (see\n' + ' section The yield statement) is called a *generator ' + 'function*.\n' + ' Such a function, when called, always returns an iterator ' + 'object\n' + ' which can be used to execute the body of the function: ' + 'calling\n' + ' the iterator\'s "next()" method will cause the function to\n' + ' execute until it provides a value using the "yield" ' + 'statement.\n' + ' When the function executes a "return" statement or falls ' + 'off the\n' + ' end, a "StopIteration" exception is raised and the iterator ' + 'will\n' + ' have reached the end of the set of values to be returned.\n' + '\n' + ' Built-in functions\n' + ' A built-in function object is a wrapper around a C ' + 'function.\n' + ' Examples of built-in functions are "len()" and ' + '"math.sin()"\n' + ' ("math" is a standard built-in module). The number and type ' + 'of\n' + ' the arguments are determined by the C function. Special ' + 'read-\n' + ' only attributes: "__doc__" is the function\'s ' + 'documentation\n' + ' string, or "None" if unavailable; "__name__" is the ' + "function's\n" + ' name; "__self__" is set to "None" (but see the next item);\n' + ' "__module__" is the name of the module the function was ' + 'defined\n' + ' in or "None" if unavailable.\n' + '\n' + ' Built-in methods\n' + ' This is really a different disguise of a built-in function, ' + 'this\n' + ' time containing an object passed to the C function as an\n' + ' implicit extra argument. An example of a built-in method ' + 'is\n' + ' "alist.append()", assuming *alist* is a list object. In ' + 'this\n' + ' case, the special read-only attribute "__self__" is set to ' + 'the\n' + ' object denoted by *alist*.\n' + '\n' + ' Class Types\n' + ' Class types, or "new-style classes," are callable. These\n' + ' objects normally act as factories for new instances of\n' + ' themselves, but variations are possible for class types ' + 'that\n' + ' override "__new__()". The arguments of the call are passed ' + 'to\n' + ' "__new__()" and, in the typical case, to "__init__()" to\n' + ' initialize the new instance.\n' + '\n' + ' Classic Classes\n' + ' Class objects are described below. When a class object is\n' + ' called, a new class instance (also described below) is ' + 'created\n' + " and returned. This implies a call to the class's " + '"__init__()"\n' + ' method if it has one. Any arguments are passed on to the\n' + ' "__init__()" method. If there is no "__init__()" method, ' + 'the\n' + ' class must be called without arguments.\n' + '\n' + ' Class instances\n' + ' Class instances are described below. Class instances are\n' + ' callable only when the class has a "__call__()" method;\n' + ' "x(arguments)" is a shorthand for "x.__call__(arguments)".\n' + '\n' + 'Modules\n' + ' Modules are imported by the "import" statement (see section ' + 'The\n' + ' import statement). A module object has a namespace implemented ' + 'by a\n' + ' dictionary object (this is the dictionary referenced by the\n' + ' func_globals attribute of functions defined in the module).\n' + ' Attribute references are translated to lookups in this ' + 'dictionary,\n' + ' e.g., "m.x" is equivalent to "m.__dict__["x"]". A module ' + 'object\n' + ' does not contain the code object used to initialize the ' + 'module\n' + " (since it isn't needed once the initialization is done).\n" + '\n' + " Attribute assignment updates the module's namespace " + 'dictionary,\n' + ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' + '\n' + ' Special read-only attribute: "__dict__" is the module\'s ' + 'namespace\n' + ' as a dictionary object.\n' + '\n' + ' **CPython implementation detail:** Because of the way CPython\n' + ' clears module dictionaries, the module dictionary will be ' + 'cleared\n' + ' when the module falls out of scope even if the dictionary ' + 'still has\n' + ' live references. To avoid this, copy the dictionary or keep ' + 'the\n' + ' module around while using its dictionary directly.\n' + '\n' + ' Predefined (writable) attributes: "__name__" is the module\'s ' + 'name;\n' + ' "__doc__" is the module\'s documentation string, or "None" if\n' + ' unavailable; "__file__" is the pathname of the file from which ' + 'the\n' + ' module was loaded, if it was loaded from a file. The ' + '"__file__"\n' + ' attribute is not present for C modules that are statically ' + 'linked\n' + ' into the interpreter; for extension modules loaded dynamically ' + 'from\n' + ' a shared library, it is the pathname of the shared library ' + 'file.\n' + '\n' + 'Classes\n' + ' Both class types (new-style classes) and class objects (old-\n' + ' style/classic classes) are typically created by class ' + 'definitions\n' + ' (see section Class definitions). A class has a namespace\n' + ' implemented by a dictionary object. Class attribute references ' + 'are\n' + ' translated to lookups in this dictionary, e.g., "C.x" is ' + 'translated\n' + ' to "C.__dict__["x"]" (although for new-style classes in ' + 'particular\n' + ' there are a number of hooks which allow for other means of ' + 'locating\n' + ' attributes). When the attribute name is not found there, the\n' + ' attribute search continues in the base classes. For ' + 'old-style\n' + ' classes, the search is depth-first, left-to-right in the order ' + 'of\n' + ' occurrence in the base class list. New-style classes use the ' + 'more\n' + ' complex C3 method resolution order which behaves correctly ' + 'even in\n' + " the presence of 'diamond' inheritance structures where there " + 'are\n' + ' multiple inheritance paths leading back to a common ancestor.\n' + ' Additional details on the C3 MRO used by new-style classes can ' + 'be\n' + ' found in the documentation accompanying the 2.3 release at\n' + ' https://www.python.org/download/releases/2.3/mro/.\n' + '\n' + ' When a class attribute reference (for class "C", say) would ' + 'yield a\n' + ' user-defined function object or an unbound user-defined ' + 'method\n' + ' object whose associated class is either "C" or one of its ' + 'base\n' + ' classes, it is transformed into an unbound user-defined ' + 'method\n' + ' object whose "im_class" attribute is "C". When it would yield ' + 'a\n' + ' class method object, it is transformed into a bound ' + 'user-defined\n' + ' method object whose "im_self" attribute is "C". When it ' + 'would\n' + ' yield a static method object, it is transformed into the ' + 'object\n' + ' wrapped by the static method object. See section Implementing\n' + ' Descriptors for another way in which attributes retrieved from ' + 'a\n' + ' class may differ from those actually contained in its ' + '"__dict__"\n' + ' (note that only new-style classes support descriptors).\n' + '\n' + " Class attribute assignments update the class's dictionary, " + 'never\n' + ' the dictionary of a base class.\n' + '\n' + ' A class object can be called (see above) to yield a class ' + 'instance\n' + ' (see below).\n' + '\n' + ' Special attributes: "__name__" is the class name; "__module__" ' + 'is\n' + ' the module name in which the class was defined; "__dict__" is ' + 'the\n' + ' dictionary containing the class\'s namespace; "__bases__" is a ' + 'tuple\n' + ' (possibly empty or a singleton) containing the base classes, ' + 'in the\n' + ' order of their occurrence in the base class list; "__doc__" is ' + 'the\n' + " class's documentation string, or None if undefined.\n" + '\n' + 'Class instances\n' + ' A class instance is created by calling a class object (see ' + 'above).\n' + ' A class instance has a namespace implemented as a dictionary ' + 'which\n' + ' is the first place in which attribute references are ' + 'searched.\n' + " When an attribute is not found there, and the instance's class " + 'has\n' + ' an attribute by that name, the search continues with the ' + 'class\n' + ' attributes. If a class attribute is found that is a ' + 'user-defined\n' + ' function object or an unbound user-defined method object ' + 'whose\n' + ' associated class is the class (call it "C") of the instance ' + 'for\n' + ' which the attribute reference was initiated or one of its ' + 'bases, it\n' + ' is transformed into a bound user-defined method object whose\n' + ' "im_class" attribute is "C" and whose "im_self" attribute is ' + 'the\n' + ' instance. Static method and class method objects are also\n' + ' transformed, as if they had been retrieved from class "C"; ' + 'see\n' + ' above under "Classes". See section Implementing Descriptors ' + 'for\n' + ' another way in which attributes of a class retrieved via its\n' + ' instances may differ from the objects actually stored in the\n' + ' class\'s "__dict__". If no class attribute is found, and the\n' + ' object\'s class has a "__getattr__()" method, that is called ' + 'to\n' + ' satisfy the lookup.\n' + '\n' + " Attribute assignments and deletions update the instance's\n" + " dictionary, never a class's dictionary. If the class has a\n" + ' "__setattr__()" or "__delattr__()" method, this is called ' + 'instead\n' + ' of updating the instance dictionary directly.\n' + '\n' + ' Class instances can pretend to be numbers, sequences, or ' + 'mappings\n' + ' if they have methods with certain special names. See section\n' + ' Special method names.\n' + '\n' + ' Special attributes: "__dict__" is the attribute dictionary;\n' + ' "__class__" is the instance\'s class.\n' + '\n' + 'Files\n' + ' A file object represents an open file. File objects are ' + 'created by\n' + ' the "open()" built-in function, and also by "os.popen()",\n' + ' "os.fdopen()", and the "makefile()" method of socket objects ' + '(and\n' + ' perhaps by other functions or methods provided by extension\n' + ' modules). The objects "sys.stdin", "sys.stdout" and ' + '"sys.stderr"\n' + ' are initialized to file objects corresponding to the ' + "interpreter's\n" + ' standard input, output and error streams. See File Objects ' + 'for\n' + ' complete documentation of file objects.\n' + '\n' + 'Internal types\n' + ' A few types used internally by the interpreter are exposed to ' + 'the\n' + ' user. Their definitions may change with future versions of ' + 'the\n' + ' interpreter, but they are mentioned here for completeness.\n' + '\n' + ' Code objects\n' + ' Code objects represent *byte-compiled* executable Python ' + 'code,\n' + ' or *bytecode*. The difference between a code object and a\n' + ' function object is that the function object contains an ' + 'explicit\n' + " reference to the function's globals (the module in which it " + 'was\n' + ' defined), while a code object contains no context; also ' + 'the\n' + ' default argument values are stored in the function object, ' + 'not\n' + ' in the code object (because they represent values ' + 'calculated at\n' + ' run-time). Unlike function objects, code objects are ' + 'immutable\n' + ' and contain no references (directly or indirectly) to ' + 'mutable\n' + ' objects.\n' + '\n' + ' Special read-only attributes: "co_name" gives the function ' + 'name;\n' + ' "co_argcount" is the number of positional arguments ' + '(including\n' + ' arguments with default values); "co_nlocals" is the number ' + 'of\n' + ' local variables used by the function (including ' + 'arguments);\n' + ' "co_varnames" is a tuple containing the names of the local\n' + ' variables (starting with the argument names); "co_cellvars" ' + 'is a\n' + ' tuple containing the names of local variables that are\n' + ' referenced by nested functions; "co_freevars" is a tuple\n' + ' containing the names of free variables; "co_code" is a ' + 'string\n' + ' representing the sequence of bytecode instructions; ' + '"co_consts"\n' + ' is a tuple containing the literals used by the bytecode;\n' + ' "co_names" is a tuple containing the names used by the ' + 'bytecode;\n' + ' "co_filename" is the filename from which the code was ' + 'compiled;\n' + ' "co_firstlineno" is the first line number of the function;\n' + ' "co_lnotab" is a string encoding the mapping from bytecode\n' + ' offsets to line numbers (for details see the source code of ' + 'the\n' + ' interpreter); "co_stacksize" is the required stack size\n' + ' (including local variables); "co_flags" is an integer ' + 'encoding a\n' + ' number of flags for the interpreter.\n' + '\n' + ' The following flag bits are defined for "co_flags": bit ' + '"0x04"\n' + ' is set if the function uses the "*arguments" syntax to ' + 'accept an\n' + ' arbitrary number of positional arguments; bit "0x08" is set ' + 'if\n' + ' the function uses the "**keywords" syntax to accept ' + 'arbitrary\n' + ' keyword arguments; bit "0x20" is set if the function is a\n' + ' generator.\n' + '\n' + ' Future feature declarations ("from __future__ import ' + 'division")\n' + ' also use bits in "co_flags" to indicate whether a code ' + 'object\n' + ' was compiled with a particular feature enabled: bit ' + '"0x2000" is\n' + ' set if the function was compiled with future division ' + 'enabled;\n' + ' bits "0x10" and "0x1000" were used in earlier versions of\n' + ' Python.\n' + '\n' + ' Other bits in "co_flags" are reserved for internal use.\n' + '\n' + ' If a code object represents a function, the first item in\n' + ' "co_consts" is the documentation string of the function, ' + 'or\n' + ' "None" if undefined.\n' + '\n' + ' Frame objects\n' + ' Frame objects represent execution frames. They may occur ' + 'in\n' + ' traceback objects (see below).\n' + '\n' + ' Special read-only attributes: "f_back" is to the previous ' + 'stack\n' + ' frame (towards the caller), or "None" if this is the ' + 'bottom\n' + ' stack frame; "f_code" is the code object being executed in ' + 'this\n' + ' frame; "f_locals" is the dictionary used to look up local\n' + ' variables; "f_globals" is used for global variables;\n' + ' "f_builtins" is used for built-in (intrinsic) names;\n' + ' "f_restricted" is a flag indicating whether the function ' + 'is\n' + ' executing in restricted execution mode; "f_lasti" gives ' + 'the\n' + ' precise instruction (this is an index into the bytecode ' + 'string\n' + ' of the code object).\n' + '\n' + ' Special writable attributes: "f_trace", if not "None", is ' + 'a\n' + ' function called at the start of each source code line (this ' + 'is\n' + ' used by the debugger); "f_exc_type", "f_exc_value",\n' + ' "f_exc_traceback" represent the last exception raised in ' + 'the\n' + ' parent frame provided another exception was ever raised in ' + 'the\n' + ' current frame (in all other cases they are None); ' + '"f_lineno" is\n' + ' the current line number of the frame --- writing to this ' + 'from\n' + ' within a trace function jumps to the given line (only for ' + 'the\n' + ' bottom-most frame). A debugger can implement a Jump ' + 'command\n' + ' (aka Set Next Statement) by writing to f_lineno.\n' + '\n' + ' Traceback objects\n' + ' Traceback objects represent a stack trace of an exception. ' + 'A\n' + ' traceback object is created when an exception occurs. When ' + 'the\n' + ' search for an exception handler unwinds the execution ' + 'stack, at\n' + ' each unwound level a traceback object is inserted in front ' + 'of\n' + ' the current traceback. When an exception handler is ' + 'entered,\n' + ' the stack trace is made available to the program. (See ' + 'section\n' + ' The try statement.) It is accessible as ' + '"sys.exc_traceback", and\n' + ' also as the third item of the tuple returned by\n' + ' "sys.exc_info()". The latter is the preferred interface, ' + 'since\n' + ' it works correctly when the program is using multiple ' + 'threads.\n' + ' When the program contains no suitable handler, the stack ' + 'trace\n' + ' is written (nicely formatted) to the standard error stream; ' + 'if\n' + ' the interpreter is interactive, it is also made available ' + 'to the\n' + ' user as "sys.last_traceback".\n' + '\n' + ' Special read-only attributes: "tb_next" is the next level ' + 'in the\n' + ' stack trace (towards the frame where the exception ' + 'occurred), or\n' + ' "None" if there is no next level; "tb_frame" points to the\n' + ' execution frame of the current level; "tb_lineno" gives the ' + 'line\n' + ' number where the exception occurred; "tb_lasti" indicates ' + 'the\n' + ' precise instruction. The line number and last instruction ' + 'in\n' + ' the traceback may differ from the line number of its frame\n' + ' object if the exception occurred in a "try" statement with ' + 'no\n' + ' matching except clause or with a finally clause.\n' + '\n' + ' Slice objects\n' + ' Slice objects are used to represent slices when *extended ' + 'slice\n' + ' syntax* is used. This is a slice using two colons, or ' + 'multiple\n' + ' slices or ellipses separated by commas, e.g., ' + '"a[i:j:step]",\n' + ' "a[i:j, k:l]", or "a[..., i:j]". They are also created by ' + 'the\n' + ' built-in "slice()" function.\n' + '\n' + ' Special read-only attributes: "start" is the lower bound; ' + '"stop"\n' + ' is the upper bound; "step" is the step value; each is ' + '"None" if\n' + ' omitted. These attributes can have any type.\n' + '\n' + ' Slice objects support one method:\n' + '\n' + ' slice.indices(self, length)\n' + '\n' + ' This method takes a single integer argument *length* ' + 'and\n' + ' computes information about the extended slice that the ' + 'slice\n' + ' object would describe if applied to a sequence of ' + '*length*\n' + ' items. It returns a tuple of three integers; ' + 'respectively\n' + ' these are the *start* and *stop* indices and the *step* ' + 'or\n' + ' stride length of the slice. Missing or out-of-bounds ' + 'indices\n' + ' are handled in a manner consistent with regular slices.\n' + '\n' + ' New in version 2.3.\n' + '\n' + ' Static method objects\n' + ' Static method objects provide a way of defeating the\n' + ' transformation of function objects to method objects ' + 'described\n' + ' above. A static method object is a wrapper around any ' + 'other\n' + ' object, usually a user-defined method object. When a ' + 'static\n' + ' method object is retrieved from a class or a class ' + 'instance, the\n' + ' object actually returned is the wrapped object, which is ' + 'not\n' + ' subject to any further transformation. Static method ' + 'objects are\n' + ' not themselves callable, although the objects they wrap ' + 'usually\n' + ' are. Static method objects are created by the built-in\n' + ' "staticmethod()" constructor.\n' + '\n' + ' Class method objects\n' + ' A class method object, like a static method object, is a ' + 'wrapper\n' + ' around another object that alters the way in which that ' + 'object\n' + ' is retrieved from classes and class instances. The ' + 'behaviour of\n' + ' class method objects upon such retrieval is described ' + 'above,\n' + ' under "User-defined methods". Class method objects are ' + 'created\n' + ' by the built-in "classmethod()" constructor.\n', + 'typesfunctions': '\n' + 'Functions\n' + '*********\n' + '\n' + 'Function objects are created by function definitions. ' + 'The only\n' + 'operation on a function object is to call it: ' + '"func(argument-list)".\n' + '\n' + 'There are really two flavors of function objects: ' + 'built-in functions\n' + 'and user-defined functions. Both support the same ' + 'operation (to call\n' + 'the function), but the implementation is different, ' + 'hence the\n' + 'different object types.\n' + '\n' + 'See Function definitions for more information.\n', + 'typesmapping': '\n' + 'Mapping Types --- "dict"\n' + '************************\n' + '\n' + 'A *mapping* object maps *hashable* values to arbitrary ' + 'objects.\n' + 'Mappings are mutable objects. There is currently only one ' + 'standard\n' + 'mapping type, the *dictionary*. (For other containers see ' + 'the built\n' + 'in "list", "set", and "tuple" classes, and the ' + '"collections" module.)\n' + '\n' + "A dictionary's keys are *almost* arbitrary values. Values " + 'that are\n' + 'not *hashable*, that is, values containing lists, ' + 'dictionaries or\n' + 'other mutable types (that are compared by value rather ' + 'than by object\n' + 'identity) may not be used as keys. Numeric types used for ' + 'keys obey\n' + 'the normal rules for numeric comparison: if two numbers ' + 'compare equal\n' + '(such as "1" and "1.0") then they can be used ' + 'interchangeably to index\n' + 'the same dictionary entry. (Note however, that since ' + 'computers store\n' + 'floating-point numbers as approximations it is usually ' + 'unwise to use\n' + 'them as dictionary keys.)\n' + '\n' + 'Dictionaries can be created by placing a comma-separated ' + 'list of "key:\n' + 'value" pairs within braces, for example: "{\'jack\': 4098, ' + "'sjoerd':\n" + '4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the ' + '"dict"\n' + 'constructor.\n' + '\n' + 'class class dict(**kwarg)\n' + 'class class dict(mapping, **kwarg)\n' + 'class class dict(iterable, **kwarg)\n' + '\n' + ' Return a new dictionary initialized from an optional ' + 'positional\n' + ' argument and a possibly empty set of keyword ' + 'arguments.\n' + '\n' + ' If no positional argument is given, an empty dictionary ' + 'is created.\n' + ' If a positional argument is given and it is a mapping ' + 'object, a\n' + ' dictionary is created with the same key-value pairs as ' + 'the mapping\n' + ' object. Otherwise, the positional argument must be an ' + '*iterable*\n' + ' object. Each item in the iterable must itself be an ' + 'iterable with\n' + ' exactly two objects. The first object of each item ' + 'becomes a key\n' + ' in the new dictionary, and the second object the ' + 'corresponding\n' + ' value. If a key occurs more than once, the last value ' + 'for that key\n' + ' becomes the corresponding value in the new dictionary.\n' + '\n' + ' If keyword arguments are given, the keyword arguments ' + 'and their\n' + ' values are added to the dictionary created from the ' + 'positional\n' + ' argument. If a key being added is already present, the ' + 'value from\n' + ' the keyword argument replaces the value from the ' + 'positional\n' + ' argument.\n' + '\n' + ' To illustrate, the following examples all return a ' + 'dictionary equal\n' + ' to "{"one": 1, "two": 2, "three": 3}":\n' + '\n' + ' >>> a = dict(one=1, two=2, three=3)\n' + " >>> b = {'one': 1, 'two': 2, 'three': 3}\n" + " >>> c = dict(zip(['one', 'two', 'three'], [1, 2, " + '3]))\n' + " >>> d = dict([('two', 2), ('one', 1), ('three', " + '3)])\n' + " >>> e = dict({'three': 3, 'one': 1, 'two': 2})\n" + ' >>> a == b == c == d == e\n' + ' True\n' + '\n' + ' Providing keyword arguments as in the first example ' + 'only works for\n' + ' keys that are valid Python identifiers. Otherwise, any ' + 'valid keys\n' + ' can be used.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' Changed in version 2.3: Support for building a ' + 'dictionary from\n' + ' keyword arguments added.\n' + '\n' + ' These are the operations that dictionaries support (and ' + 'therefore,\n' + ' custom mapping types should support too):\n' + '\n' + ' len(d)\n' + '\n' + ' Return the number of items in the dictionary *d*.\n' + '\n' + ' d[key]\n' + '\n' + ' Return the item of *d* with key *key*. Raises a ' + '"KeyError" if\n' + ' *key* is not in the map.\n' + '\n' + ' If a subclass of dict defines a method ' + '"__missing__()" and *key*\n' + ' is not present, the "d[key]" operation calls that ' + 'method with\n' + ' the key *key* as argument. The "d[key]" operation ' + 'then returns\n' + ' or raises whatever is returned or raised by the\n' + ' "__missing__(key)" call. No other operations or ' + 'methods invoke\n' + ' "__missing__()". If "__missing__()" is not defined, ' + '"KeyError"\n' + ' is raised. "__missing__()" must be a method; it ' + 'cannot be an\n' + ' instance variable:\n' + '\n' + ' >>> class Counter(dict):\n' + ' ... def __missing__(self, key):\n' + ' ... return 0\n' + ' >>> c = Counter()\n' + " >>> c['red']\n" + ' 0\n' + " >>> c['red'] += 1\n" + " >>> c['red']\n" + ' 1\n' + '\n' + ' The example above shows part of the implementation ' + 'of\n' + ' "collections.Counter". A different "__missing__" ' + 'method is used\n' + ' by "collections.defaultdict".\n' + '\n' + ' New in version 2.5: Recognition of __missing__ ' + 'methods of dict\n' + ' subclasses.\n' + '\n' + ' d[key] = value\n' + '\n' + ' Set "d[key]" to *value*.\n' + '\n' + ' del d[key]\n' + '\n' + ' Remove "d[key]" from *d*. Raises a "KeyError" if ' + '*key* is not\n' + ' in the map.\n' + '\n' + ' key in d\n' + '\n' + ' Return "True" if *d* has a key *key*, else "False".\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' key not in d\n' + '\n' + ' Equivalent to "not key in d".\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' iter(d)\n' + '\n' + ' Return an iterator over the keys of the dictionary. ' + 'This is a\n' + ' shortcut for "iterkeys()".\n' + '\n' + ' clear()\n' + '\n' + ' Remove all items from the dictionary.\n' + '\n' + ' copy()\n' + '\n' + ' Return a shallow copy of the dictionary.\n' + '\n' + ' fromkeys(seq[, value])\n' + '\n' + ' Create a new dictionary with keys from *seq* and ' + 'values set to\n' + ' *value*.\n' + '\n' + ' "fromkeys()" is a class method that returns a new ' + 'dictionary.\n' + ' *value* defaults to "None".\n' + '\n' + ' New in version 2.3.\n' + '\n' + ' get(key[, default])\n' + '\n' + ' Return the value for *key* if *key* is in the ' + 'dictionary, else\n' + ' *default*. If *default* is not given, it defaults to ' + '"None", so\n' + ' that this method never raises a "KeyError".\n' + '\n' + ' has_key(key)\n' + '\n' + ' Test for the presence of *key* in the dictionary. ' + '"has_key()"\n' + ' is deprecated in favor of "key in d".\n' + '\n' + ' items()\n' + '\n' + ' Return a copy of the dictionary\'s list of "(key, ' + 'value)" pairs.\n' + '\n' + ' **CPython implementation detail:** Keys and values ' + 'are listed in\n' + ' an arbitrary order which is non-random, varies ' + 'across Python\n' + " implementations, and depends on the dictionary's " + 'history of\n' + ' insertions and deletions.\n' + '\n' + ' If "items()", "keys()", "values()", "iteritems()", ' + '"iterkeys()",\n' + ' and "itervalues()" are called with no intervening ' + 'modifications\n' + ' to the dictionary, the lists will directly ' + 'correspond. This\n' + ' allows the creation of "(value, key)" pairs using ' + '"zip()":\n' + ' "pairs = zip(d.values(), d.keys())". The same ' + 'relationship\n' + ' holds for the "iterkeys()" and "itervalues()" ' + 'methods: "pairs =\n' + ' zip(d.itervalues(), d.iterkeys())" provides the same ' + 'value for\n' + ' "pairs". Another way to create the same list is ' + '"pairs = [(v, k)\n' + ' for (k, v) in d.iteritems()]".\n' + '\n' + ' iteritems()\n' + '\n' + ' Return an iterator over the dictionary\'s "(key, ' + 'value)" pairs.\n' + ' See the note for "dict.items()".\n' + '\n' + ' Using "iteritems()" while adding or deleting entries ' + 'in the\n' + ' dictionary may raise a "RuntimeError" or fail to ' + 'iterate over\n' + ' all entries.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' iterkeys()\n' + '\n' + " Return an iterator over the dictionary's keys. See " + 'the note for\n' + ' "dict.items()".\n' + '\n' + ' Using "iterkeys()" while adding or deleting entries ' + 'in the\n' + ' dictionary may raise a "RuntimeError" or fail to ' + 'iterate over\n' + ' all entries.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' itervalues()\n' + '\n' + " Return an iterator over the dictionary's values. " + 'See the note\n' + ' for "dict.items()".\n' + '\n' + ' Using "itervalues()" while adding or deleting ' + 'entries in the\n' + ' dictionary may raise a "RuntimeError" or fail to ' + 'iterate over\n' + ' all entries.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' keys()\n' + '\n' + " Return a copy of the dictionary's list of keys. See " + 'the note\n' + ' for "dict.items()".\n' + '\n' + ' pop(key[, default])\n' + '\n' + ' If *key* is in the dictionary, remove it and return ' + 'its value,\n' + ' else return *default*. If *default* is not given ' + 'and *key* is\n' + ' not in the dictionary, a "KeyError" is raised.\n' + '\n' + ' New in version 2.3.\n' + '\n' + ' popitem()\n' + '\n' + ' Remove and return an arbitrary "(key, value)" pair ' + 'from the\n' + ' dictionary.\n' + '\n' + ' "popitem()" is useful to destructively iterate over ' + 'a\n' + ' dictionary, as often used in set algorithms. If the ' + 'dictionary\n' + ' is empty, calling "popitem()" raises a "KeyError".\n' + '\n' + ' setdefault(key[, default])\n' + '\n' + ' If *key* is in the dictionary, return its value. If ' + 'not, insert\n' + ' *key* with a value of *default* and return ' + '*default*. *default*\n' + ' defaults to "None".\n' + '\n' + ' update([other])\n' + '\n' + ' Update the dictionary with the key/value pairs from ' + '*other*,\n' + ' overwriting existing keys. Return "None".\n' + '\n' + ' "update()" accepts either another dictionary object ' + 'or an\n' + ' iterable of key/value pairs (as tuples or other ' + 'iterables of\n' + ' length two). If keyword arguments are specified, ' + 'the dictionary\n' + ' is then updated with those key/value pairs: ' + '"d.update(red=1,\n' + ' blue=2)".\n' + '\n' + ' Changed in version 2.4: Allowed the argument to be ' + 'an iterable\n' + ' of key/value pairs and allowed keyword arguments.\n' + '\n' + ' values()\n' + '\n' + " Return a copy of the dictionary's list of values. " + 'See the note\n' + ' for "dict.items()".\n' + '\n' + ' viewitems()\n' + '\n' + ' Return a new view of the dictionary\'s items ("(key, ' + 'value)"\n' + ' pairs). See below for documentation of view ' + 'objects.\n' + '\n' + ' New in version 2.7.\n' + '\n' + ' viewkeys()\n' + '\n' + " Return a new view of the dictionary's keys. See " + 'below for\n' + ' documentation of view objects.\n' + '\n' + ' New in version 2.7.\n' + '\n' + ' viewvalues()\n' + '\n' + " Return a new view of the dictionary's values. See " + 'below for\n' + ' documentation of view objects.\n' + '\n' + ' New in version 2.7.\n' + '\n' + ' Dictionaries compare equal if and only if they have the ' + 'same "(key,\n' + ' value)" pairs.\n' + '\n' + '\n' + 'Dictionary view objects\n' + '=======================\n' + '\n' + 'The objects returned by "dict.viewkeys()", ' + '"dict.viewvalues()" and\n' + '"dict.viewitems()" are *view objects*. They provide a ' + 'dynamic view on\n' + "the dictionary's entries, which means that when the " + 'dictionary\n' + 'changes, the view reflects these changes.\n' + '\n' + 'Dictionary views can be iterated over to yield their ' + 'respective data,\n' + 'and support membership tests:\n' + '\n' + 'len(dictview)\n' + '\n' + ' Return the number of entries in the dictionary.\n' + '\n' + 'iter(dictview)\n' + '\n' + ' Return an iterator over the keys, values or items ' + '(represented as\n' + ' tuples of "(key, value)") in the dictionary.\n' + '\n' + ' Keys and values are iterated over in an arbitrary order ' + 'which is\n' + ' non-random, varies across Python implementations, and ' + 'depends on\n' + " the dictionary's history of insertions and deletions. " + 'If keys,\n' + ' values and items views are iterated over with no ' + 'intervening\n' + ' modifications to the dictionary, the order of items ' + 'will directly\n' + ' correspond. This allows the creation of "(value, key)" ' + 'pairs using\n' + ' "zip()": "pairs = zip(d.values(), d.keys())". Another ' + 'way to\n' + ' create the same list is "pairs = [(v, k) for (k, v) in ' + 'd.items()]".\n' + '\n' + ' Iterating views while adding or deleting entries in the ' + 'dictionary\n' + ' may raise a "RuntimeError" or fail to iterate over all ' + 'entries.\n' + '\n' + 'x in dictview\n' + '\n' + ' Return "True" if *x* is in the underlying dictionary\'s ' + 'keys, values\n' + ' or items (in the latter case, *x* should be a "(key, ' + 'value)"\n' + ' tuple).\n' + '\n' + 'Keys views are set-like since their entries are unique and ' + 'hashable.\n' + 'If all values are hashable, so that (key, value) pairs are ' + 'unique and\n' + 'hashable, then the items view is also set-like. (Values ' + 'views are not\n' + 'treated as set-like since the entries are generally not ' + 'unique.) Then\n' + 'these set operations are available ("other" refers either ' + 'to another\n' + 'view or a set):\n' + '\n' + 'dictview & other\n' + '\n' + ' Return the intersection of the dictview and the other ' + 'object as a\n' + ' new set.\n' + '\n' + 'dictview | other\n' + '\n' + ' Return the union of the dictview and the other object ' + 'as a new set.\n' + '\n' + 'dictview - other\n' + '\n' + ' Return the difference between the dictview and the ' + 'other object\n' + " (all elements in *dictview* that aren't in *other*) as " + 'a new set.\n' + '\n' + 'dictview ^ other\n' + '\n' + ' Return the symmetric difference (all elements either in ' + '*dictview*\n' + ' or *other*, but not in both) of the dictview and the ' + 'other object\n' + ' as a new set.\n' + '\n' + 'An example of dictionary view usage:\n' + '\n' + " >>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, " + "'spam': 500}\n" + ' >>> keys = dishes.viewkeys()\n' + ' >>> values = dishes.viewvalues()\n' + '\n' + ' >>> # iteration\n' + ' >>> n = 0\n' + ' >>> for val in values:\n' + ' ... n += val\n' + ' >>> print(n)\n' + ' 504\n' + '\n' + ' >>> # keys and values are iterated over in the same ' + 'order\n' + ' >>> list(keys)\n' + " ['eggs', 'bacon', 'sausage', 'spam']\n" + ' >>> list(values)\n' + ' [2, 1, 1, 500]\n' + '\n' + ' >>> # view objects are dynamic and reflect dict ' + 'changes\n' + " >>> del dishes['eggs']\n" + " >>> del dishes['sausage']\n" + ' >>> list(keys)\n' + " ['spam', 'bacon']\n" + '\n' + ' >>> # set operations\n' + " >>> keys & {'eggs', 'bacon', 'salad'}\n" + " {'bacon'}\n", + 'typesmethods': '\n' + 'Methods\n' + '*******\n' + '\n' + 'Methods are functions that are called using the attribute ' + 'notation.\n' + 'There are two flavors: built-in methods (such as ' + '"append()" on lists)\n' + 'and class instance methods. Built-in methods are ' + 'described with the\n' + 'types that support them.\n' + '\n' + 'The implementation adds two special read-only attributes ' + 'to class\n' + 'instance methods: "m.im_self" is the object on which the ' + 'method\n' + 'operates, and "m.im_func" is the function implementing the ' + 'method.\n' + 'Calling "m(arg-1, arg-2, ..., arg-n)" is completely ' + 'equivalent to\n' + 'calling "m.im_func(m.im_self, arg-1, arg-2, ..., arg-n)".\n' + '\n' + 'Class instance methods are either *bound* or *unbound*, ' + 'referring to\n' + 'whether the method was accessed through an instance or a ' + 'class,\n' + 'respectively. When a method is unbound, its "im_self" ' + 'attribute will\n' + 'be "None" and if called, an explicit "self" object must be ' + 'passed as\n' + 'the first argument. In this case, "self" must be an ' + 'instance of the\n' + "unbound method's class (or a subclass of that class), " + 'otherwise a\n' + '"TypeError" is raised.\n' + '\n' + 'Like function objects, methods objects support getting ' + 'arbitrary\n' + 'attributes. However, since method attributes are actually ' + 'stored on\n' + 'the underlying function object ("meth.im_func"), setting ' + 'method\n' + 'attributes on either bound or unbound methods is ' + 'disallowed.\n' + 'Attempting to set an attribute on a method results in an\n' + '"AttributeError" being raised. In order to set a method ' + 'attribute,\n' + 'you need to explicitly set it on the underlying function ' + 'object:\n' + '\n' + ' >>> class C:\n' + ' ... def method(self):\n' + ' ... pass\n' + ' ...\n' + ' >>> c = C()\n' + " >>> c.method.whoami = 'my name is method' # can't set " + 'on the method\n' + ' Traceback (most recent call last):\n' + ' File "", line 1, in \n' + " AttributeError: 'instancemethod' object has no " + "attribute 'whoami'\n" + " >>> c.method.im_func.whoami = 'my name is method'\n" + ' >>> c.method.whoami\n' + " 'my name is method'\n" + '\n' + 'See The standard type hierarchy for more information.\n', + 'typesmodules': '\n' + 'Modules\n' + '*******\n' + '\n' + 'The only special operation on a module is attribute ' + 'access: "m.name",\n' + 'where *m* is a module and *name* accesses a name defined ' + "in *m*'s\n" + 'symbol table. Module attributes can be assigned to. (Note ' + 'that the\n' + '"import" statement is not, strictly speaking, an operation ' + 'on a module\n' + 'object; "import foo" does not require a module object ' + 'named *foo* to\n' + 'exist, rather it requires an (external) *definition* for a ' + 'module\n' + 'named *foo* somewhere.)\n' + '\n' + 'A special attribute of every module is "__dict__". This is ' + 'the\n' + "dictionary containing the module's symbol table. Modifying " + 'this\n' + "dictionary will actually change the module's symbol table, " + 'but direct\n' + 'assignment to the "__dict__" attribute is not possible ' + '(you can write\n' + '"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", ' + "but you can't\n" + 'write "m.__dict__ = {}"). Modifying "__dict__" directly ' + 'is not\n' + 'recommended.\n' + '\n' + 'Modules built into the interpreter are written like this: ' + '"". If loaded from a file, they are ' + 'written as\n' + '"".\n', + 'typesseq': '\n' + 'Sequence Types --- "str", "unicode", "list", "tuple", ' + '"bytearray", "buffer", "xrange"\n' + '*************************************************************************************\n' + '\n' + 'There are seven sequence types: strings, Unicode strings, ' + 'lists,\n' + 'tuples, bytearrays, buffers, and xrange objects.\n' + '\n' + 'For other containers see the built in "dict" and "set" ' + 'classes, and\n' + 'the "collections" module.\n' + '\n' + 'String literals are written in single or double quotes: ' + '"\'xyzzy\'",\n' + '""frobozz"". See String literals for more about string ' + 'literals.\n' + 'Unicode strings are much like strings, but are specified in ' + 'the syntax\n' + 'using a preceding "\'u\'" character: "u\'abc\'", "u"def"". In ' + 'addition to\n' + 'the functionality described here, there are also ' + 'string-specific\n' + 'methods described in the String Methods section. Lists are ' + 'constructed\n' + 'with square brackets, separating items with commas: "[a, b, ' + 'c]".\n' + 'Tuples are constructed by the comma operator (not within ' + 'square\n' + 'brackets), with or without enclosing parentheses, but an empty ' + 'tuple\n' + 'must have the enclosing parentheses, such as "a, b, c" or ' + '"()". A\n' + 'single item tuple must have a trailing comma, such as "(d,)".\n' + '\n' + 'Bytearray objects are created with the built-in function\n' + '"bytearray()".\n' + '\n' + 'Buffer objects are not directly supported by Python syntax, ' + 'but can be\n' + 'created by calling the built-in function "buffer()". They ' + "don't\n" + 'support concatenation or repetition.\n' + '\n' + 'Objects of type xrange are similar to buffers in that there is ' + 'no\n' + 'specific syntax to create them, but they are created using ' + 'the\n' + '"xrange()" function. They don\'t support slicing, ' + 'concatenation or\n' + 'repetition, and using "in", "not in", "min()" or "max()" on ' + 'them is\n' + 'inefficient.\n' + '\n' + 'Most sequence types support the following operations. The ' + '"in" and\n' + '"not in" operations have the same priorities as the ' + 'comparison\n' + 'operations. The "+" and "*" operations have the same priority ' + 'as the\n' + 'corresponding numeric operations. [3] Additional methods are ' + 'provided\n' + 'for Mutable Sequence Types.\n' + '\n' + 'This table lists the sequence operations sorted in ascending ' + 'priority.\n' + 'In the table, *s* and *t* are sequences of the same type; *n*, ' + '*i* and\n' + '*j* are integers:\n' + '\n' + '+--------------------+----------------------------------+------------+\n' + '| Operation | Result | ' + 'Notes |\n' + '+====================+==================================+============+\n' + '| "x in s" | "True" if an item of *s* is | ' + '(1) |\n' + '| | equal to *x*, else "False" ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "x not in s" | "False" if an item of *s* is | ' + '(1) |\n' + '| | equal to *x*, else "True" ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s + t" | the concatenation of *s* and *t* | ' + '(6) |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s * n, n * s" | equivalent to adding *s* to | ' + '(2) |\n' + '| | itself *n* times ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s[i]" | *i*th item of *s*, origin 0 | ' + '(3) |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s[i:j]" | slice of *s* from *i* to *j* | ' + '(3)(4) |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s[i:j:k]" | slice of *s* from *i* to *j* | ' + '(3)(5) |\n' + '| | with step *k* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "len(s)" | length of *s* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "min(s)" | smallest item of *s* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "max(s)" | largest item of *s* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s.index(x)" | index of the first occurrence of ' + '| |\n' + '| | *x* in *s* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '| "s.count(x)" | total number of occurrences of ' + '| |\n' + '| | *x* in *s* ' + '| |\n' + '+--------------------+----------------------------------+------------+\n' + '\n' + 'Sequence types also support comparisons. In particular, tuples ' + 'and\n' + 'lists are compared lexicographically by comparing ' + 'corresponding\n' + 'elements. This means that to compare equal, every element must ' + 'compare\n' + 'equal and the two sequences must be of the same type and have ' + 'the same\n' + 'length. (For full details see Comparisons in the language ' + 'reference.)\n' + '\n' + 'Notes:\n' + '\n' + '1. When *s* is a string or Unicode string object the "in" and ' + '"not\n' + ' in" operations act like a substring test. In Python ' + 'versions\n' + ' before 2.3, *x* had to be a string of length 1. In Python ' + '2.3 and\n' + ' beyond, *x* may be a string of any length.\n' + '\n' + '2. Values of *n* less than "0" are treated as "0" (which ' + 'yields an\n' + ' empty sequence of the same type as *s*). Note that items ' + 'in the\n' + ' sequence *s* are not copied; they are referenced multiple ' + 'times.\n' + ' This often haunts new Python programmers; consider:\n' + '\n' + ' >>> lists = [[]] * 3\n' + ' >>> lists\n' + ' [[], [], []]\n' + ' >>> lists[0].append(3)\n' + ' >>> lists\n' + ' [[3], [3], [3]]\n' + '\n' + ' What has happened is that "[[]]" is a one-element list ' + 'containing\n' + ' an empty list, so all three elements of "[[]] * 3" are ' + 'references\n' + ' to this single empty list. Modifying any of the elements ' + 'of\n' + ' "lists" modifies this single list. You can create a list ' + 'of\n' + ' different lists this way:\n' + '\n' + ' >>> lists = [[] for i in range(3)]\n' + ' >>> lists[0].append(3)\n' + ' >>> lists[1].append(5)\n' + ' >>> lists[2].append(7)\n' + ' >>> lists\n' + ' [[3], [5], [7]]\n' + '\n' + ' Further explanation is available in the FAQ entry How do I ' + 'create a\n' + ' multidimensional list?.\n' + '\n' + '3. If *i* or *j* is negative, the index is relative to the end ' + 'of\n' + ' the string: "len(s) + i" or "len(s) + j" is substituted. ' + 'But note\n' + ' that "-0" is still "0".\n' + '\n' + '4. The slice of *s* from *i* to *j* is defined as the sequence ' + 'of\n' + ' items with index *k* such that "i <= k < j". If *i* or *j* ' + 'is\n' + ' greater than "len(s)", use "len(s)". If *i* is omitted or ' + '"None",\n' + ' use "0". If *j* is omitted or "None", use "len(s)". If ' + '*i* is\n' + ' greater than or equal to *j*, the slice is empty.\n' + '\n' + '5. The slice of *s* from *i* to *j* with step *k* is defined ' + 'as the\n' + ' sequence of items with index "x = i + n*k" such that "0 <= ' + 'n <\n' + ' (j-i)/k". In other words, the indices are "i", "i+k", ' + '"i+2*k",\n' + ' "i+3*k" and so on, stopping when *j* is reached (but never\n' + ' including *j*). If *i* or *j* is greater than "len(s)", ' + 'use\n' + ' "len(s)". If *i* or *j* are omitted or "None", they become ' + '"end"\n' + ' values (which end depends on the sign of *k*). Note, *k* ' + 'cannot be\n' + ' zero. If *k* is "None", it is treated like "1".\n' + '\n' + '6. **CPython implementation detail:** If *s* and *t* are both\n' + ' strings, some Python implementations such as CPython can ' + 'usually\n' + ' perform an in-place optimization for assignments of the ' + 'form "s = s\n' + ' + t" or "s += t". When applicable, this optimization ' + 'makes\n' + ' quadratic run-time much less likely. This optimization is ' + 'both\n' + ' version and implementation dependent. For performance ' + 'sensitive\n' + ' code, it is preferable to use the "str.join()" method which ' + 'assures\n' + ' consistent linear concatenation performance across versions ' + 'and\n' + ' implementations.\n' + '\n' + ' Changed in version 2.4: Formerly, string concatenation ' + 'never\n' + ' occurred in-place.\n' + '\n' + '\n' + 'String Methods\n' + '==============\n' + '\n' + 'Below are listed the string methods which both 8-bit strings ' + 'and\n' + 'Unicode objects support. Some of them are also available on\n' + '"bytearray" objects.\n' + '\n' + "In addition, Python's strings support the sequence type " + 'methods\n' + 'described in the Sequence Types --- str, unicode, list, ' + 'tuple,\n' + 'bytearray, buffer, xrange section. To output formatted strings ' + 'use\n' + 'template strings or the "%" operator described in the String\n' + 'Formatting Operations section. Also, see the "re" module for ' + 'string\n' + 'functions based on regular expressions.\n' + '\n' + 'str.capitalize()\n' + '\n' + ' Return a copy of the string with its first character ' + 'capitalized\n' + ' and the rest lowercased.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.center(width[, fillchar])\n' + '\n' + ' Return centered in a string of length *width*. Padding is ' + 'done\n' + ' using the specified *fillchar* (default is a space).\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.count(sub[, start[, end]])\n' + '\n' + ' Return the number of non-overlapping occurrences of ' + 'substring *sub*\n' + ' in the range [*start*, *end*]. Optional arguments *start* ' + 'and\n' + ' *end* are interpreted as in slice notation.\n' + '\n' + 'str.decode([encoding[, errors]])\n' + '\n' + ' Decodes the string using the codec registered for ' + '*encoding*.\n' + ' *encoding* defaults to the default string encoding. ' + '*errors* may\n' + ' be given to set a different error handling scheme. The ' + 'default is\n' + ' "\'strict\'", meaning that encoding errors raise ' + '"UnicodeError".\n' + ' Other possible values are "\'ignore\'", "\'replace\'" and ' + 'any other\n' + ' name registered via "codecs.register_error()", see section ' + 'Codec\n' + ' Base Classes.\n' + '\n' + ' New in version 2.2.\n' + '\n' + ' Changed in version 2.3: Support for other error handling ' + 'schemes\n' + ' added.\n' + '\n' + ' Changed in version 2.7: Support for keyword arguments ' + 'added.\n' + '\n' + 'str.encode([encoding[, errors]])\n' + '\n' + ' Return an encoded version of the string. Default encoding ' + 'is the\n' + ' current default string encoding. *errors* may be given to ' + 'set a\n' + ' different error handling scheme. The default for *errors* ' + 'is\n' + ' "\'strict\'", meaning that encoding errors raise a ' + '"UnicodeError".\n' + ' Other possible values are "\'ignore\'", "\'replace\'",\n' + ' "\'xmlcharrefreplace\'", "\'backslashreplace\'" and any ' + 'other name\n' + ' registered via "codecs.register_error()", see section Codec ' + 'Base\n' + ' Classes. For a list of possible encodings, see section ' + 'Standard\n' + ' Encodings.\n' + '\n' + ' New in version 2.0.\n' + '\n' + ' Changed in version 2.3: Support for "\'xmlcharrefreplace\'" ' + 'and\n' + ' "\'backslashreplace\'" and other error handling schemes ' + 'added.\n' + '\n' + ' Changed in version 2.7: Support for keyword arguments ' + 'added.\n' + '\n' + 'str.endswith(suffix[, start[, end]])\n' + '\n' + ' Return "True" if the string ends with the specified ' + '*suffix*,\n' + ' otherwise return "False". *suffix* can also be a tuple of ' + 'suffixes\n' + ' to look for. With optional *start*, test beginning at ' + 'that\n' + ' position. With optional *end*, stop comparing at that ' + 'position.\n' + '\n' + ' Changed in version 2.5: Accept tuples as *suffix*.\n' + '\n' + 'str.expandtabs([tabsize])\n' + '\n' + ' Return a copy of the string where all tab characters are ' + 'replaced\n' + ' by one or more spaces, depending on the current column and ' + 'the\n' + ' given tab size. Tab positions occur every *tabsize* ' + 'characters\n' + ' (default is 8, giving tab positions at columns 0, 8, 16 and ' + 'so on).\n' + ' To expand the string, the current column is set to zero and ' + 'the\n' + ' string is examined character by character. If the ' + 'character is a\n' + ' tab ("\\t"), one or more space characters are inserted in ' + 'the result\n' + ' until the current column is equal to the next tab position. ' + '(The\n' + ' tab character itself is not copied.) If the character is a ' + 'newline\n' + ' ("\\n") or return ("\\r"), it is copied and the current ' + 'column is\n' + ' reset to zero. Any other character is copied unchanged and ' + 'the\n' + ' current column is incremented by one regardless of how the\n' + ' character is represented when printed.\n' + '\n' + " >>> '01\\t012\\t0123\\t01234'.expandtabs()\n" + " '01 012 0123 01234'\n" + " >>> '01\\t012\\t0123\\t01234'.expandtabs(4)\n" + " '01 012 0123 01234'\n" + '\n' + 'str.find(sub[, start[, end]])\n' + '\n' + ' Return the lowest index in the string where substring *sub* ' + 'is\n' + ' found, such that *sub* is contained in the slice ' + '"s[start:end]".\n' + ' Optional arguments *start* and *end* are interpreted as in ' + 'slice\n' + ' notation. Return "-1" if *sub* is not found.\n' + '\n' + ' Note: The "find()" method should be used only if you need ' + 'to know\n' + ' the position of *sub*. To check if *sub* is a substring ' + 'or not,\n' + ' use the "in" operator:\n' + '\n' + " >>> 'Py' in 'Python'\n" + ' True\n' + '\n' + 'str.format(*args, **kwargs)\n' + '\n' + ' Perform a string formatting operation. The string on which ' + 'this\n' + ' method is called can contain literal text or replacement ' + 'fields\n' + ' delimited by braces "{}". Each replacement field contains ' + 'either\n' + ' the numeric index of a positional argument, or the name of ' + 'a\n' + ' keyword argument. Returns a copy of the string where each\n' + ' replacement field is replaced with the string value of the\n' + ' corresponding argument.\n' + '\n' + ' >>> "The sum of 1 + 2 is {0}".format(1+2)\n' + " 'The sum of 1 + 2 is 3'\n" + '\n' + ' See Format String Syntax for a description of the various\n' + ' formatting options that can be specified in format ' + 'strings.\n' + '\n' + ' This method of string formatting is the new standard in ' + 'Python 3,\n' + ' and should be preferred to the "%" formatting described in ' + 'String\n' + ' Formatting Operations in new code.\n' + '\n' + ' New in version 2.6.\n' + '\n' + 'str.index(sub[, start[, end]])\n' + '\n' + ' Like "find()", but raise "ValueError" when the substring is ' + 'not\n' + ' found.\n' + '\n' + 'str.isalnum()\n' + '\n' + ' Return true if all characters in the string are ' + 'alphanumeric and\n' + ' there is at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isalpha()\n' + '\n' + ' Return true if all characters in the string are alphabetic ' + 'and\n' + ' there is at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isdigit()\n' + '\n' + ' Return true if all characters in the string are digits and ' + 'there is\n' + ' at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.islower()\n' + '\n' + ' Return true if all cased characters [4] in the string are ' + 'lowercase\n' + ' and there is at least one cased character, false ' + 'otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isspace()\n' + '\n' + ' Return true if there are only whitespace characters in the ' + 'string\n' + ' and there is at least one character, false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.istitle()\n' + '\n' + ' Return true if the string is a titlecased string and there ' + 'is at\n' + ' least one character, for example uppercase characters may ' + 'only\n' + ' follow uncased characters and lowercase characters only ' + 'cased ones.\n' + ' Return false otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.isupper()\n' + '\n' + ' Return true if all cased characters [4] in the string are ' + 'uppercase\n' + ' and there is at least one cased character, false ' + 'otherwise.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.join(iterable)\n' + '\n' + ' Return a string which is the concatenation of the strings ' + 'in the\n' + ' *iterable* *iterable*. The separator between elements is ' + 'the\n' + ' string providing this method.\n' + '\n' + 'str.ljust(width[, fillchar])\n' + '\n' + ' Return the string left justified in a string of length ' + '*width*.\n' + ' Padding is done using the specified *fillchar* (default is ' + 'a\n' + ' space). The original string is returned if *width* is less ' + 'than or\n' + ' equal to "len(s)".\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.lower()\n' + '\n' + ' Return a copy of the string with all the cased characters ' + '[4]\n' + ' converted to lowercase.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.lstrip([chars])\n' + '\n' + ' Return a copy of the string with leading characters ' + 'removed. The\n' + ' *chars* argument is a string specifying the set of ' + 'characters to be\n' + ' removed. If omitted or "None", the *chars* argument ' + 'defaults to\n' + ' removing whitespace. The *chars* argument is not a prefix; ' + 'rather,\n' + ' all combinations of its values are stripped:\n' + '\n' + " >>> ' spacious '.lstrip()\n" + " 'spacious '\n" + " >>> 'www.example.com'.lstrip('cmowz.')\n" + " 'example.com'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.partition(sep)\n' + '\n' + ' Split the string at the first occurrence of *sep*, and ' + 'return a\n' + ' 3-tuple containing the part before the separator, the ' + 'separator\n' + ' itself, and the part after the separator. If the separator ' + 'is not\n' + ' found, return a 3-tuple containing the string itself, ' + 'followed by\n' + ' two empty strings.\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'str.replace(old, new[, count])\n' + '\n' + ' Return a copy of the string with all occurrences of ' + 'substring *old*\n' + ' replaced by *new*. If the optional argument *count* is ' + 'given, only\n' + ' the first *count* occurrences are replaced.\n' + '\n' + 'str.rfind(sub[, start[, end]])\n' + '\n' + ' Return the highest index in the string where substring ' + '*sub* is\n' + ' found, such that *sub* is contained within "s[start:end]".\n' + ' Optional arguments *start* and *end* are interpreted as in ' + 'slice\n' + ' notation. Return "-1" on failure.\n' + '\n' + 'str.rindex(sub[, start[, end]])\n' + '\n' + ' Like "rfind()" but raises "ValueError" when the substring ' + '*sub* is\n' + ' not found.\n' + '\n' + 'str.rjust(width[, fillchar])\n' + '\n' + ' Return the string right justified in a string of length ' + '*width*.\n' + ' Padding is done using the specified *fillchar* (default is ' + 'a\n' + ' space). The original string is returned if *width* is less ' + 'than or\n' + ' equal to "len(s)".\n' + '\n' + ' Changed in version 2.4: Support for the *fillchar* ' + 'argument.\n' + '\n' + 'str.rpartition(sep)\n' + '\n' + ' Split the string at the last occurrence of *sep*, and ' + 'return a\n' + ' 3-tuple containing the part before the separator, the ' + 'separator\n' + ' itself, and the part after the separator. If the separator ' + 'is not\n' + ' found, return a 3-tuple containing two empty strings, ' + 'followed by\n' + ' the string itself.\n' + '\n' + ' New in version 2.5.\n' + '\n' + 'str.rsplit([sep[, maxsplit]])\n' + '\n' + ' Return a list of the words in the string, using *sep* as ' + 'the\n' + ' delimiter string. If *maxsplit* is given, at most ' + '*maxsplit* splits\n' + ' are done, the *rightmost* ones. If *sep* is not specified ' + 'or\n' + ' "None", any whitespace string is a separator. Except for ' + 'splitting\n' + ' from the right, "rsplit()" behaves like "split()" which is\n' + ' described in detail below.\n' + '\n' + ' New in version 2.4.\n' + '\n' + 'str.rstrip([chars])\n' + '\n' + ' Return a copy of the string with trailing characters ' + 'removed. The\n' + ' *chars* argument is a string specifying the set of ' + 'characters to be\n' + ' removed. If omitted or "None", the *chars* argument ' + 'defaults to\n' + ' removing whitespace. The *chars* argument is not a suffix; ' + 'rather,\n' + ' all combinations of its values are stripped:\n' + '\n' + " >>> ' spacious '.rstrip()\n" + " ' spacious'\n" + " >>> 'mississippi'.rstrip('ipz')\n" + " 'mississ'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.split([sep[, maxsplit]])\n' + '\n' + ' Return a list of the words in the string, using *sep* as ' + 'the\n' + ' delimiter string. If *maxsplit* is given, at most ' + '*maxsplit*\n' + ' splits are done (thus, the list will have at most ' + '"maxsplit+1"\n' + ' elements). If *maxsplit* is not specified or "-1", then ' + 'there is\n' + ' no limit on the number of splits (all possible splits are ' + 'made).\n' + '\n' + ' If *sep* is given, consecutive delimiters are not grouped ' + 'together\n' + ' and are deemed to delimit empty strings (for example,\n' + ' "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). ' + 'The *sep* argument\n' + ' may consist of multiple characters (for example,\n' + ' "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', ' + '\'3\']"). Splitting an\n' + ' empty string with a specified separator returns "[\'\']".\n' + '\n' + ' If *sep* is not specified or is "None", a different ' + 'splitting\n' + ' algorithm is applied: runs of consecutive whitespace are ' + 'regarded\n' + ' as a single separator, and the result will contain no empty ' + 'strings\n' + ' at the start or end if the string has leading or trailing\n' + ' whitespace. Consequently, splitting an empty string or a ' + 'string\n' + ' consisting of just whitespace with a "None" separator ' + 'returns "[]".\n' + '\n' + ' For example, "\' 1 2 3 \'.split()" returns "[\'1\', ' + '\'2\', \'3\']", and\n' + ' "\' 1 2 3 \'.split(None, 1)" returns "[\'1\', \'2 3 ' + '\']".\n' + '\n' + 'str.splitlines([keepends])\n' + '\n' + ' Return a list of the lines in the string, breaking at line\n' + ' boundaries. This method uses the *universal newlines* ' + 'approach to\n' + ' splitting lines. Line breaks are not included in the ' + 'resulting list\n' + ' unless *keepends* is given and true.\n' + '\n' + ' For example, "\'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()" ' + 'returns "[\'ab\n' + ' c\', \'\', \'de fg\', \'kl\']", while the same call with\n' + ' "splitlines(True)" returns "[\'ab c\\n\', \'\\n\', \'de ' + 'fg\\r\', \'kl\\r\\n\']".\n' + '\n' + ' Unlike "split()" when a delimiter string *sep* is given, ' + 'this\n' + ' method returns an empty list for the empty string, and a ' + 'terminal\n' + ' line break does not result in an extra line.\n' + '\n' + 'str.startswith(prefix[, start[, end]])\n' + '\n' + ' Return "True" if string starts with the *prefix*, otherwise ' + 'return\n' + ' "False". *prefix* can also be a tuple of prefixes to look ' + 'for.\n' + ' With optional *start*, test string beginning at that ' + 'position.\n' + ' With optional *end*, stop comparing string at that ' + 'position.\n' + '\n' + ' Changed in version 2.5: Accept tuples as *prefix*.\n' + '\n' + 'str.strip([chars])\n' + '\n' + ' Return a copy of the string with the leading and trailing\n' + ' characters removed. The *chars* argument is a string ' + 'specifying the\n' + ' set of characters to be removed. If omitted or "None", the ' + '*chars*\n' + ' argument defaults to removing whitespace. The *chars* ' + 'argument is\n' + ' not a prefix or suffix; rather, all combinations of its ' + 'values are\n' + ' stripped:\n' + '\n' + " >>> ' spacious '.strip()\n" + " 'spacious'\n" + " >>> 'www.example.com'.strip('cmowz.')\n" + " 'example'\n" + '\n' + ' Changed in version 2.2.2: Support for the *chars* ' + 'argument.\n' + '\n' + 'str.swapcase()\n' + '\n' + ' Return a copy of the string with uppercase characters ' + 'converted to\n' + ' lowercase and vice versa.\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.title()\n' + '\n' + ' Return a titlecased version of the string where words start ' + 'with an\n' + ' uppercase character and the remaining characters are ' + 'lowercase.\n' + '\n' + ' The algorithm uses a simple language-independent definition ' + 'of a\n' + ' word as groups of consecutive letters. The definition ' + 'works in\n' + ' many contexts but it means that apostrophes in contractions ' + 'and\n' + ' possessives form word boundaries, which may not be the ' + 'desired\n' + ' result:\n' + '\n' + ' >>> "they\'re bill\'s friends from the UK".title()\n' + ' "They\'Re Bill\'S Friends From The Uk"\n' + '\n' + ' A workaround for apostrophes can be constructed using ' + 'regular\n' + ' expressions:\n' + '\n' + ' >>> import re\n' + ' >>> def titlecase(s):\n' + ' ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n' + ' ... lambda mo: mo.group(0)[0].upper() ' + '+\n' + ' ... ' + 'mo.group(0)[1:].lower(),\n' + ' ... s)\n' + ' ...\n' + ' >>> titlecase("they\'re bill\'s friends.")\n' + ' "They\'re Bill\'s Friends."\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.translate(table[, deletechars])\n' + '\n' + ' Return a copy of the string where all characters occurring ' + 'in the\n' + ' optional argument *deletechars* are removed, and the ' + 'remaining\n' + ' characters have been mapped through the given translation ' + 'table,\n' + ' which must be a string of length 256.\n' + '\n' + ' You can use the "maketrans()" helper function in the ' + '"string"\n' + ' module to create a translation table. For string objects, ' + 'set the\n' + ' *table* argument to "None" for translations that only ' + 'delete\n' + ' characters:\n' + '\n' + " >>> 'read this short text'.translate(None, 'aeiou')\n" + " 'rd ths shrt txt'\n" + '\n' + ' New in version 2.6: Support for a "None" *table* argument.\n' + '\n' + ' For Unicode objects, the "translate()" method does not ' + 'accept the\n' + ' optional *deletechars* argument. Instead, it returns a ' + 'copy of the\n' + ' *s* where all characters have been mapped through the ' + 'given\n' + ' translation table which must be a mapping of Unicode ' + 'ordinals to\n' + ' Unicode ordinals, Unicode strings or "None". Unmapped ' + 'characters\n' + ' are left untouched. Characters mapped to "None" are ' + 'deleted. Note,\n' + ' a more flexible approach is to create a custom character ' + 'mapping\n' + ' codec using the "codecs" module (see "encodings.cp1251" for ' + 'an\n' + ' example).\n' + '\n' + 'str.upper()\n' + '\n' + ' Return a copy of the string with all the cased characters ' + '[4]\n' + ' converted to uppercase. Note that "str.upper().isupper()" ' + 'might be\n' + ' "False" if "s" contains uncased characters or if the ' + 'Unicode\n' + ' category of the resulting character(s) is not "Lu" ' + '(Letter,\n' + ' uppercase), but e.g. "Lt" (Letter, titlecase).\n' + '\n' + ' For 8-bit strings, this method is locale-dependent.\n' + '\n' + 'str.zfill(width)\n' + '\n' + ' Return the numeric string left filled with zeros in a ' + 'string of\n' + ' length *width*. A sign prefix is handled correctly. The ' + 'original\n' + ' string is returned if *width* is less than or equal to ' + '"len(s)".\n' + '\n' + ' New in version 2.2.2.\n' + '\n' + 'The following methods are present only on unicode objects:\n' + '\n' + 'unicode.isnumeric()\n' + '\n' + ' Return "True" if there are only numeric characters in S, ' + '"False"\n' + ' otherwise. Numeric characters include digit characters, and ' + 'all\n' + ' characters that have the Unicode numeric value property, ' + 'e.g.\n' + ' U+2155, VULGAR FRACTION ONE FIFTH.\n' + '\n' + 'unicode.isdecimal()\n' + '\n' + ' Return "True" if there are only decimal characters in S, ' + '"False"\n' + ' otherwise. Decimal characters include digit characters, and ' + 'all\n' + ' characters that can be used to form decimal-radix numbers, ' + 'e.g.\n' + ' U+0660, ARABIC-INDIC DIGIT ZERO.\n' + '\n' + '\n' + 'String Formatting Operations\n' + '============================\n' + '\n' + 'String and Unicode objects have one unique built-in operation: ' + 'the "%"\n' + 'operator (modulo). This is also known as the string ' + '*formatting* or\n' + '*interpolation* operator. Given "format % values" (where ' + '*format* is\n' + 'a string or Unicode object), "%" conversion specifications in ' + '*format*\n' + 'are replaced with zero or more elements of *values*. The ' + 'effect is\n' + 'similar to the using "sprintf()" in the C language. If ' + '*format* is a\n' + 'Unicode object, or if any of the objects being converted using ' + 'the\n' + '"%s" conversion are Unicode objects, the result will also be a ' + 'Unicode\n' + 'object.\n' + '\n' + 'If *format* requires a single argument, *values* may be a ' + 'single non-\n' + 'tuple object. [5] Otherwise, *values* must be a tuple with ' + 'exactly\n' + 'the number of items specified by the format string, or a ' + 'single\n' + 'mapping object (for example, a dictionary).\n' + '\n' + 'A conversion specifier contains two or more characters and has ' + 'the\n' + 'following components, which must occur in this order:\n' + '\n' + '1. The "\'%\'" character, which marks the start of the ' + 'specifier.\n' + '\n' + '2. Mapping key (optional), consisting of a parenthesised ' + 'sequence\n' + ' of characters (for example, "(somename)").\n' + '\n' + '3. Conversion flags (optional), which affect the result of ' + 'some\n' + ' conversion types.\n' + '\n' + '4. Minimum field width (optional). If specified as an ' + '"\'*\'"\n' + ' (asterisk), the actual width is read from the next element ' + 'of the\n' + ' tuple in *values*, and the object to convert comes after ' + 'the\n' + ' minimum field width and optional precision.\n' + '\n' + '5. Precision (optional), given as a "\'.\'" (dot) followed by ' + 'the\n' + ' precision. If specified as "\'*\'" (an asterisk), the ' + 'actual width\n' + ' is read from the next element of the tuple in *values*, and ' + 'the\n' + ' value to convert comes after the precision.\n' + '\n' + '6. Length modifier (optional).\n' + '\n' + '7. Conversion type.\n' + '\n' + 'When the right argument is a dictionary (or other mapping ' + 'type), then\n' + 'the formats in the string *must* include a parenthesised ' + 'mapping key\n' + 'into that dictionary inserted immediately after the "\'%\'" ' + 'character.\n' + 'The mapping key selects the value to be formatted from the ' + 'mapping.\n' + 'For example:\n' + '\n' + ">>> print '%(language)s has %(number)03d quote types.' % \\\n" + '... {"language": "Python", "number": 2}\n' + 'Python has 002 quote types.\n' + '\n' + 'In this case no "*" specifiers may occur in a format (since ' + 'they\n' + 'require a sequential parameter list).\n' + '\n' + 'The conversion flag characters are:\n' + '\n' + '+-----------+-----------------------------------------------------------------------+\n' + '| Flag | ' + 'Meaning ' + '|\n' + '+===========+=======================================================================+\n' + '| "\'#\'" | The value conversion will use the "alternate ' + 'form" (where defined |\n' + '| | ' + 'below). ' + '|\n' + '+-----------+-----------------------------------------------------------------------+\n' + '| "\'0\'" | The conversion will be zero padded for numeric ' + 'values. |\n' + '+-----------+-----------------------------------------------------------------------+\n' + '| "\'-\'" | The converted value is left adjusted ' + '(overrides the "\'0\'" conversion |\n' + '| | if both are ' + 'given). |\n' + '+-----------+-----------------------------------------------------------------------+\n' + '| "\' \'" | (a space) A blank should be left before a ' + 'positive number (or empty |\n' + '| | string) produced by a signed ' + 'conversion. |\n' + '+-----------+-----------------------------------------------------------------------+\n' + '| "\'+\'" | A sign character ("\'+\'" or "\'-\'") will ' + 'precede the conversion |\n' + '| | (overrides a "space" ' + 'flag). |\n' + '+-----------+-----------------------------------------------------------------------+\n' + '\n' + 'A length modifier ("h", "l", or "L") may be present, but is ' + 'ignored as\n' + 'it is not necessary for Python -- so e.g. "%ld" is identical ' + 'to "%d".\n' + '\n' + 'The conversion types are:\n' + '\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| Conversion | ' + 'Meaning | ' + 'Notes |\n' + '+==============+=======================================================+=========+\n' + '| "\'d\'" | Signed integer ' + 'decimal. | |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'i\'" | Signed integer ' + 'decimal. | |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'o\'" | Signed octal ' + 'value. | (1) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'u\'" | Obsolete type -- it is identical to ' + '"\'d\'". | (7) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'x\'" | Signed hexadecimal ' + '(lowercase). | (2) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'X\'" | Signed hexadecimal ' + '(uppercase). | (2) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'e\'" | Floating point exponential format ' + '(lowercase). | (3) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'E\'" | Floating point exponential format ' + '(uppercase). | (3) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'f\'" | Floating point decimal ' + 'format. | (3) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'F\'" | Floating point decimal ' + 'format. | (3) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'g\'" | Floating point format. Uses lowercase ' + 'exponential | (4) |\n' + '| | format if exponent is less than -4 or not ' + 'less than | |\n' + '| | precision, decimal format ' + 'otherwise. | |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'G\'" | Floating point format. Uses uppercase ' + 'exponential | (4) |\n' + '| | format if exponent is less than -4 or not ' + 'less than | |\n' + '| | precision, decimal format ' + 'otherwise. | |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'c\'" | Single character (accepts integer or single ' + 'character | |\n' + '| | ' + 'string). ' + '| |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'r\'" | String (converts any Python object using ' + 'repr()). | (5) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'s\'" | String (converts any Python object using ' + '"str()"). | (6) |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '| "\'%\'" | No argument is converted, results in a ' + '"\'%\'" | |\n' + '| | character in the ' + 'result. | |\n' + '+--------------+-------------------------------------------------------+---------+\n' + '\n' + 'Notes:\n' + '\n' + '1. The alternate form causes a leading zero ("\'0\'") to be ' + 'inserted\n' + ' between left-hand padding and the formatting of the number ' + 'if the\n' + ' leading character of the result is not already a zero.\n' + '\n' + '2. The alternate form causes a leading "\'0x\'" or "\'0X\'" ' + '(depending\n' + ' on whether the "\'x\'" or "\'X\'" format was used) to be ' + 'inserted\n' + ' between left-hand padding and the formatting of the number ' + 'if the\n' + ' leading character of the result is not already a zero.\n' + '\n' + '3. The alternate form causes the result to always contain a ' + 'decimal\n' + ' point, even if no digits follow it.\n' + '\n' + ' The precision determines the number of digits after the ' + 'decimal\n' + ' point and defaults to 6.\n' + '\n' + '4. The alternate form causes the result to always contain a ' + 'decimal\n' + ' point, and trailing zeroes are not removed as they would ' + 'otherwise\n' + ' be.\n' + '\n' + ' The precision determines the number of significant digits ' + 'before\n' + ' and after the decimal point and defaults to 6.\n' + '\n' + '5. The "%r" conversion was added in Python 2.0.\n' + '\n' + ' The precision determines the maximal number of characters ' + 'used.\n' + '\n' + '6. If the object or format provided is a "unicode" string, ' + 'the\n' + ' resulting string will also be "unicode".\n' + '\n' + ' The precision determines the maximal number of characters ' + 'used.\n' + '\n' + '7. See **PEP 237**.\n' + '\n' + 'Since Python strings have an explicit length, "%s" conversions ' + 'do not\n' + 'assume that "\'\\0\'" is the end of the string.\n' + '\n' + 'Changed in version 2.7: "%f" conversions for numbers whose ' + 'absolute\n' + 'value is over 1e50 are no longer replaced by "%g" ' + 'conversions.\n' + '\n' + 'Additional string operations are defined in standard modules ' + '"string"\n' + 'and "re".\n' + '\n' + '\n' + 'XRange Type\n' + '===========\n' + '\n' + 'The "xrange" type is an immutable sequence which is commonly ' + 'used for\n' + 'looping. The advantage of the "xrange" type is that an ' + '"xrange"\n' + 'object will always take the same amount of memory, no matter ' + 'the size\n' + 'of the range it represents. There are no consistent ' + 'performance\n' + 'advantages.\n' + '\n' + 'XRange objects have very little behavior: they only support ' + 'indexing,\n' + 'iteration, and the "len()" function.\n' + '\n' + '\n' + 'Mutable Sequence Types\n' + '======================\n' + '\n' + 'List and "bytearray" objects support additional operations ' + 'that allow\n' + 'in-place modification of the object. Other mutable sequence ' + 'types\n' + '(when added to the language) should also support these ' + 'operations.\n' + 'Strings and tuples are immutable sequence types: such objects ' + 'cannot\n' + 'be modified once created. The following operations are defined ' + 'on\n' + 'mutable sequence types (where *x* is an arbitrary object):\n' + '\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| Operation | ' + 'Result | Notes |\n' + '+================================+==================================+=======================+\n' + '| "s[i] = x" | item *i* of *s* is replaced ' + 'by | |\n' + '| | ' + '*x* | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s[i:j] = t" | slice of *s* from *i* to ' + '*j* is | |\n' + '| | replaced by the contents of ' + 'the | |\n' + '| | iterable ' + '*t* | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "del s[i:j]" | same as "s[i:j] = ' + '[]" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s[i:j:k] = t" | the elements of "s[i:j:k]" ' + 'are | (1) |\n' + '| | replaced by those of ' + '*t* | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "del s[i:j:k]" | removes the elements ' + 'of | |\n' + '| | "s[i:j:k]" from the ' + 'list | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.append(x)" | same as "s[len(s):len(s)] = ' + '[x]" | (2) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.extend(x)" or "s += t" | for the most part the same ' + 'as | (3) |\n' + '| | "s[len(s):len(s)] = ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s *= n" | updates *s* with its ' + 'contents | (11) |\n' + '| | repeated *n* ' + 'times | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.count(x)" | return number of *i*\'s for ' + 'which | |\n' + '| | "s[i] == ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.index(x[, i[, j]])" | return smallest *k* such ' + 'that | (4) |\n' + '| | "s[k] == x" and "i <= k < ' + 'j" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.insert(i, x)" | same as "s[i:i] = ' + '[x]" | (5) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.pop([i])" | same as "x = s[i]; del ' + 's[i]; | (6) |\n' + '| | return ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.remove(x)" | same as "del ' + 's[s.index(x)]" | (4) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.reverse()" | reverses the items of *s* ' + 'in | (7) |\n' + '| | ' + 'place | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.sort([cmp[, key[, | sort the items of *s* in ' + 'place | (7)(8)(9)(10) |\n' + '| reverse]]])" ' + '| | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '\n' + 'Notes:\n' + '\n' + '1. *t* must have the same length as the slice it is ' + 'replacing.\n' + '\n' + '2. The C implementation of Python has historically accepted\n' + ' multiple parameters and implicitly joined them into a ' + 'tuple; this\n' + ' no longer works in Python 2.0. Use of this misfeature has ' + 'been\n' + ' deprecated since Python 1.4.\n' + '\n' + '3. *x* can be any iterable object.\n' + '\n' + '4. Raises "ValueError" when *x* is not found in *s*. When a\n' + ' negative index is passed as the second or third parameter ' + 'to the\n' + ' "index()" method, the list length is added, as for slice ' + 'indices.\n' + ' If it is still negative, it is truncated to zero, as for ' + 'slice\n' + ' indices.\n' + '\n' + ' Changed in version 2.3: Previously, "index()" didn\'t have ' + 'arguments\n' + ' for specifying start and stop positions.\n' + '\n' + '5. When a negative index is passed as the first parameter to ' + 'the\n' + ' "insert()" method, the list length is added, as for slice ' + 'indices.\n' + ' If it is still negative, it is truncated to zero, as for ' + 'slice\n' + ' indices.\n' + '\n' + ' Changed in version 2.3: Previously, all negative indices ' + 'were\n' + ' truncated to zero.\n' + '\n' + '6. The "pop()" method\'s optional argument *i* defaults to ' + '"-1", so\n' + ' that by default the last item is removed and returned.\n' + '\n' + '7. The "sort()" and "reverse()" methods modify the list in ' + 'place\n' + ' for economy of space when sorting or reversing a large ' + 'list. To\n' + " remind you that they operate by side effect, they don't " + 'return the\n' + ' sorted or reversed list.\n' + '\n' + '8. The "sort()" method takes optional arguments for ' + 'controlling the\n' + ' comparisons.\n' + '\n' + ' *cmp* specifies a custom comparison function of two ' + 'arguments (list\n' + ' items) which should return a negative, zero or positive ' + 'number\n' + ' depending on whether the first argument is considered ' + 'smaller than,\n' + ' equal to, or larger than the second argument: "cmp=lambda ' + 'x,y:\n' + ' cmp(x.lower(), y.lower())". The default value is "None".\n' + '\n' + ' *key* specifies a function of one argument that is used to ' + 'extract\n' + ' a comparison key from each list element: "key=str.lower". ' + 'The\n' + ' default value is "None".\n' + '\n' + ' *reverse* is a boolean value. If set to "True", then the ' + 'list\n' + ' elements are sorted as if each comparison were reversed.\n' + '\n' + ' In general, the *key* and *reverse* conversion processes ' + 'are much\n' + ' faster than specifying an equivalent *cmp* function. This ' + 'is\n' + ' because *cmp* is called multiple times for each list ' + 'element while\n' + ' *key* and *reverse* touch each element only once. Use\n' + ' "functools.cmp_to_key()" to convert an old-style *cmp* ' + 'function to\n' + ' a *key* function.\n' + '\n' + ' Changed in version 2.3: Support for "None" as an equivalent ' + 'to\n' + ' omitting *cmp* was added.\n' + '\n' + ' Changed in version 2.4: Support for *key* and *reverse* was ' + 'added.\n' + '\n' + '9. Starting with Python 2.3, the "sort()" method is guaranteed ' + 'to\n' + ' be stable. A sort is stable if it guarantees not to change ' + 'the\n' + ' relative order of elements that compare equal --- this is ' + 'helpful\n' + ' for sorting in multiple passes (for example, sort by ' + 'department,\n' + ' then by salary grade).\n' + '\n' + '10. **CPython implementation detail:** While a list is being\n' + ' sorted, the effect of attempting to mutate, or even ' + 'inspect, the\n' + ' list is undefined. The C implementation of Python 2.3 and ' + 'newer\n' + ' makes the list appear empty for the duration, and raises\n' + ' "ValueError" if it can detect that the list has been ' + 'mutated\n' + ' during a sort.\n' + '\n' + '11. The value *n* is an integer, or an object implementing\n' + ' "__index__()". Zero and negative values of *n* clear the\n' + ' sequence. Items in the sequence are not copied; they are\n' + ' referenced multiple times, as explained for "s * n" under ' + 'Sequence\n' + ' Types --- str, unicode, list, tuple, bytearray, buffer, ' + 'xrange.\n', + 'typesseq-mutable': '\n' + 'Mutable Sequence Types\n' + '**********************\n' + '\n' + 'List and "bytearray" objects support additional ' + 'operations that allow\n' + 'in-place modification of the object. Other mutable ' + 'sequence types\n' + '(when added to the language) should also support these ' + 'operations.\n' + 'Strings and tuples are immutable sequence types: such ' + 'objects cannot\n' + 'be modified once created. The following operations are ' + 'defined on\n' + 'mutable sequence types (where *x* is an arbitrary ' + 'object):\n' + '\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| Operation | ' + 'Result | ' + 'Notes |\n' + '+================================+==================================+=======================+\n' + '| "s[i] = x" | item *i* of *s* is ' + 'replaced by | |\n' + '| | ' + '*x* ' + '| |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s[i:j] = t" | slice of *s* from ' + '*i* to *j* is | |\n' + '| | replaced by the ' + 'contents of the | |\n' + '| | iterable ' + '*t* | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "del s[i:j]" | same as "s[i:j] = ' + '[]" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s[i:j:k] = t" | the elements of ' + '"s[i:j:k]" are | (1) |\n' + '| | replaced by those ' + 'of *t* | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "del s[i:j:k]" | removes the ' + 'elements of | |\n' + '| | "s[i:j:k]" from the ' + 'list | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.append(x)" | same as ' + '"s[len(s):len(s)] = [x]" | (2) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.extend(x)" or "s += t" | for the most part ' + 'the same as | (3) |\n' + '| | "s[len(s):len(s)] = ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s *= n" | updates *s* with ' + 'its contents | (11) |\n' + '| | repeated *n* ' + 'times | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.count(x)" | return number of ' + "*i*'s for which | |\n" + '| | "s[i] == ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.index(x[, i[, j]])" | return smallest *k* ' + 'such that | (4) |\n' + '| | "s[k] == x" and "i ' + '<= k < j" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.insert(i, x)" | same as "s[i:i] = ' + '[x]" | (5) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.pop([i])" | same as "x = s[i]; ' + 'del s[i]; | (6) |\n' + '| | return ' + 'x" | |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.remove(x)" | same as "del ' + 's[s.index(x)]" | (4) |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.reverse()" | reverses the items ' + 'of *s* in | (7) |\n' + '| | ' + 'place ' + '| |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '| "s.sort([cmp[, key[, | sort the items of ' + '*s* in place | (7)(8)(9)(10) |\n' + '| reverse]]])" ' + '| ' + '| |\n' + '+--------------------------------+----------------------------------+-----------------------+\n' + '\n' + 'Notes:\n' + '\n' + '1. *t* must have the same length as the slice it is ' + 'replacing.\n' + '\n' + '2. The C implementation of Python has historically ' + 'accepted\n' + ' multiple parameters and implicitly joined them into ' + 'a tuple; this\n' + ' no longer works in Python 2.0. Use of this ' + 'misfeature has been\n' + ' deprecated since Python 1.4.\n' + '\n' + '3. *x* can be any iterable object.\n' + '\n' + '4. Raises "ValueError" when *x* is not found in *s*. ' + 'When a\n' + ' negative index is passed as the second or third ' + 'parameter to the\n' + ' "index()" method, the list length is added, as for ' + 'slice indices.\n' + ' If it is still negative, it is truncated to zero, ' + 'as for slice\n' + ' indices.\n' + '\n' + ' Changed in version 2.3: Previously, "index()" ' + "didn't have arguments\n" + ' for specifying start and stop positions.\n' + '\n' + '5. When a negative index is passed as the first ' + 'parameter to the\n' + ' "insert()" method, the list length is added, as for ' + 'slice indices.\n' + ' If it is still negative, it is truncated to zero, ' + 'as for slice\n' + ' indices.\n' + '\n' + ' Changed in version 2.3: Previously, all negative ' + 'indices were\n' + ' truncated to zero.\n' + '\n' + '6. The "pop()" method\'s optional argument *i* ' + 'defaults to "-1", so\n' + ' that by default the last item is removed and ' + 'returned.\n' + '\n' + '7. The "sort()" and "reverse()" methods modify the ' + 'list in place\n' + ' for economy of space when sorting or reversing a ' + 'large list. To\n' + ' remind you that they operate by side effect, they ' + "don't return the\n" + ' sorted or reversed list.\n' + '\n' + '8. The "sort()" method takes optional arguments for ' + 'controlling the\n' + ' comparisons.\n' + '\n' + ' *cmp* specifies a custom comparison function of two ' + 'arguments (list\n' + ' items) which should return a negative, zero or ' + 'positive number\n' + ' depending on whether the first argument is ' + 'considered smaller than,\n' + ' equal to, or larger than the second argument: ' + '"cmp=lambda x,y:\n' + ' cmp(x.lower(), y.lower())". The default value is ' + '"None".\n' + '\n' + ' *key* specifies a function of one argument that is ' + 'used to extract\n' + ' a comparison key from each list element: ' + '"key=str.lower". The\n' + ' default value is "None".\n' + '\n' + ' *reverse* is a boolean value. If set to "True", ' + 'then the list\n' + ' elements are sorted as if each comparison were ' + 'reversed.\n' + '\n' + ' In general, the *key* and *reverse* conversion ' + 'processes are much\n' + ' faster than specifying an equivalent *cmp* ' + 'function. This is\n' + ' because *cmp* is called multiple times for each ' + 'list element while\n' + ' *key* and *reverse* touch each element only once. ' + 'Use\n' + ' "functools.cmp_to_key()" to convert an old-style ' + '*cmp* function to\n' + ' a *key* function.\n' + '\n' + ' Changed in version 2.3: Support for "None" as an ' + 'equivalent to\n' + ' omitting *cmp* was added.\n' + '\n' + ' Changed in version 2.4: Support for *key* and ' + '*reverse* was added.\n' + '\n' + '9. Starting with Python 2.3, the "sort()" method is ' + 'guaranteed to\n' + ' be stable. A sort is stable if it guarantees not ' + 'to change the\n' + ' relative order of elements that compare equal --- ' + 'this is helpful\n' + ' for sorting in multiple passes (for example, sort ' + 'by department,\n' + ' then by salary grade).\n' + '\n' + '10. **CPython implementation detail:** While a list is ' + 'being\n' + ' sorted, the effect of attempting to mutate, or ' + 'even inspect, the\n' + ' list is undefined. The C implementation of Python ' + '2.3 and newer\n' + ' makes the list appear empty for the duration, and ' + 'raises\n' + ' "ValueError" if it can detect that the list has ' + 'been mutated\n' + ' during a sort.\n' + '\n' + '11. The value *n* is an integer, or an object ' + 'implementing\n' + ' "__index__()". Zero and negative values of *n* ' + 'clear the\n' + ' sequence. Items in the sequence are not copied; ' + 'they are\n' + ' referenced multiple times, as explained for "s * ' + 'n" under Sequence\n' + ' Types --- str, unicode, list, tuple, bytearray, ' + 'buffer, xrange.\n', + 'unary': '\n' + 'Unary arithmetic and bitwise operations\n' + '***************************************\n' + '\n' + 'All unary arithmetic and bitwise operations have the same ' + 'priority:\n' + '\n' + ' u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n' + '\n' + 'The unary "-" (minus) operator yields the negation of its ' + 'numeric\n' + 'argument.\n' + '\n' + 'The unary "+" (plus) operator yields its numeric argument ' + 'unchanged.\n' + '\n' + 'The unary "~" (invert) operator yields the bitwise inversion of ' + 'its\n' + 'plain or long integer argument. The bitwise inversion of "x" is\n' + 'defined as "-(x+1)". It only applies to integral numbers.\n' + '\n' + 'In all three cases, if the argument does not have the proper ' + 'type, a\n' + '"TypeError" exception is raised.\n', + 'while': '\n' + 'The "while" statement\n' + '*********************\n' + '\n' + 'The "while" statement is used for repeated execution as long as ' + 'an\n' + 'expression is true:\n' + '\n' + ' while_stmt ::= "while" expression ":" suite\n' + ' ["else" ":" suite]\n' + '\n' + 'This repeatedly tests the expression and, if it is true, executes ' + 'the\n' + 'first suite; if the expression is false (which may be the first ' + 'time\n' + 'it is tested) the suite of the "else" clause, if present, is ' + 'executed\n' + 'and the loop terminates.\n' + '\n' + 'A "break" statement executed in the first suite terminates the ' + 'loop\n' + 'without executing the "else" clause\'s suite. A "continue" ' + 'statement\n' + 'executed in the first suite skips the rest of the suite and goes ' + 'back\n' + 'to testing the expression.\n', + 'with': '\n' + 'The "with" statement\n' + '********************\n' + '\n' + 'New in version 2.5.\n' + '\n' + 'The "with" statement is used to wrap the execution of a block ' + 'with\n' + 'methods defined by a context manager (see section With Statement\n' + 'Context Managers). This allows common ' + '"try"..."except"..."finally"\n' + 'usage patterns to be encapsulated for convenient reuse.\n' + '\n' + ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' + ' with_item ::= expression ["as" target]\n' + '\n' + 'The execution of the "with" statement with one "item" proceeds as\n' + 'follows:\n' + '\n' + '1. The context expression (the expression given in the ' + '"with_item")\n' + ' is evaluated to obtain a context manager.\n' + '\n' + '2. The context manager\'s "__exit__()" is loaded for later use.\n' + '\n' + '3. The context manager\'s "__enter__()" method is invoked.\n' + '\n' + '4. If a target was included in the "with" statement, the return\n' + ' value from "__enter__()" is assigned to it.\n' + '\n' + ' Note: The "with" statement guarantees that if the ' + '"__enter__()"\n' + ' method returns without an error, then "__exit__()" will ' + 'always be\n' + ' called. Thus, if an error occurs during the assignment to ' + 'the\n' + ' target list, it will be treated the same as an error ' + 'occurring\n' + ' within the suite would be. See step 6 below.\n' + '\n' + '5. The suite is executed.\n' + '\n' + '6. The context manager\'s "__exit__()" method is invoked. If an\n' + ' exception caused the suite to be exited, its type, value, and\n' + ' traceback are passed as arguments to "__exit__()". Otherwise, ' + 'three\n' + ' "None" arguments are supplied.\n' + '\n' + ' If the suite was exited due to an exception, and the return ' + 'value\n' + ' from the "__exit__()" method was false, the exception is ' + 'reraised.\n' + ' If the return value was true, the exception is suppressed, and\n' + ' execution continues with the statement following the "with"\n' + ' statement.\n' + '\n' + ' If the suite was exited for any reason other than an exception, ' + 'the\n' + ' return value from "__exit__()" is ignored, and execution ' + 'proceeds\n' + ' at the normal location for the kind of exit that was taken.\n' + '\n' + 'With more than one item, the context managers are processed as if\n' + 'multiple "with" statements were nested:\n' + '\n' + ' with A() as a, B() as b:\n' + ' suite\n' + '\n' + 'is equivalent to\n' + '\n' + ' with A() as a:\n' + ' with B() as b:\n' + ' suite\n' + '\n' + 'Note: In Python 2.5, the "with" statement is only allowed when ' + 'the\n' + ' "with_statement" feature has been enabled. It is always enabled ' + 'in\n' + ' Python 2.6.\n' + '\n' + 'Changed in version 2.7: Support for multiple context expressions.\n' + '\n' + 'See also: **PEP 0343** - The "with" statement\n' + '\n' + ' The specification, background, and examples for the Python ' + '"with"\n' + ' statement.\n', + 'yield': '\n' + 'The "yield" statement\n' + '*********************\n' + '\n' + ' yield_stmt ::= yield_expression\n' + '\n' + 'The "yield" statement is only used when defining a generator ' + 'function,\n' + 'and is only used in the body of the generator function. Using a\n' + '"yield" statement in a function definition is sufficient to cause ' + 'that\n' + 'definition to create a generator function instead of a normal\n' + 'function.\n' + '\n' + 'When a generator function is called, it returns an iterator known ' + 'as a\n' + 'generator iterator, or more commonly, a generator. The body of ' + 'the\n' + "generator function is executed by calling the generator's " + '"next()"\n' + 'method repeatedly until it raises an exception.\n' + '\n' + 'When a "yield" statement is executed, the state of the generator ' + 'is\n' + 'frozen and the value of "expression_list" is returned to ' + '"next()"\'s\n' + 'caller. By "frozen" we mean that all local state is retained,\n' + 'including the current bindings of local variables, the ' + 'instruction\n' + 'pointer, and the internal evaluation stack: enough information ' + 'is\n' + 'saved so that the next time "next()" is invoked, the function ' + 'can\n' + 'proceed exactly as if the "yield" statement were just another ' + 'external\n' + 'call.\n' + '\n' + 'As of Python version 2.5, the "yield" statement is now allowed in ' + 'the\n' + '"try" clause of a "try" ... "finally" construct. If the ' + 'generator is\n' + 'not resumed before it is finalized (by reaching a zero reference ' + 'count\n' + "or by being garbage collected), the generator-iterator's " + '"close()"\n' + 'method will be called, allowing any pending "finally" clauses to\n' + 'execute.\n' + '\n' + 'For full details of "yield" semantics, refer to the Yield ' + 'expressions\n' + 'section.\n' + '\n' + 'Note: In Python 2.2, the "yield" statement was only allowed when ' + 'the\n' + ' "generators" feature has been enabled. This "__future__" ' + 'import\n' + ' statement was used to enable the feature:\n' + '\n' + ' from __future__ import generators\n' + '\n' + 'See also: **PEP 0255** - Simple Generators\n' + '\n' + ' The proposal for adding generators and the "yield" statement ' + 'to\n' + ' Python.\n' + '\n' + ' **PEP 0342** - Coroutines via Enhanced Generators\n' + ' The proposal that, among other generator enhancements, ' + 'proposed\n' + ' allowing "yield" to appear inside a "try" ... "finally" ' + 'block.\n'} -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 17:09:08 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2015 22:09:08 +0000 Subject: [Python-checkins] =?utf-8?q?release=3A_revert_what_I_suppose_were?= =?utf-8?q?_unintended_changes?= Message-ID: <20151121220908.9718.52072@psf.io> https://hg.python.org/release/rev/cebd02ed3a63 changeset: 100:cebd02ed3a63 user: Benjamin Peterson date: Sat Nov 21 14:09:05 2015 -0800 summary: revert what I suppose were unintended changes files: release.py | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/release.py b/release.py --- a/release.py +++ b/release.py @@ -34,7 +34,7 @@ def run_cmd(args, silent=False): cmd = SPACE.join(args) - if 1: # not silent: + if not silent: print('Executing %s' % cmd) try: if silent: @@ -250,9 +250,9 @@ except OSError: pass - if 1 or tag.is_final: + if tag.is_final: docdist = build_docs() - if 1 or tag.is_final: + if tag.is_final: shutil.copytree(docdist, 'docs') with changed_dir(os.path.join(archivename, 'Doc')): -- Repository URL: https://hg.python.org/release From python-checkins at python.org Sat Nov 21 17:09:08 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2015 22:09:08 +0000 Subject: [Python-checkins] =?utf-8?q?release=3A_use_python3_builtin_virtua?= =?utf-8?q?lenvs?= Message-ID: <20151121220908.22169.4158@psf.io> https://hg.python.org/release/rev/94572be8a1a2 changeset: 99:94572be8a1a2 user: Benjamin Peterson date: Sat Nov 21 14:08:38 2015 -0800 summary: use python3 builtin virtualenvs files: release.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/release.py b/release.py --- a/release.py +++ b/release.py @@ -281,7 +281,7 @@ """Build and tarball the documentation""" print("Building docs") with tempfile.TemporaryDirectory() as venv: - run_cmd(['virtualenv', venv]) + run_cmd(['python3', '-m', 'venv', venv]) pip = os.path.join(venv, 'bin', 'pip') run_cmd([pip, 'install', 'Sphinx==1.2.3']) # run_cmd([pip, 'install', 'Sphinx']) -- Repository URL: https://hg.python.org/release From python-checkins at python.org Sat Nov 21 17:14:12 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2015 22:14:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Added_tag_v2?= =?utf-8?q?=2E7=2E11rc1_for_changeset_82dd9545bd93?= Message-ID: <20151121221412.9712.8669@psf.io> https://hg.python.org/cpython/rev/0ed9ac28deb0 changeset: 99274:0ed9ac28deb0 branch: 2.7 user: Benjamin Peterson date: Sat Nov 21 13:38:43 2015 -0800 summary: Added tag v2.7.11rc1 for changeset 82dd9545bd93 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -170,3 +170,4 @@ 648dcafa7e5f40da31079bc7a7f0c445f1ea4ab9 v2.7.9 80ccce248ba2657ed5da3ccf7999f35b78827f5e v2.7.10rc1 15c95b7d81dcf821daade360741e00714667653f v2.7.10 +82dd9545bd93d6e7a9821e1dabc7b25508d0fa3a v2.7.11rc1 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 17:14:13 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sat, 21 Nov 2015 22:14:13 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogYnVtcCB0byAyLjcu?= =?utf-8?q?11rc1?= Message-ID: <20151121221412.130857.35332@psf.io> https://hg.python.org/cpython/rev/82dd9545bd93 changeset: 99273:82dd9545bd93 branch: 2.7 tag: v2.7.11rc1 user: Benjamin Peterson date: Sat Nov 21 13:38:35 2015 -0800 summary: bump to 2.7.11rc1 files: Include/patchlevel.h | 8 ++++---- Misc/NEWS | 8 ++++---- README | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -22,12 +22,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 2 #define PY_MINOR_VERSION 7 -#define PY_MICRO_VERSION 10 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL -#define PY_RELEASE_SERIAL 0 +#define PY_MICRO_VERSION 11 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7.10+" +#define PY_VERSION "2.7.11rc1" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,10 +2,10 @@ Python News +++++++++++ -What's New in Python 2.7.11? -============================ - -*Release date: XXXX-XX-XX* +What's New in Python 2.7.11 release candidate 1? +================================================ + +*Release date: 2015-11-21* Core and Builtins ----------------- diff --git a/README b/README --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is Python version 2.7.10 +This is Python version 2.7.11 ============================= Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 17:56:49 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 22:56:49 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325689=3A_Merge_ftplib_and_nntplib_docs_from_3=2E4_int?= =?utf-8?q?o_3=2E5?= Message-ID: <20151121225648.38225.13286@psf.io> https://hg.python.org/cpython/rev/2fa12e53e8f3 changeset: 99276:2fa12e53e8f3 branch: 3.5 parent: 99270:a70281b5d076 parent: 99275:74111e62a76c user: Martin Panter date: Sat Nov 21 22:48:54 2015 +0000 summary: Issue #25689: Merge ftplib and nntplib docs from 3.4 into 3.5 files: Doc/library/ftplib.rst | 3 +-- Doc/library/nntplib.rst | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -52,8 +52,7 @@ will be used). *source_address* is a 2-tuple ``(host, port)`` for the socket to bind to as its source address before connecting. - :class:`FTP` class supports the :keyword:`with` statement. Here is a sample - on how using it: + The :class:`FTP` class supports the :keyword:`with` statement, e.g.: >>> from ftplib import FTP >>> with FTP("ftp1.at.proftpd.org") as ftp: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -69,9 +69,9 @@ connecting to an NNTP server on the local machine and intend to call reader-specific commands, such as ``group``. If you get unexpected :exc:`NNTPPermanentError`\ s, you might need to set *readermode*. - :class:`NNTP` class supports the :keyword:`with` statement to + The :class:`NNTP` class supports the :keyword:`with` statement to unconditionally consume :exc:`OSError` exceptions and to close the NNTP - connection when done. Here is a sample on how using it: + connection when done, e.g.: >>> from nntplib import NNTP >>> with NNTP('news.gmane.org') as n: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 17:56:49 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 22:56:49 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325689=3A_Merge_ftplib_and_nntplib_docs_from_3?= =?utf-8?q?=2E5?= Message-ID: <20151121225648.38241.849@psf.io> https://hg.python.org/cpython/rev/b99a30383bd5 changeset: 99277:b99a30383bd5 parent: 99271:2e1a9e327859 parent: 99276:2fa12e53e8f3 user: Martin Panter date: Sat Nov 21 22:49:06 2015 +0000 summary: Issue #25689: Merge ftplib and nntplib docs from 3.5 files: Doc/library/ftplib.rst | 3 +-- Doc/library/nntplib.rst | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -52,8 +52,7 @@ will be used). *source_address* is a 2-tuple ``(host, port)`` for the socket to bind to as its source address before connecting. - :class:`FTP` class supports the :keyword:`with` statement. Here is a sample - on how using it: + The :class:`FTP` class supports the :keyword:`with` statement, e.g.: >>> from ftplib import FTP >>> with FTP("ftp1.at.proftpd.org") as ftp: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -69,9 +69,9 @@ connecting to an NNTP server on the local machine and intend to call reader-specific commands, such as ``group``. If you get unexpected :exc:`NNTPPermanentError`\ s, you might need to set *readermode*. - :class:`NNTP` class supports the :keyword:`with` statement to + The :class:`NNTP` class supports the :keyword:`with` statement to unconditionally consume :exc:`OSError` exceptions and to close the NNTP - connection when done. Here is a sample on how using it: + connection when done, e.g.: >>> from nntplib import NNTP >>> with NNTP('news.gmane.org') as n: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 17:56:49 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 21 Nov 2015 22:56:49 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Njg5?= =?utf-8?q?=3A_Fix_language_in_ftplib_and_nntplib_docs?= Message-ID: <20151121225648.130853.85814@psf.io> https://hg.python.org/cpython/rev/74111e62a76c changeset: 99275:74111e62a76c branch: 3.4 parent: 99269:5f9c7162c04d user: Martin Panter date: Sat Nov 21 22:03:08 2015 +0000 summary: Issue #25689: Fix language in ftplib and nntplib docs Original patch by Silent Ghost. files: Doc/library/ftplib.rst | 3 +-- Doc/library/nntplib.rst | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/ftplib.rst b/Doc/library/ftplib.rst --- a/Doc/library/ftplib.rst +++ b/Doc/library/ftplib.rst @@ -52,8 +52,7 @@ will be used). *source_address* is a 2-tuple ``(host, port)`` for the socket to bind to as its source address before connecting. - :class:`FTP` class supports the :keyword:`with` statement. Here is a sample - on how using it: + The :class:`FTP` class supports the :keyword:`with` statement, e.g.: >>> from ftplib import FTP >>> with FTP("ftp1.at.proftpd.org") as ftp: diff --git a/Doc/library/nntplib.rst b/Doc/library/nntplib.rst --- a/Doc/library/nntplib.rst +++ b/Doc/library/nntplib.rst @@ -69,9 +69,9 @@ connecting to an NNTP server on the local machine and intend to call reader-specific commands, such as ``group``. If you get unexpected :exc:`NNTPPermanentError`\ s, you might need to set *readermode*. - :class:`NNTP` class supports the :keyword:`with` statement to + The :class:`NNTP` class supports the :keyword:`with` statement to unconditionally consume :exc:`OSError` exceptions and to close the NNTP - connection when done. Here is a sample on how using it: + connection when done, e.g.: >>> from nntplib import NNTP >>> with NNTP('news.gmane.org') as n: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 20:05:03 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 22 Nov 2015 01:05:03 +0000 Subject: [Python-checkins] =?utf-8?q?release=3A_fix_for_two_digit_bug_fix_?= =?utf-8?q?releases?= Message-ID: <20151122010503.15091.65185@psf.io> https://hg.python.org/release/rev/bed4ccea4d9f changeset: 101:bed4ccea4d9f user: Benjamin Peterson date: Sat Nov 21 17:03:31 2015 -0800 summary: fix for two digit bug fix releases files: add-to-pydotorg.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/add-to-pydotorg.py b/add-to-pydotorg.py --- a/add-to-pydotorg.py +++ b/add-to-pydotorg.py @@ -83,7 +83,7 @@ return 'http://hg.python.org/cpython/file/v%s/Misc/NEWS' % release def slug_for(release): - return release[0] + '-' + release[2] + '-' + release[4] + \ + return base_version(release).replace(".", "") + \ ('-' + release[len(base_version(release)):] if release[len(base_version(release)):] else '') def sigfile_for(release, rfile): -- Repository URL: https://hg.python.org/release From python-checkins at python.org Sat Nov 21 21:39:12 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 22 Nov 2015 02:39:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_post_rc1_updat?= =?utf-8?q?es?= Message-ID: <20151122023912.3558.13025@psf.io> https://hg.python.org/cpython/rev/4f61b62bc09d changeset: 99278:4f61b62bc09d branch: 2.7 parent: 99274:0ed9ac28deb0 user: Benjamin Peterson date: Sat Nov 21 18:38:18 2015 -0800 summary: post rc1 updates files: Include/patchlevel.h | 2 +- Misc/NEWS | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -27,7 +27,7 @@ #define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "2.7.11rc1" +#define PY_VERSION "2.7.11rc1+" /*--end constants--*/ /* Subversion Revision number of this file (not of the repository). Empty diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,18 @@ Python News +++++++++++ +What's New in Python 2.7.11? +============================ + +*Release date: 2015-12-05* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 2.7.11 release candidate 1? ================================================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 21 21:39:18 2015 From: python-checkins at python.org (benjamin.peterson) Date: Sun, 22 Nov 2015 02:39:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_news_section_f?= =?utf-8?b?b3IgMi43LjEy?= Message-ID: <20151122023912.21507.15486@psf.io> https://hg.python.org/cpython/rev/fd47601145dd changeset: 99279:fd47601145dd branch: 2.7 user: Benjamin Peterson date: Sat Nov 21 18:39:07 2015 -0800 summary: news section for 2.7.12 files: Misc/NEWS | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,18 @@ Python News +++++++++++ +What's New in Python 2.7.12? +============================ + +*Release date: XXXX-XX-XX* + +Core and Builtins +----------------- + +Library +------- + + What's New in Python 2.7.11? ============================ -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sun Nov 22 03:43:46 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 22 Nov 2015 08:43:46 +0000 Subject: [Python-checkins] Daily reference leaks (b99a30383bd5): sum=4 Message-ID: <20151122084345.38215.45640@psf.io> results for b99a30383bd5 on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogkPVZis', '--timeout', '7200'] From python-checkins at python.org Sun Nov 22 05:31:43 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 10:31:43 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2319687=3A_Fixed_memory_leak_on_failed_Element_sl?= =?utf-8?q?ice_assignment=2E?= Message-ID: <20151122103143.20264.59189@psf.io> https://hg.python.org/cpython/rev/de5a11836ad4 changeset: 99282:de5a11836ad4 parent: 99277:b99a30383bd5 parent: 99281:4d5417444961 user: Serhiy Storchaka date: Sun Nov 22 12:30:54 2015 +0200 summary: Issue #19687: Fixed memory leak on failed Element slice assignment. Added new tests for Element slice assignments. files: Lib/test/test_xml_etree.py | 75 ++++++++++++++++++++++++++ Modules/_elementtree.c | 36 +++++------- 2 files changed, 90 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2350,6 +2350,7 @@ self.assertEqual(e[-2].tag, 'a8') self.assertRaises(IndexError, lambda: e[12]) + self.assertRaises(IndexError, lambda: e[-12]) def test_getslice_range(self): e = self._make_elem_with_children(6) @@ -2368,12 +2369,17 @@ self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9']) self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8']) self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3']) def test_getslice_negative_steps(self): e = self._make_elem_with_children(4) self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0']) self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3']) def test_delslice(self): e = self._make_elem_with_children(4) @@ -2400,6 +2406,75 @@ del e[::2] self.assertEqual(self._subelem_tags(e), ['a1']) + def test_setslice_single_index(self): + e = self._make_elem_with_children(4) + e[1] = ET.Element('b') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + + e[-2] = ET.Element('c') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + with self.assertRaises(IndexError): + e[5] = ET.Element('d') + with self.assertRaises(IndexError): + e[-5] = ET.Element('d') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + def test_setslice_range(self): + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(3)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3']) + + def test_setslice_steps(self): + e = self._make_elem_with_children(6) + e[1:5:2] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5']) + + e = self._make_elem_with_children(6) + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[1:5:2] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + + e = self._make_elem_with_children(4) + e[1::sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::sys.maxsize<<64] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + + def test_setslice_negative_steps(self): + e = self._make_elem_with_children(4) + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3']) + + e = self._make_elem_with_children(4) + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[2:0:-1] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3']) + + e = self._make_elem_with_children(4) + e[1::-sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::-sys.maxsize-1] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + e[1::-sys.maxsize<<64] = [ET.Element('d')] + self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3']) + class IOTest(unittest.TestCase): def tearDown(self): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1711,7 +1711,7 @@ Py_ssize_t start, stop, step, slicelen, newlen, cur, i; PyObject* recycle = NULL; - PyObject* seq = NULL; + PyObject* seq; if (!self->extra) { if (create_extra(self, NULL) < 0) @@ -1790,21 +1790,21 @@ Py_XDECREF(recycle); return 0; } - else { - /* A new slice is actually being assigned */ - seq = PySequence_Fast(value, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name - ); - return -1; - } - newlen = PySequence_Size(seq); + + /* A new slice is actually being assigned */ + seq = PySequence_Fast(value, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + ); + return -1; } + newlen = PySequence_Size(seq); if (step != 1 && newlen != slicelen) { + Py_DECREF(seq); PyErr_Format(PyExc_ValueError, "attempt to assign sequence of size %zd " "to extended slice of size %zd", @@ -1816,9 +1816,7 @@ /* Resize before creating the recycle bin, to prevent refleaks. */ if (newlen > slicelen) { if (element_resize(self, newlen - slicelen) < 0) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } } @@ -1829,9 +1827,7 @@ we're done modifying the element */ recycle = PyList_New(slicelen); if (!recycle) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } for (cur = start, i = 0; i < slicelen; @@ -1859,9 +1855,7 @@ self->extra->length += newlen - slicelen; - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); /* discard the recycle bin, and everything in it */ Py_XDECREF(recycle); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 05:31:43 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 10:31:43 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzE5Njg3?= =?utf-8?q?=3A_Fixed_memory_leak_on_failed_Element_slice_assignment=2E?= Message-ID: <20151122103143.38235.61949@psf.io> https://hg.python.org/cpython/rev/d51d420f3e9d changeset: 99280:d51d420f3e9d branch: 3.4 parent: 99275:74111e62a76c user: Serhiy Storchaka date: Sun Nov 22 12:18:38 2015 +0200 summary: Issue #19687: Fixed memory leak on failed Element slice assignment. Added new tests for Element slice assignments. files: Lib/test/test_xml_etree.py | 75 ++++++++++++++++++++++++++ Modules/_elementtree.c | 36 +++++------- 2 files changed, 90 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2350,6 +2350,7 @@ self.assertEqual(e[-2].tag, 'a8') self.assertRaises(IndexError, lambda: e[12]) + self.assertRaises(IndexError, lambda: e[-12]) def test_getslice_range(self): e = self._make_elem_with_children(6) @@ -2368,12 +2369,17 @@ self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9']) self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8']) self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3']) def test_getslice_negative_steps(self): e = self._make_elem_with_children(4) self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0']) self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3']) def test_delslice(self): e = self._make_elem_with_children(4) @@ -2400,6 +2406,75 @@ del e[::2] self.assertEqual(self._subelem_tags(e), ['a1']) + def test_setslice_single_index(self): + e = self._make_elem_with_children(4) + e[1] = ET.Element('b') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + + e[-2] = ET.Element('c') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + with self.assertRaises(IndexError): + e[5] = ET.Element('d') + with self.assertRaises(IndexError): + e[-5] = ET.Element('d') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + def test_setslice_range(self): + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(3)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3']) + + def test_setslice_steps(self): + e = self._make_elem_with_children(6) + e[1:5:2] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5']) + + e = self._make_elem_with_children(6) + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[1:5:2] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + + e = self._make_elem_with_children(4) + e[1::sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::sys.maxsize<<64] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + + def test_setslice_negative_steps(self): + e = self._make_elem_with_children(4) + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3']) + + e = self._make_elem_with_children(4) + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[2:0:-1] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3']) + + e = self._make_elem_with_children(4) + e[1::-sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::-sys.maxsize-1] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + e[1::-sys.maxsize<<64] = [ET.Element('d')] + self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3']) + class IOTest(unittest.TestCase): def tearDown(self): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1605,7 +1605,7 @@ Py_ssize_t start, stop, step, slicelen, newlen, cur, i; PyObject* recycle = NULL; - PyObject* seq = NULL; + PyObject* seq; if (!self->extra) { if (create_extra(self, NULL) < 0) @@ -1684,21 +1684,21 @@ Py_XDECREF(recycle); return 0; } - else { - /* A new slice is actually being assigned */ - seq = PySequence_Fast(value, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name - ); - return -1; - } - newlen = PySequence_Size(seq); + + /* A new slice is actually being assigned */ + seq = PySequence_Fast(value, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + ); + return -1; } + newlen = PySequence_Size(seq); if (step != 1 && newlen != slicelen) { + Py_DECREF(seq); PyErr_Format(PyExc_ValueError, "attempt to assign sequence of size %zd " "to extended slice of size %zd", @@ -1710,9 +1710,7 @@ /* Resize before creating the recycle bin, to prevent refleaks. */ if (newlen > slicelen) { if (element_resize(self, newlen - slicelen) < 0) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } } @@ -1723,9 +1721,7 @@ we're done modifying the element */ recycle = PyList_New(slicelen); if (!recycle) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } for (cur = start, i = 0; i < slicelen; @@ -1753,9 +1749,7 @@ self->extra->length += newlen - slicelen; - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); /* discard the recycle bin, and everything in it */ Py_XDECREF(recycle); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 05:31:43 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 10:31:43 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2319687=3A_Fixed_memory_leak_on_failed_Element_slice_as?= =?utf-8?q?signment=2E?= Message-ID: <20151122103143.9697.96550@psf.io> https://hg.python.org/cpython/rev/4d5417444961 changeset: 99281:4d5417444961 branch: 3.5 parent: 99276:2fa12e53e8f3 parent: 99280:d51d420f3e9d user: Serhiy Storchaka date: Sun Nov 22 12:30:28 2015 +0200 summary: Issue #19687: Fixed memory leak on failed Element slice assignment. Added new tests for Element slice assignments. files: Lib/test/test_xml_etree.py | 75 ++++++++++++++++++++++++++ Modules/_elementtree.c | 36 +++++------- 2 files changed, 90 insertions(+), 21 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -2350,6 +2350,7 @@ self.assertEqual(e[-2].tag, 'a8') self.assertRaises(IndexError, lambda: e[12]) + self.assertRaises(IndexError, lambda: e[-12]) def test_getslice_range(self): e = self._make_elem_with_children(6) @@ -2368,12 +2369,17 @@ self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9']) self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8']) self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3']) def test_getslice_negative_steps(self): e = self._make_elem_with_children(4) self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0']) self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3']) def test_delslice(self): e = self._make_elem_with_children(4) @@ -2400,6 +2406,75 @@ del e[::2] self.assertEqual(self._subelem_tags(e), ['a1']) + def test_setslice_single_index(self): + e = self._make_elem_with_children(4) + e[1] = ET.Element('b') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + + e[-2] = ET.Element('c') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + with self.assertRaises(IndexError): + e[5] = ET.Element('d') + with self.assertRaises(IndexError): + e[-5] = ET.Element('d') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + def test_setslice_range(self): + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(3)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3']) + + def test_setslice_steps(self): + e = self._make_elem_with_children(6) + e[1:5:2] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5']) + + e = self._make_elem_with_children(6) + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[1:5:2] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + + e = self._make_elem_with_children(4) + e[1::sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::sys.maxsize<<64] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + + def test_setslice_negative_steps(self): + e = self._make_elem_with_children(4) + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3']) + + e = self._make_elem_with_children(4) + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[2:0:-1] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3']) + + e = self._make_elem_with_children(4) + e[1::-sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::-sys.maxsize-1] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + e[1::-sys.maxsize<<64] = [ET.Element('d')] + self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3']) + class IOTest(unittest.TestCase): def tearDown(self): diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1711,7 +1711,7 @@ Py_ssize_t start, stop, step, slicelen, newlen, cur, i; PyObject* recycle = NULL; - PyObject* seq = NULL; + PyObject* seq; if (!self->extra) { if (create_extra(self, NULL) < 0) @@ -1790,21 +1790,21 @@ Py_XDECREF(recycle); return 0; } - else { - /* A new slice is actually being assigned */ - seq = PySequence_Fast(value, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name - ); - return -1; - } - newlen = PySequence_Size(seq); + + /* A new slice is actually being assigned */ + seq = PySequence_Fast(value, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + ); + return -1; } + newlen = PySequence_Size(seq); if (step != 1 && newlen != slicelen) { + Py_DECREF(seq); PyErr_Format(PyExc_ValueError, "attempt to assign sequence of size %zd " "to extended slice of size %zd", @@ -1816,9 +1816,7 @@ /* Resize before creating the recycle bin, to prevent refleaks. */ if (newlen > slicelen) { if (element_resize(self, newlen - slicelen) < 0) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } } @@ -1829,9 +1827,7 @@ we're done modifying the element */ recycle = PyList_New(slicelen); if (!recycle) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } for (cur = start, i = 0; i < slicelen; @@ -1859,9 +1855,7 @@ self->extra->length += newlen - slicelen; - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); /* discard the recycle bin, and everything in it */ Py_XDECREF(recycle); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 05:31:44 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 10:31:44 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzE5Njg3?= =?utf-8?q?=3A_Fixed_memory_leak_on_failed_Element_slice_assignment=2E?= Message-ID: <20151122103143.127570.22135@psf.io> https://hg.python.org/cpython/rev/c33e4881721f changeset: 99283:c33e4881721f branch: 2.7 parent: 99279:fd47601145dd user: Serhiy Storchaka date: Sun Nov 22 12:31:11 2015 +0200 summary: Issue #19687: Fixed memory leak on failed Element slice assignment. files: Modules/_elementtree.c | 16 ++++++---------- 1 files changed, 6 insertions(+), 10 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1390,15 +1390,17 @@ if (step != 1 && newlen != slicelen) { + Py_XDECREF(seq); PyErr_Format(PyExc_ValueError, #if (PY_VERSION_HEX < 0x02050000) "attempt to assign sequence of size %d " "to extended slice of size %d", + (int)newlen, (int)slicelen #else "attempt to assign sequence of size %zd " "to extended slice of size %zd", + newlen, slicelen #endif - newlen, slicelen ); return -1; } @@ -1407,9 +1409,7 @@ /* Resize before creating the recycle bin, to prevent refleaks. */ if (newlen > slicelen) { if (element_resize(self, newlen - slicelen) < 0) { - if (seq) { - Py_DECREF(seq); - } + Py_XDECREF(seq); return -1; } } @@ -1420,9 +1420,7 @@ we're done modifying the element */ recycle = PyList_New(slicelen); if (!recycle) { - if (seq) { - Py_DECREF(seq); - } + Py_XDECREF(seq); return -1; } for (cur = start, i = 0; i < slicelen; @@ -1450,9 +1448,7 @@ self->extra->length += newlen - slicelen; - if (seq) { - Py_DECREF(seq); - } + Py_XDECREF(seq); /* discard the recycle bin, and everything in it */ Py_XDECREF(recycle); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 07:56:52 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 12:56:52 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjI0?= =?utf-8?q?=3A_ZipFile_now_always_writes_a_ZIP=5FSTORED_header_for_directo?= =?utf-8?q?ry?= Message-ID: <20151122125652.9718.19277@psf.io> https://hg.python.org/cpython/rev/e7d1df56f70b changeset: 99284:e7d1df56f70b branch: 3.4 parent: 99280:d51d420f3e9d user: Serhiy Storchaka date: Sun Nov 22 14:49:58 2015 +0200 summary: Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. files: Lib/test/test_shutil.py | 23 +++++++++++++++++++++++ Lib/zipfile.py | 4 +++- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1099,6 +1099,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @requires_zlib + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(shutil.which('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output.decode(errors="replace") + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1337,7 +1337,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16 # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1471,6 +1471,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + - Issue #25583: Avoid incorrect errors raised by os.makedirs(exist_ok=True) when the OS gives priority to errors such as EACCES over EEXIST. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 07:56:52 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 12:56:52 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325624=3A_ZipFile_now_always_writes_a_ZIP=5FSTOR?= =?utf-8?q?ED_header_for_directory?= Message-ID: <20151122125652.21515.93754@psf.io> https://hg.python.org/cpython/rev/09ed44192995 changeset: 99286:09ed44192995 parent: 99282:de5a11836ad4 parent: 99285:0f8d426e0d0c user: Serhiy Storchaka date: Sun Nov 22 14:50:59 2015 +0200 summary: Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. files: Lib/test/test_shutil.py | 23 +++++++++++++++++++++++ Lib/zipfile.py | 4 +++- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1105,6 +1105,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @requires_zlib + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(shutil.which('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output.decode(errors="replace") + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1444,7 +1444,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16 # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1522,6 +1522,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + - Issue #25626: Change three zlib functions to accept sizes that fit in Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 07:56:52 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 12:56:52 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjI0?= =?utf-8?q?=3A_ZipFile_now_always_writes_a_ZIP=5FSTORED_header_for_directo?= =?utf-8?q?ry?= Message-ID: <20151122125652.15089.6311@psf.io> https://hg.python.org/cpython/rev/de5582c569ff changeset: 99287:de5582c569ff branch: 2.7 parent: 99283:c33e4881721f user: Serhiy Storchaka date: Sun Nov 22 14:56:22 2015 +0200 summary: Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. files: Lib/test/test_shutil.py | 23 +++++++++++++++++++++++ Lib/zipfile.py | 4 +++- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -511,6 +511,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @unittest.skipUnless(zlib, "Requires zlib") + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(find_executable('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1134,7 +1134,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1443,6 +1443,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + What's New in Python 2.7.11? ============================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 07:56:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 22 Nov 2015 12:56:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325624=3A_ZipFile_now_always_writes_a_ZIP=5FSTORED_hea?= =?utf-8?q?der_for_directory?= Message-ID: <20151122125652.38233.10716@psf.io> https://hg.python.org/cpython/rev/0f8d426e0d0c changeset: 99285:0f8d426e0d0c branch: 3.5 parent: 99281:4d5417444961 parent: 99284:e7d1df56f70b user: Serhiy Storchaka date: Sun Nov 22 14:50:25 2015 +0200 summary: Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. files: Lib/test/test_shutil.py | 23 +++++++++++++++++++++++ Lib/zipfile.py | 4 +++- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1105,6 +1105,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @requires_zlib + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(shutil.which('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output.decode(errors="replace") + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1444,7 +1444,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16 # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1518,6 +1518,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -77,6 +77,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + - Issue #25626: Change three zlib functions to accept sizes that fit in Py_ssize_t, but internally cap those sizes to UINT_MAX. This resolves a regression in 3.5 where GzipFile.read() failed to read chunks larger than 2 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 09:45:14 2015 From: python-checkins at python.org (victor.stinner) Date: Sun, 22 Nov 2015 14:45:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325694=3A_Install_?= =?utf-8?q?test=2Elibregrtest_to_be_able_to_run_tests_on_the_installed?= Message-ID: <20151122144513.130845.13576@psf.io> https://hg.python.org/cpython/rev/1f563b259f09 changeset: 99288:1f563b259f09 parent: 99286:09ed44192995 user: Victor Stinner date: Sun Nov 22 15:18:40 2015 +0100 summary: Issue #25694: Install test.libregrtest to be able to run tests on the installed Python files: Makefile.pre.in | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1167,6 +1167,7 @@ test/cjkencodings test/decimaltestdata test/xmltestdata \ test/eintrdata \ test/imghdrdata \ + test/libregrtest \ test/subprocessdata test/sndhdrdata test/support \ test/tracedmodules test/encoded_modules \ test/test_import \ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 09:45:14 2015 From: python-checkins at python.org (victor.stinner) Date: Sun, 22 Nov 2015 14:45:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325694=3A_Fix_test?= =?utf-8?q?=5Fregrtest_for_installed_Python?= Message-ID: <20151122144513.127578.18016@psf.io> https://hg.python.org/cpython/rev/fea86d0049d2 changeset: 99289:fea86d0049d2 user: Victor Stinner date: Sun Nov 22 15:18:54 2015 +0100 summary: Issue #25694: Fix test_regrtest for installed Python files: Lib/test/test_regrtest.py | 20 +++++++++++++++----- 1 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -14,6 +14,7 @@ import re import subprocess import sys +import sysconfig import textwrap import unittest from test import libregrtest @@ -306,7 +307,7 @@ TESTNAME_REGEX = r'test_[a-z0-9_]+' def setUp(self): - self.testdir = os.path.join(ROOT_DIR, 'Lib', 'test') + self.testdir = os.path.realpath(os.path.dirname(__file__)) # When test_regrtest is interrupted by CTRL+c, it can leave # temporary test files @@ -330,8 +331,13 @@ self.addCleanup(support.unlink, path) # Use 'x' mode to ensure that we do not override existing tests - with open(path, 'x', encoding='utf-8') as fp: - fp.write(code) + try: + with open(path, 'x', encoding='utf-8') as fp: + fp.write(code) + except PermissionError as exc: + if not sysconfig.is_python_build(): + self.skipTest("cannot write %s: %s" % (path, exc)) + raise return name def regex_search(self, regex, output): @@ -471,7 +477,7 @@ def test_script_regrtest(self): # Lib/test/regrtest.py - script = os.path.join(ROOT_DIR, 'Lib', 'test', 'regrtest.py') + script = os.path.join(self.testdir, 'regrtest.py') args = [*self.python_args, script, *self.regrtest_args, *self.tests] self.run_tests(args) @@ -503,10 +509,12 @@ def test_script_autotest(self): # Lib/test/autotest.py - script = os.path.join(ROOT_DIR, 'Lib', 'test', 'autotest.py') + script = os.path.join(self.testdir, 'autotest.py') args = [*self.python_args, script, *self.regrtest_args, *self.tests] self.run_tests(args) + @unittest.skipUnless(sysconfig.is_python_build(), + 'run_tests.py script is not installed') def test_tools_script_run_tests(self): # Tools/scripts/run_tests.py script = os.path.join(ROOT_DIR, 'Tools', 'scripts', 'run_tests.py') @@ -516,6 +524,8 @@ proc = self.run_command(args) self.check_output(proc.stdout) + @unittest.skipUnless(sysconfig.is_python_build(), + 'test.bat script is not installed') @unittest.skipUnless(sys.platform == 'win32', 'Windows only') def test_tools_buildbot_test(self): # Tools\buildbot\test.bat -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 19:53:54 2015 From: python-checkins at python.org (donald.stufft) Date: Mon, 23 Nov 2015 00:53:54 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_Add_PEP_508_-_Dependency_spec?= =?utf-8?q?ification_for_Python_Software_Packages?= Message-ID: <20151123005354.3562.95640@psf.io> https://hg.python.org/peps/rev/cbb8059be2f9 changeset: 6127:cbb8059be2f9 user: Donald Stufft date: Sun Nov 22 19:53:50 2015 -0500 summary: Add PEP 508 - Dependency specification for Python Software Packages files: pep-0508.txt | 562 +++++++++++++++++++++++++++++++++++++++ 1 files changed, 562 insertions(+), 0 deletions(-) diff --git a/pep-0508.txt b/pep-0508.txt new file mode 100644 --- /dev/null +++ b/pep-0508.txt @@ -0,0 +1,562 @@ +PEP: 508 +Title: Dependency specification for Python Software Packages +Version: $Revision$ +Last-Modified: $Date$ +Author: Robert Collins +BDFL-Delegate: Donald Stufft +Discussions-To: distutils-sig +Status: Accepted +Type: Standards Track +Content-Type: text/x-rst +Created: 11-Nov-2015 +Post-History: 05-Nov-2015, 16-Nov-2015 +Resolution: https://mail.python.org/pipermail/distutils-sig/2015-November/027868.html + + +Abstract +======== + +This PEP specifies the language used to describe dependencies for packages. +It draws a border at the edge of describing a single dependency - the +different sorts of dependencies and when they should be installed is a higher +level problem. The intent is to provide a building block for higher layer +specifications. + +The job of a dependency is to enable tools like pip [#pip]_ to find the right +package to install. Sometimes this is very loose - just specifying a name, and +sometimes very specific - referring to a specific file to install. Sometimes +dependencies are only relevant in one platform, or only some versions are +acceptable, so the language permits describing all these cases. + +The language defined is a compact line based format which is already in +widespread use in pip requirements files, though we do not specify the command +line option handling that those files permit. There is one caveat - the +URL reference form, specified in PEP-440 [#pep440]_ is not actually +implemented in pip, but since PEP-440 is accepted, we use that format rather +than pip's current native format. + +Motivation +========== + +Any specification in the Python packaging ecosystem that needs to consume +lists of dependencies needs to build on an approved PEP for such, but +PEP-426 [#pep426]_ is mostly aspirational - and there are already existing +implementations of the dependency specification which we can instead adopt. +The existing implementations are battle proven and user friendly, so adopting +them is arguably much better than approving an aspirational, unconsumed, format. + +Specification +============= + +Examples +-------- + +All features of the language shown with a name based lookup:: + + requests [security,tests] >= 2.8.1, == 2.8.* ; python_version < "2.7.10" + +A minimal URL based lookup:: + + pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686 + +Concepts +-------- + +A dependency specification always specifies a distribution name. It may +include extras, which expand the dependencies of the named distribution to +enable optional features. The version installed can be controlled using +version limits, or giving the URL to a specific artifact to install. Finally +the dependency can be made conditional using environment markers. + +Grammar +------- + +We first cover the grammar briefly and then drill into the semantics of each +section later. + +A distribution specification is written in ASCII text. We use a parsley +[#parsley]_ grammar to provide a precise grammar. It is expected that the +specification will be embedded into a larger system which offers framing such +as comments, multiple line support via continuations, or other such features. + +The full grammar including annotations to build a useful parse tree is +included at the end of the PEP. + +Versions may be specified according to the PEP-440 [#pep440]_ rules. (Note: +URI is defined in std-66 [#std66]_:: + + version_cmp = wsp* '<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '===' + version = wsp* ( letterOrDigit | '-' | '_' | '.' | '*' | '+' | '!' )+ + version_one = version_cmp version wsp* + version_many = version_one (wsp* ',' version_one)* + versionspec = ( '(' version_many ')' ) | version_many + urlspec = '@' wsp* + +Environment markers allow making a specification only take effect in some +environments:: + + marker_op = version_cmp | (wsp* 'in') | (wsp* 'not' wsp+ 'in') + python_str_c = (wsp | letter | digit | '(' | ')' | '.' | '{' | '}' | + '-' | '_' | '*' | '#' | ':' | ';' | ',' | '/' | '?' | + '[' | ']' | '!' | '~' | '`' | '@' | '$' | '%' | '^' | + '&' | '=' | '+' | '|' | '<' | '>' ) + dquote = '"' + squote = '\\'' + python_str = (squote (python_str_c | dquote)* squote | + dquote (python_str_c | squote)* dquote) + env_var = ('python_version' | 'python_full_version' | + 'os_name' | 'sys_platform' | 'platform_release' | + 'platform_system' | 'platform_version' | + 'platform_machine' | 'python_implementation' | + 'implementation_name' | 'implementation_version' | + 'extra' # ONLY when defined by a containing layer + ) + marker_var = wsp* (env_var | python_str) + marker_expr = marker_var marker_op marker_var + | wsp* '(' marker wsp* ')' + marker_and = marker_expr wsp* 'and' marker_expr + | marker_expr + marker_or = marker_and wsp* 'or' marker_and + | marker_and + marker = marker_or + quoted_marker = ';' wsp* marker + +Optional components of a distribution may be specified using the extras +field:: + + identifier = letterOrDigit ( + letterOrDigit | + (( letterOrDigit | '-' | '_' | '.')* letterOrDigit ) )* + name = identifier + extras_list = identifier (wsp* ',' wsp* identifier)* + extras = '[' wsp* extras_list? wsp* ']' + +Giving us a rule for name based requirements:: + + name_req = name wsp* extras? wsp* versionspec? wsp* quoted_marker? + +And a rule for direct reference specifications:: + + url_req = name wsp* extras? wsp* urlspec wsp+ quoted_marker? + +Leading to the unified rule that can specify a dependency.:: + + specification = wsp* ( url_req | name_req ) wsp* + +Whitespace +---------- + +Non line-breaking whitespace is mostly optional with no semantic meaning. The +sole exception is detecting the end of a URL requirement. + +Names +----- + +Python distribution names are currently defined in PEP-345 [#pep345]_. Names +act as the primary identifier for distributions. They are present in all +dependency specifications, and are sufficient to be a specification on their +own. However, PyPI places strict restrictions on names - they must match a +case insensitive regex or they won't be accepted. Accordingly in this PEP we +limit the acceptable values for identifiers to that regex. A full redefinition +of name may take place in a future metadata PEP. The regex (run with +re.IGNORECASE) is:: + + ^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$ + +Extras +------ + +An extra is an optional part of a distribution. Distributions can specify as +many extras as they wish, and each extra results in the declaration of +additional dependencies of the distribution **when** the extra is used in a +dependency specification. For instance:: + + requests[security] + +Extras union in the dependencies they define with the dependencies of the +distribution they are attached to. The example above would result in requests +being installed, and requests own dependencies, and also any dependencies that +are listed in the "security" extra of requests. + +If multiple extras are listed, all the dependencies are unioned together. + +Versions +-------- + +See PEP-440 [#pep440]_ for more detail on both version numbers and version +comparisons. Version specifications limit the versions of a distribution that +can be used. They only apply to distributions looked up by name, rather than +via a URL. Version comparison are also used in the markers feature. The +optional brackets around a version are present for compatibility with PEP-345 +[#pep345]_ but should not be generated, only accepted. + +Environment Markers +------------------- + +Environment markers allow a dependency specification to provide a rule that +describes when the dependency should be used. For instance, consider a package +that needs argparse. In Python 2.7 argparse is always present. On older Python +versions it has to be installed as a dependency. This can be expressed as so:: + + argparse;python_version<"2.7" + +A marker expression evalutes to either True or False. When it evaluates to +False, the dependency specification should be ignored. + +The marker language is a subset of Python itself, chosen for the ability to +safely evaluate it without running arbitrary code that could become a security +vulnerability. Markers were first standardised in PEP-345 [#pep345]_. This PEP +fixes some issues that were observed in the design described in PEP-426 +[#pep426]_. + +Comparisons in marker expressions are typed by the comparison operator. The + operators that are not in perform the same as they +do for strings in Python. The operators use the PEP-440 +[#pep440]_ version comparison rules when those are defined (that is when both +sides have a valid version specifier). If there is no defined PEP-440 +behaviour and the operator exists in Python, then the operator falls back to +the Python behaviour. Otherwise an error should be raised. e.g. the following +will result in errors:: + + "dog" ~= "fred" + python_version ~= "surprise" + +User supplied constants are always encoded as strings with either ``'`` or +``"`` quote marks. Note that backslash escapes are not defined, but existing +implementations do support them. They are not included in this +specification because they add complexity and there is no observable need for +them today. Similarly we do not define non-ASCII character support: all the +runtime variables we are referencing are expected to be ASCII-only. + +The variables in the marker grammar such as "os_name" resolve to values looked +up in the Python runtime. With the exception of "extra" all values are defined +on all Python versions today - it is an error in the implementation of markers +if a value is not defined. + +Unknown variables must raise an error rather than resulting in a comparison +that evaluates to True or False. + +Variables whose value cannot be calculated on a given Python implementation +should evaluate to ``0`` for versions, and an empty string for all other +variables. + +The "extra" variable is special. It is used by wheels to signal which +specifications apply to a given extra in the wheel ``METADATA`` file, but +since the ``METADATA`` file is based on a draft version of PEP-426, there is +no current specification for this. Regardless, outside of a context where this +special handling is taking place, the "extra" variable should result in an +error like all other unknown variables. + +.. list-table:: + :header-rows: 1 + + * - Marker + - Python equivalent + - Sample values + * - ``os_name`` + - ``os.name`` + - ``posix``, ``java`` + * - ``sys_platform`` + - ``sys.platform`` + - ``linux``, ``linux2``, ``darwin``, ``java1.8.0_51`` (note that "linux" + is from Python3 and "linux2" from Python2) + * - ``platform_machine`` + - ``platform.machine()`` + - ``x86_64`` + * - ``python_implementation`` + - ``platform.python_implementation()`` + - ``CPython``, ``Jython`` + * - ``platform_release`` + - ``platform.release()`` + - ``3.14.1-x86_64-linode39``, ``14.5.0``, ``1.8.0_51`` + * - ``platform_system`` + - ``platform.system()`` + - ``Linux``, ``Windows``, ``Java`` + * - ``platform_version`` + - ``platform.version()`` + - ``#1 SMP Fri Apr 25 13:07:35 EDT 2014`` + ``Java HotSpot(TM) 64-Bit Server VM, 25.51-b03, Oracle Corporation`` + ``Darwin Kernel Version 14.5.0: Wed Jul 29 02:18:53 PDT 2015; root:xnu-2782.40.9~2/RELEASE_X86_64`` + * - ``python_version`` + - ``platform.python_version()[:3]`` + - ``3.4``, ``2.7`` + * - ``python_full_version`` + - ``platform.python_version()`` + - ``3.4.0``, ``3.5.0b1`` + * - ``implementation_name`` + - ``sys.implementation.name`` + - ``cpython`` + * - ``implementation_version`` + - see definition below + - ``3.4.0``, ``3.5.0b1`` + * - ``extra`` + - An error except when defined by the context interpreting the + specification. + - ``test`` + +The ``implementation_version`` marker variable is derived from +``sys.implementation.version``:: + + def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + else: + implementation_version = "0" + +Backwards Compatibility +======================= + +Most of this PEP is already widely deployed and thus offers no compatibility +concerns. + +There are however a few points where the PEP differs from the deployed base. + +Firstly, PEP-440 direct references haven't actually been deployed in the wild, +but they were designed to be compatibly added, and there are no known +obstacles to adding them to pip or other tools that consume the existing +dependency metadata in distributions - particularly since they won't be +permitted to be present in PyPI uploaded distributions anyway. + +Secondly, PEP-426 markers which have had some reasonable deployment, +particularly in wheels and pip, will handle version comparisons with +``python_version`` "2.7.10" differently. Specifically in 426 "2.7.10" is less +than "2.7.9". This backward incompatibility is deliberate. We are also +defining new operators - "~=" and "===", and new variables - +``platform_release``, ``platform_system``, ``implementation_name``, and +``implementation_version`` which are not present in older marker +implementations. The variables will error on those implementations. Users of +both features will need to make a judgement as to when support has become +sufficiently widespread in the ecosystem that using them will not cause +compatibility issues. + +Thirdly, PEP-345 required brackets around version specifiers. In order to +accept PEP-345 dependency specifications, brackets are accepted, but they +should not be generated. + +Rationale +========= + +In order to move forward with any new PEPs that depend on environment markers, +we needed a specification that included them in their modern form. This PEP +brings together all the currently unspecified components into a specified +form. + +The requirement specifier was adopted from the EBNF in the setuptools +pkg_resources documentation, since we wish to avoid depending on a defacto, vs +PEP specified, standard. + +Complete Grammar +================ + +The complete parsley grammar:: + + wsp = ' ' | '\t' + version_cmp = wsp* <'<' | '<=' | '!=' | '==' | '>=' | '>' | '~=' | '==='> + version = wsp* <( letterOrDigit | '-' | '_' | '.' | '*' | '+' | '!' )+> + version_one = version_cmp:op version:v wsp* -> (op, v) + version_many = version_one:v1 (wsp* ',' version_one)*:v2 -> [v1] + v2 + versionspec = ('(' version_many:v ')' ->v) | version_many + urlspec = '@' wsp* + marker_op = version_cmp | (wsp* 'in') | (wsp* 'not' wsp+ 'in') + python_str_c = (wsp | letter | digit | '(' | ')' | '.' | '{' | '}' | + '-' | '_' | '*' | '#' | ':' | ';' | ',' | '/' | '?' | + '[' | ']' | '!' | '~' | '`' | '@' | '$' | '%' | '^' | + '&' | '=' | '+' | '|' | '<' | '>' ) + dquote = '"' + squote = '\\'' + python_str = (squote <(python_str_c | dquote)*>:s squote | + dquote <(python_str_c | squote)*>:s dquote) -> s + env_var = ('python_version' | 'python_full_version' | + 'os_name' | 'sys_platform' | 'platform_release' | + 'platform_system' | 'platform_version' | + 'platform_machine' | 'python_implementation' | + 'implementation_name' | 'implementation_version' | + 'extra' # ONLY when defined by a containing layer + ):varname -> lookup(varname) + marker_var = wsp* (env_var | python_str) + marker_expr = marker_var:l marker_op:o marker_var:r -> (o, l, r) + | wsp* '(' marker:m wsp* ')' -> m + marker_and = marker_expr:l wsp* 'and' marker_expr:r -> ('and', l, r) + | marker_expr:m -> m + marker_or = marker_and:l wsp* 'or' marker_and:r -> ('or', l, r) + | marker_and:m -> m + marker = marker_or + quoted_marker = ';' wsp* marker + identifier = + name = identifier + extras_list = identifier:i (wsp* ',' wsp* identifier)*:ids -> [i] + ids + extras = '[' wsp* extras_list?:e wsp* ']' -> e + name_req = (name:n wsp* extras?:e wsp* versionspec?:v wsp* quoted_marker?:m + -> (n, e or [], v or [], m)) + url_req = (name:n wsp* extras?:e wsp* urlspec:v wsp+ quoted_marker?:m + -> (n, e or [], v, m)) + specification = wsp* ( url_req | name_req ):s wsp* -> s + # The result is a tuple - name, list-of-extras, + # list-of-version-constraints-or-a-url, marker-ast or None + + + URI_reference = + URI = scheme ':' hier_part ('?' query )? ( '#' fragment)? + hier_part = ('//' authority path_abempty) | path_absolute | path_rootless | path_empty + absolute_URI = scheme ':' hier_part ( '?' query )? + relative_ref = relative_part ( '?' query )? ( '#' fragment )? + relative_part = '//' authority path_abempty | path_absolute | path_noscheme | path_empty + scheme = letter ( letter | digit | '+' | '-' | '.')* + authority = ( userinfo '@' )? host ( ':' port )? + userinfo = ( unreserved | pct_encoded | sub_delims | ':')* + host = IP_literal | IPv4address | reg_name + port = digit* + IP_literal = '[' ( IPv6address | IPvFuture) ']' + IPvFuture = 'v' hexdig+ '.' ( unreserved | sub_delims | ':')+ + IPv6address = ( + ( h16 ':'){6} ls32 + | '::' ( h16 ':'){5} ls32 + | ( h16 )? '::' ( h16 ':'){4} ls32 + | ( ( h16 ':')? h16 )? '::' ( h16 ':'){3} ls32 + | ( ( h16 ':'){0,2} h16 )? '::' ( h16 ':'){2} ls32 + | ( ( h16 ':'){0,3} h16 )? '::' h16 ':' ls32 + | ( ( h16 ':'){0,4} h16 )? '::' ls32 + | ( ( h16 ':'){0,5} h16 )? '::' h16 + | ( ( h16 ':'){0,6} h16 )? '::' ) + h16 = hexdig{1,4} + ls32 = ( h16 ':' h16) | IPv4address + IPv4address = dec_octet '.' dec_octet '.' dec_octet '.' Dec_octet + nz = ~'0' digit + dec_octet = ( + digit # 0-9 + | nz digit # 10-99 + | '1' digit{2} # 100-199 + | '2' ('0' | '1' | '2' | '3' | '4') digit # 200-249 + | '25' ('0' | '1' | '2' | '3' | '4' | '5') )# %250-255 + reg_name = ( unreserved | pct_encoded | sub_delims)* + path = ( + path_abempty # begins with '/' or is empty + | path_absolute # begins with '/' but not '//' + | path_noscheme # begins with a non-colon segment + | path_rootless # begins with a segment + | path_empty ) # zero characters + path_abempty = ( '/' segment)* + path_absolute = '/' ( segment_nz ( '/' segment)* )? + path_noscheme = segment_nz_nc ( '/' segment)* + path_rootless = segment_nz ( '/' segment)* + path_empty = pchar{0} + segment = pchar* + segment_nz = pchar+ + segment_nz_nc = ( unreserved | pct_encoded | sub_delims | '@')+ + # non-zero-length segment without any colon ':' + pchar = unreserved | pct_encoded | sub_delims | ':' | '@' + query = ( pchar | '/' | '?')* + fragment = ( pchar | '/' | '?')* + pct_encoded = '%' hexdig + unreserved = letter | digit | '-' | '.' | '_' | '~' + reserved = gen_delims | sub_delims + gen_delims = ':' | '/' | '?' | '#' | '(' | ')?' | '@' + sub_delims = '!' | '$' | '&' | '\\'' | '(' | ')' | '*' | '+' | ',' | ';' | '=' + hexdig = digit | 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'd' | 'D' | 'e' | 'E' | 'f' | 'F' + +A test program - if the grammar is in a string ``grammar``:: + + import os + import sys + import platform + + from parsley import makeGrammar + + grammar = """ + wsp ... + """ + tests = [ + "A", + "aa", + "name", + "name>=3", + "name>=3,<2", + "name [fred,bar] @ http://foo.com ; python_version=='2.7'", + "name[quux, strange];python_version<'2.7' and platform_version=='2'", + "name; os_name=='a' or os_name=='b'", + # Should parse as (a and b) or c + "name; os_name=='a' and os_name=='b' or os_name=='c'", + # Overriding precedence -> a and (b or c) + "name; os_name=='a' and (os_name=='b' or os_name=='c')", + # should parse as a or (b and c) + "name; os_name=='a' or os_name=='b' and os_name=='c'", + # Overriding precedence -> (a or b) and c + "name; (os_name=='a' or os_name=='b') and os_name=='c'", + ] + + def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + bindings = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'python_full_version': platform.python_version(), + 'python_implementation': platform.python_implementation(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + + compiled = makeGrammar(grammar, {'lookup': bindings.__getitem__}) + for test in tests: + parsed = compiled(test).specification() + print("%s -> %s" % (test, parsed)) + +References +========== + +.. [#pip] pip, the recommended installer for Python packages + (http://pip.readthedocs.org/en/stable/) + +.. [#pep345] PEP-345, Python distribution metadata version 1.2. + (https://www.python.org/dev/peps/pep-0345/) + +.. [#pep426] PEP-426, Python distribution metadata. + (https://www.python.org/dev/peps/pep-0426/) + +.. [#pep440] PEP-440, Python distribution metadata. + (https://www.python.org/dev/peps/pep-0440/) + +.. [#std66] The URL specification. + (https://tools.ietf.org/html/rfc3986) + +.. [#parsley] The parsley PEG library. + (https://pypi.python.org/pypi/parsley/) + +Copyright +========= + +This document has been placed in the public domain. + + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + coding: utf-8 + End: -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Sun Nov 22 19:55:17 2015 From: python-checkins at python.org (donald.stufft) Date: Mon, 23 Nov 2015 00:55:17 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_Correct_a_slightly_inaccurate?= =?utf-8?q?_statement?= Message-ID: <20151123005517.127562.39491@psf.io> https://hg.python.org/peps/rev/1fe535b37cf0 changeset: 6128:1fe535b37cf0 user: Donald Stufft date: Sun Nov 22 19:55:14 2015 -0500 summary: Correct a slightly inaccurate statement files: pep-0508.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/pep-0508.txt b/pep-0508.txt --- a/pep-0508.txt +++ b/pep-0508.txt @@ -203,7 +203,7 @@ A marker expression evalutes to either True or False. When it evaluates to False, the dependency specification should be ignored. -The marker language is a subset of Python itself, chosen for the ability to +The marker language is inspired by Python itself, chosen for the ability to safely evaluate it without running arbitrary code that could become a security vulnerability. Markers were first standardised in PEP-345 [#pep345]_. This PEP fixes some issues that were observed in the design described in PEP-426 -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Sun Nov 22 21:21:36 2015 From: python-checkins at python.org (steve.dower) Date: Mon, 23 Nov 2015 02:21:36 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fixes_upload_d?= =?utf-8?q?irectories_for_Windows_installer=2E?= Message-ID: <20151123022135.127562.62881@psf.io> https://hg.python.org/cpython/rev/8db7523a13ea changeset: 99290:8db7523a13ea branch: 3.5 parent: 99285:0f8d426e0d0c user: Steve Dower date: Sun Nov 22 18:20:11 2015 -0800 summary: Fixes upload directories for Windows installer. files: Tools/msi/bundle/bundle.targets | 2 +- Tools/msi/uploadrelease.proj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -18,7 +18,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi} - $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseName)`).Replace(`{msi}`, `{2}`)) + $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, `{2}`)) $(DefineConstants);DownloadUrl={2} diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -16,7 +16,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) - $(DownloadUrl.TrimEnd(`/`)) + $(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, ``).TrimEnd(`/`)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 21:21:36 2015 From: python-checkins at python.org (steve.dower) Date: Mon, 23 Nov 2015 02:21:36 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_from_3=2E5?= Message-ID: <20151123022135.130861.47421@psf.io> https://hg.python.org/cpython/rev/2662099d477e changeset: 99291:2662099d477e parent: 99289:fea86d0049d2 parent: 99290:8db7523a13ea user: Steve Dower date: Sun Nov 22 18:20:37 2015 -0800 summary: Merge from 3.5 files: Tools/msi/bundle/bundle.targets | 2 +- Tools/msi/uploadrelease.proj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -18,7 +18,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi} - $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseName)`).Replace(`{msi}`, `{2}`)) + $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, `{2}`)) $(DefineConstants);DownloadUrl={2} diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -16,7 +16,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) - $(DownloadUrl.TrimEnd(`/`)) + $(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, ``).TrimEnd(`/`)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 22:05:35 2015 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 23 Nov 2015 03:05:35 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_rm_duplicate_e?= =?utf-8?q?ntry?= Message-ID: <20151123030535.3548.43123@psf.io> https://hg.python.org/cpython/rev/94da1d00000b changeset: 99294:94da1d00000b branch: 2.7 user: Benjamin Peterson date: Sun Nov 22 19:05:29 2015 -0800 summary: rm duplicate entry files: Misc/NEWS | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,9 +13,6 @@ Library ------- -- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory - entries. Patch by Dingyuan Wang. - What's New in Python 2.7.11? ============================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 22:05:35 2015 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 23 Nov 2015 03:05:35 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjI0?= =?utf-8?q?=3A_ZipFile_now_always_writes_a_ZIP=5FSTORED_header_for_directo?= =?utf-8?q?ry?= Message-ID: <20151123030535.38235.77611@psf.io> https://hg.python.org/cpython/rev/43208b0f2535 changeset: 99292:43208b0f2535 branch: 2.7 parent: 99278:4f61b62bc09d user: Benjamin Peterson date: Sun Nov 22 19:04:56 2015 -0800 summary: Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. files: Lib/test/test_shutil.py | 23 +++++++++++++++++++++++ Lib/zipfile.py | 4 +++- Misc/ACKS | 1 + Misc/NEWS | 3 +++ 4 files changed, 30 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -511,6 +511,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @unittest.skipUnless(zlib, "Requires zlib") + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(find_executable('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1134,7 +1134,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16L # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1443,6 +1443,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + What's New in Python 2.7.11 release candidate 1? ================================================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 22 22:05:35 2015 From: python-checkins at python.org (benjamin.peterson) Date: Mon, 23 Nov 2015 03:05:35 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMi43IC0+IDIuNyk6?= =?utf-8?q?_merge_2=2E7=2E11_release_branch?= Message-ID: <20151123030535.127576.90991@psf.io> https://hg.python.org/cpython/rev/d452cf840e5b changeset: 99293:d452cf840e5b branch: 2.7 parent: 99287:de5582c569ff parent: 99292:43208b0f2535 user: Benjamin Peterson date: Sun Nov 22 19:05:14 2015 -0800 summary: merge 2.7.11 release branch files: Misc/NEWS | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -28,6 +28,9 @@ Library ------- +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + What's New in Python 2.7.11 release candidate 1? ================================================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 01:50:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 06:50:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Njkx?= =?utf-8?q?=3A_Fixed_crash_on_deleting_ElementTree=2EElement_attributes=2E?= Message-ID: <20151123065053.9710.5316@psf.io> https://hg.python.org/cpython/rev/852c9ed9115c changeset: 99295:852c9ed9115c branch: 3.4 parent: 99284:e7d1df56f70b user: Serhiy Storchaka date: Mon Nov 23 08:42:25 2015 +0200 summary: Issue #25691: Fixed crash on deleting ElementTree.Element attributes. files: Lib/test/test_xml_etree.py | 27 ++++++++++++++++++++ Lib/test/test_xml_etree_c.py | 32 ++++++++++++++++++++++++ Misc/NEWS | 2 + Modules/_elementtree.c | 6 ++++ 4 files changed, 67 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -244,6 +244,33 @@ self.assertEqual(ET.XML, ET.fromstring) self.assertEqual(ET.PI, ET.ProcessingInstruction) + def test_set_attribute(self): + element = ET.Element('tag') + + self.assertEqual(element.tag, 'tag') + element.tag = 'Tag' + self.assertEqual(element.tag, 'Tag') + element.tag = 'TAG' + self.assertEqual(element.tag, 'TAG') + + self.assertIsNone(element.text) + element.text = 'Text' + self.assertEqual(element.text, 'Text') + element.text = 'TEXT' + self.assertEqual(element.text, 'TEXT') + + self.assertIsNone(element.tail) + element.tail = 'Tail' + self.assertEqual(element.tail, 'Tail') + element.tail = 'TAIL' + self.assertEqual(element.tail, 'TAIL') + + self.assertEqual(element.attrib, {}) + element.attrib = {'a': 'b', 'c': 'd'} + self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'}) + element.attrib = {'A': 'B', 'C': 'D'} + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_simpleops(self): # Basic method sanity checks. diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -22,6 +22,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,8 @@ Library ------- +- Issue #25691: Fixed crash on deleting ElementTree.Element attributes. + - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1852,6 +1852,12 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { char *name = ""; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attribute"); + return -1; + } if (PyUnicode_Check(nameobj)) name = _PyUnicode_AsString(nameobj); if (name == NULL) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 01:50:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 06:50:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325691=3A_Fixed_crash_on_deleting_ElementTree=2EElemen?= =?utf-8?q?t_attributes=2E?= Message-ID: <20151123065053.21529.90431@psf.io> https://hg.python.org/cpython/rev/3a44f06907f1 changeset: 99296:3a44f06907f1 branch: 3.5 parent: 99290:8db7523a13ea parent: 99295:852c9ed9115c user: Serhiy Storchaka date: Mon Nov 23 08:47:26 2015 +0200 summary: Issue #25691: Fixed crash on deleting ElementTree.Element attributes. files: Lib/test/test_xml_etree.py | 27 ++++++++++++++++++++ Lib/test/test_xml_etree_c.py | 32 ++++++++++++++++++++++++ Misc/NEWS | 2 + Modules/_elementtree.c | 6 ++++ 4 files changed, 67 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -244,6 +244,33 @@ self.assertEqual(ET.XML, ET.fromstring) self.assertEqual(ET.PI, ET.ProcessingInstruction) + def test_set_attribute(self): + element = ET.Element('tag') + + self.assertEqual(element.tag, 'tag') + element.tag = 'Tag' + self.assertEqual(element.tag, 'Tag') + element.tag = 'TAG' + self.assertEqual(element.tag, 'TAG') + + self.assertIsNone(element.text) + element.text = 'Text' + self.assertEqual(element.text, 'Text') + element.text = 'TEXT' + self.assertEqual(element.text, 'TEXT') + + self.assertIsNone(element.tail) + element.tail = 'Tail' + self.assertEqual(element.tail, 'Tail') + element.tail = 'TAIL' + self.assertEqual(element.tail, 'TAIL') + + self.assertEqual(element.attrib, {}) + element.attrib = {'a': 'b', 'c': 'd'} + self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'}) + element.attrib = {'A': 'B', 'C': 'D'} + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_simpleops(self): # Basic method sanity checks. diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -22,6 +22,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -77,6 +77,8 @@ Library ------- +- Issue #25691: Fixed crash on deleting ElementTree.Element attributes. + - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1921,6 +1921,12 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { char *name = ""; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attribute"); + return -1; + } if (PyUnicode_Check(nameobj)) name = _PyUnicode_AsString(nameobj); if (name == NULL) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 01:50:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 06:50:53 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Njkx?= =?utf-8?q?=3A_Added_tests_on_deleting_cElementTree=2EElement_attributes?= =?utf-8?q?=2E?= Message-ID: <20151123065053.9714.64709@psf.io> https://hg.python.org/cpython/rev/e3dea2e4f93d changeset: 99298:e3dea2e4f93d branch: 2.7 parent: 99294:94da1d00000b user: Serhiy Storchaka date: Mon Nov 23 08:50:20 2015 +0200 summary: Issue #25691: Added tests on deleting cElementTree.Element attributes. files: Lib/test/test_xml_etree_c.py | 32 ++++++++++++++++++++++++ 1 files changed, 32 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -30,6 +30,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_main(): from test import test_xml_etree, test_xml_etree_c -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 01:50:53 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 06:50:53 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325691=3A_Fixed_crash_on_deleting_ElementTree=2E?= =?utf-8?q?Element_attributes=2E?= Message-ID: <20151123065053.130859.13435@psf.io> https://hg.python.org/cpython/rev/936fcd0ba6b1 changeset: 99297:936fcd0ba6b1 parent: 99291:2662099d477e parent: 99296:3a44f06907f1 user: Serhiy Storchaka date: Mon Nov 23 08:49:39 2015 +0200 summary: Issue #25691: Fixed crash on deleting ElementTree.Element attributes. files: Lib/test/test_xml_etree.py | 27 ++++++++++++++++++++ Lib/test/test_xml_etree_c.py | 32 ++++++++++++++++++++++++ Misc/NEWS | 2 + Modules/_elementtree.c | 6 ++++ 4 files changed, 67 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -244,6 +244,33 @@ self.assertEqual(ET.XML, ET.fromstring) self.assertEqual(ET.PI, ET.ProcessingInstruction) + def test_set_attribute(self): + element = ET.Element('tag') + + self.assertEqual(element.tag, 'tag') + element.tag = 'Tag' + self.assertEqual(element.tag, 'Tag') + element.tag = 'TAG' + self.assertEqual(element.tag, 'TAG') + + self.assertIsNone(element.text) + element.text = 'Text' + self.assertEqual(element.text, 'Text') + element.text = 'TEXT' + self.assertEqual(element.text, 'TEXT') + + self.assertIsNone(element.tail) + element.tail = 'Tail' + self.assertEqual(element.tail, 'Tail') + element.tail = 'TAIL' + self.assertEqual(element.tail, 'TAIL') + + self.assertEqual(element.attrib, {}) + element.attrib = {'a': 'b', 'c': 'd'} + self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'}) + element.attrib = {'A': 'B', 'C': 'D'} + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_simpleops(self): # Basic method sanity checks. diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -22,6 +22,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,8 @@ Library ------- +- Issue #25691: Fixed crash on deleting ElementTree.Element attributes. + - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1921,6 +1921,12 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { char *name = ""; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attribute"); + return -1; + } if (PyUnicode_Check(nameobj)) name = _PyUnicode_AsString(nameobj); if (name == NULL) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:29:40 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:29:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Added_tag_v3?= =?utf-8?q?=2E5=2E1rc1_for_changeset_948ef16a6951?= Message-ID: <20151123072940.21507.7038@psf.io> https://hg.python.org/cpython/rev/da245b9641d9 changeset: 99301:da245b9641d9 branch: 3.5 user: Larry Hastings date: Sat Nov 21 23:54:48 2015 -0800 summary: Added tag v3.5.1rc1 for changeset 948ef16a6951 files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -157,3 +157,4 @@ 66ed52375df802f9d0a34480daaa8ce79fc41313 v3.5.0rc3 2d033fedfa7f1e325fd14ccdaa9cb42155da206f v3.5.0rc4 374f501f4567b7595f2ad7798aa09afa2456bb28 v3.5.0 +948ef16a69513ba1ff15c9d7d0b012b949df4c80 v3.5.1rc1 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:29:40 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:29:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Version_bump_f?= =?utf-8?q?or_Python_3=2E5=2E1rc1=2E?= Message-ID: <20151123072940.15101.51767@psf.io> https://hg.python.org/cpython/rev/948ef16a6951 changeset: 99300:948ef16a6951 branch: 3.5 tag: v3.5.1rc1 user: Larry Hastings date: Sat Nov 21 23:54:22 2015 -0800 summary: Version bump for Python 3.5.1rc1. files: Include/patchlevel.h | 8 ++++---- Misc/NEWS | 2 +- README | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -18,12 +18,12 @@ /*--start constants--*/ #define PY_MAJOR_VERSION 3 #define PY_MINOR_VERSION 5 -#define PY_MICRO_VERSION 0 -#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_FINAL -#define PY_RELEASE_SERIAL 0 +#define PY_MICRO_VERSION 1 +#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_GAMMA +#define PY_RELEASE_SERIAL 1 /* Version as a string */ -#define PY_VERSION "3.5.0+" +#define PY_VERSION "3.5.1rc1" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -6,7 +6,7 @@ What's New in Python 3.5.1 release candidate 1? =============================================== -Release date: TBA +Release date: 2015-11-22 Core and Builtins ----------------- diff --git a/README b/README --- a/README +++ b/README @@ -1,4 +1,4 @@ -This is Python version 3.5.0 +This is Python version 3.5.1 ============================ Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:29:40 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:29:40 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy41IC0+IDMuNSk6?= =?utf-8?q?_Merge_3=2E5=2E1rc1_release_changes_back_into_main_3=2E5_branch?= =?utf-8?q?=2E?= Message-ID: <20151123072940.21507.6194@psf.io> https://hg.python.org/cpython/rev/a077bab36ae4 changeset: 99303:a077bab36ae4 branch: 3.5 parent: 99302:afc0ad583808 parent: 99296:3a44f06907f1 user: Larry Hastings date: Sun Nov 22 23:27:07 2015 -0800 summary: Merge 3.5.1rc1 release changes back into main 3.5 branch. files: Lib/test/test_shutil.py | 23 ++++ Lib/test/test_xml_etree.py | 102 ++++++++++++++++++++ Lib/test/test_xml_etree_c.py | 32 ++++++ Lib/zipfile.py | 4 +- Misc/ACKS | 1 + Misc/NEWS | 17 +++ Modules/_elementtree.c | 42 ++++---- Tools/msi/bundle/bundle.targets | 2 +- Tools/msi/uploadrelease.proj | 2 +- 9 files changed, 201 insertions(+), 24 deletions(-) diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -1105,6 +1105,29 @@ names2 = zf.namelist() self.assertEqual(sorted(names), sorted(names2)) + @requires_zlib + @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run') + @unittest.skipUnless(shutil.which('unzip'), + 'Need the unzip command to run') + def test_unzip_zipfile(self): + root_dir, base_dir = self._create_files() + base_name = os.path.join(self.mkdtemp(), 'archive') + archive = make_archive(base_name, 'zip', root_dir, base_dir) + + # check if ZIP file was created + self.assertEqual(archive, base_name + '.zip') + self.assertTrue(os.path.isfile(archive)) + + # now check the ZIP file using `unzip -t` + zip_cmd = ['unzip', '-t', archive] + with support.change_cwd(root_dir): + try: + subprocess.check_output(zip_cmd, stderr=subprocess.STDOUT) + except subprocess.CalledProcessError as exc: + details = exc.output.decode(errors="replace") + msg = "{}\n\n**Unzip Output**\n{}" + self.fail(msg.format(exc, details)) + def test_make_archive(self): tmpdir = self.mkdtemp() base_name = os.path.join(tmpdir, 'archive') diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -244,6 +244,33 @@ self.assertEqual(ET.XML, ET.fromstring) self.assertEqual(ET.PI, ET.ProcessingInstruction) + def test_set_attribute(self): + element = ET.Element('tag') + + self.assertEqual(element.tag, 'tag') + element.tag = 'Tag' + self.assertEqual(element.tag, 'Tag') + element.tag = 'TAG' + self.assertEqual(element.tag, 'TAG') + + self.assertIsNone(element.text) + element.text = 'Text' + self.assertEqual(element.text, 'Text') + element.text = 'TEXT' + self.assertEqual(element.text, 'TEXT') + + self.assertIsNone(element.tail) + element.tail = 'Tail' + self.assertEqual(element.tail, 'Tail') + element.tail = 'TAIL' + self.assertEqual(element.tail, 'TAIL') + + self.assertEqual(element.attrib, {}) + element.attrib = {'a': 'b', 'c': 'd'} + self.assertEqual(element.attrib, {'a': 'b', 'c': 'd'}) + element.attrib = {'A': 'B', 'C': 'D'} + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + def test_simpleops(self): # Basic method sanity checks. @@ -2350,6 +2377,7 @@ self.assertEqual(e[-2].tag, 'a8') self.assertRaises(IndexError, lambda: e[12]) + self.assertRaises(IndexError, lambda: e[-12]) def test_getslice_range(self): e = self._make_elem_with_children(6) @@ -2368,12 +2396,17 @@ self.assertEqual(self._elem_tags(e[::3]), ['a0', 'a3', 'a6', 'a9']) self.assertEqual(self._elem_tags(e[::8]), ['a0', 'a8']) self.assertEqual(self._elem_tags(e[1::8]), ['a1', 'a9']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::sys.maxsize<<64]), ['a3']) def test_getslice_negative_steps(self): e = self._make_elem_with_children(4) self.assertEqual(self._elem_tags(e[::-1]), ['a3', 'a2', 'a1', 'a0']) self.assertEqual(self._elem_tags(e[::-2]), ['a3', 'a1']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize-1]), ['a3']) + self.assertEqual(self._elem_tags(e[3::-sys.maxsize<<64]), ['a3']) def test_delslice(self): e = self._make_elem_with_children(4) @@ -2400,6 +2433,75 @@ del e[::2] self.assertEqual(self._subelem_tags(e), ['a1']) + def test_setslice_single_index(self): + e = self._make_elem_with_children(4) + e[1] = ET.Element('b') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + + e[-2] = ET.Element('c') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + with self.assertRaises(IndexError): + e[5] = ET.Element('d') + with self.assertRaises(IndexError): + e[-5] = ET.Element('d') + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'c', 'a3']) + + def test_setslice_range(self): + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a3']) + + e = self._make_elem_with_children(4) + e[1:3] = [ET.Element('b%s' % i) for i in range(3)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'b1', 'b2', 'a3']) + + def test_setslice_steps(self): + e = self._make_elem_with_children(6) + e[1:5:2] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b0', 'a2', 'b1', 'a4', 'a5']) + + e = self._make_elem_with_children(6) + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[1:5:2] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[1:5:2] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3', 'a4', 'a5']) + + e = self._make_elem_with_children(4) + e[1::sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::sys.maxsize<<64] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + + def test_setslice_negative_steps(self): + e = self._make_elem_with_children(4) + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(2)] + self.assertEqual(self._subelem_tags(e), ['a0', 'b1', 'b0', 'a3']) + + e = self._make_elem_with_children(4) + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b')] + with self.assertRaises(ValueError): + e[2:0:-1] = [ET.Element('b%s' % i) for i in range(3)] + with self.assertRaises(ValueError): + e[2:0:-1] = [] + self.assertEqual(self._subelem_tags(e), ['a0', 'a1', 'a2', 'a3']) + + e = self._make_elem_with_children(4) + e[1::-sys.maxsize] = [ET.Element('b')] + self.assertEqual(self._subelem_tags(e), ['a0', 'b', 'a2', 'a3']) + e[1::-sys.maxsize-1] = [ET.Element('c')] + self.assertEqual(self._subelem_tags(e), ['a0', 'c', 'a2', 'a3']) + e[1::-sys.maxsize<<64] = [ET.Element('d')] + self.assertEqual(self._subelem_tags(e), ['a0', 'd', 'a2', 'a3']) + class IOTest(unittest.TestCase): def tearDown(self): diff --git a/Lib/test/test_xml_etree_c.py b/Lib/test/test_xml_etree_c.py --- a/Lib/test/test_xml_etree_c.py +++ b/Lib/test/test_xml_etree_c.py @@ -22,6 +22,38 @@ finally: data = None + def test_del_attribute(self): + element = cET.Element('tag') + + element.tag = 'TAG' + with self.assertRaises(AttributeError): + del element.tag + self.assertEqual(element.tag, 'TAG') + + with self.assertRaises(AttributeError): + del element.text + self.assertIsNone(element.text) + element.text = 'TEXT' + with self.assertRaises(AttributeError): + del element.text + self.assertEqual(element.text, 'TEXT') + + with self.assertRaises(AttributeError): + del element.tail + self.assertIsNone(element.tail) + element.tail = 'TAIL' + with self.assertRaises(AttributeError): + del element.tail + self.assertEqual(element.tail, 'TAIL') + + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {}) + element.attrib = {'A': 'B', 'C': 'D'} + with self.assertRaises(AttributeError): + del element.attrib + self.assertEqual(element.attrib, {'A': 'B', 'C': 'D'}) + @unittest.skipUnless(cET, 'requires _elementtree') class TestAliasWorking(unittest.TestCase): diff --git a/Lib/zipfile.py b/Lib/zipfile.py --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1444,7 +1444,9 @@ arcname += '/' zinfo = ZipInfo(arcname, date_time) zinfo.external_attr = (st[0] & 0xFFFF) << 16 # Unix attributes - if compress_type is None: + if isdir: + zinfo.compress_type = ZIP_STORED + elif compress_type is None: zinfo.compress_type = self.compression else: zinfo.compress_type = compress_type diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1518,6 +1518,7 @@ Larry Wall Kevin Walzer Rodrigo Steinmuller Wanderley +Dingyuan Wang Ke Wang Greg Ward Tom Wardill diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,23 @@ Python News +++++++++++ +What's New in Python 3.5.2 release candidate 1? +=============================================== + +Release date: XXXX-XX-XX + +Core and Builtins +----------------- + +Library +------- + +- Issue #25691: Fixed crash on deleting ElementTree.Element attributes. + +- Issue #25624: ZipFile now always writes a ZIP_STORED header for directory + entries. Patch by Dingyuan Wang. + + What's New in Python 3.5.1 final? ================================= diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1711,7 +1711,7 @@ Py_ssize_t start, stop, step, slicelen, newlen, cur, i; PyObject* recycle = NULL; - PyObject* seq = NULL; + PyObject* seq; if (!self->extra) { if (create_extra(self, NULL) < 0) @@ -1790,21 +1790,21 @@ Py_XDECREF(recycle); return 0; } - else { - /* A new slice is actually being assigned */ - seq = PySequence_Fast(value, ""); - if (!seq) { - PyErr_Format( - PyExc_TypeError, - "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name - ); - return -1; - } - newlen = PySequence_Size(seq); + + /* A new slice is actually being assigned */ + seq = PySequence_Fast(value, ""); + if (!seq) { + PyErr_Format( + PyExc_TypeError, + "expected sequence, not \"%.200s\"", Py_TYPE(value)->tp_name + ); + return -1; } + newlen = PySequence_Size(seq); if (step != 1 && newlen != slicelen) { + Py_DECREF(seq); PyErr_Format(PyExc_ValueError, "attempt to assign sequence of size %zd " "to extended slice of size %zd", @@ -1816,9 +1816,7 @@ /* Resize before creating the recycle bin, to prevent refleaks. */ if (newlen > slicelen) { if (element_resize(self, newlen - slicelen) < 0) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } } @@ -1829,9 +1827,7 @@ we're done modifying the element */ recycle = PyList_New(slicelen); if (!recycle) { - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); return -1; } for (cur = start, i = 0; i < slicelen; @@ -1859,9 +1855,7 @@ self->extra->length += newlen - slicelen; - if (seq) { - Py_DECREF(seq); - } + Py_DECREF(seq); /* discard the recycle bin, and everything in it */ Py_XDECREF(recycle); @@ -1927,6 +1921,12 @@ element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) { char *name = ""; + + if (value == NULL) { + PyErr_SetString(PyExc_AttributeError, + "can't delete attribute"); + return -1; + } if (PyUnicode_Check(nameobj)) name = _PyUnicode_AsString(nameobj); if (name == NULL) diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -18,7 +18,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/{version}/{arch}{releasename}/{msi} - $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseName)`).Replace(`{msi}`, `{2}`)) + $(DefineConstants);DownloadUrl=$(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, `{2}`)) $(DefineConstants);DownloadUrl={2} diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -16,7 +16,7 @@ $(DownloadUrlBase.TrimEnd(`/`))/$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber) - $(DownloadUrl.TrimEnd(`/`)) + $(DownloadUrl.Replace(`{version}`, `$(MajorVersionNumber).$(MinorVersionNumber).$(MicroVersionNumber)`).Replace(`{arch}`, `$(ArchName)`).Replace(`{releasename}`, `$(ReleaseLevelName)`).Replace(`{msi}`, ``).TrimEnd(`/`)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:29:41 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:29:41 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Post-release_u?= =?utf-8?q?pdates_for_Python_3=2E5=2E1rc1=2E?= Message-ID: <20151123072940.127558.92915@psf.io> https://hg.python.org/cpython/rev/afc0ad583808 changeset: 99302:afc0ad583808 branch: 3.5 user: Larry Hastings date: Sun Nov 22 23:22:47 2015 -0800 summary: Post-release updates for Python 3.5.1rc1. files: Include/patchlevel.h | 2 +- Misc/NEWS | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletions(-) diff --git a/Include/patchlevel.h b/Include/patchlevel.h --- 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.5.1rc1" +#define PY_VERSION "3.5.1rc1+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -2,6 +2,17 @@ Python News +++++++++++ +What's New in Python 3.5.1 final? +================================= + +Release date: 2015-12-06 + +Core and Builtins +----------------- + +Library +------- + What's New in Python 3.5.1 release candidate 1? =============================================== -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:29:40 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:29:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Updated_pydoc_?= =?utf-8?q?topics_for_3=2E5=2E1rc1=2E?= Message-ID: <20151123072940.21501.9910@psf.io> https://hg.python.org/cpython/rev/c6fd55b63d8e changeset: 99299:c6fd55b63d8e branch: 3.5 parent: 99276:2fa12e53e8f3 user: Larry Hastings date: Sat Nov 21 23:50:36 2015 -0800 summary: Updated pydoc topics for 3.5.1rc1. files: Lib/pydoc_data/topics.py | 12958 +------------------------ 1 files changed, 78 insertions(+), 12880 deletions(-) diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,12881 +1,79 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Sat Sep 12 17:22:24 2015 -topics = {'assert': '\n' - 'The "assert" statement\n' - '**********************\n' - '\n' - 'Assert statements are a convenient way to insert debugging ' - 'assertions\n' - 'into a program:\n' - '\n' - ' assert_stmt ::= "assert" expression ["," expression]\n' - '\n' - 'The simple form, "assert expression", is equivalent to\n' - '\n' - ' if __debug__:\n' - ' if not expression: raise AssertionError\n' - '\n' - 'The extended form, "assert expression1, expression2", is ' - 'equivalent to\n' - '\n' - ' if __debug__:\n' - ' if not expression1: raise AssertionError(expression2)\n' - '\n' - 'These equivalences assume that "__debug__" and "AssertionError" ' - 'refer\n' - 'to the built-in variables with those names. In the current\n' - 'implementation, the built-in variable "__debug__" is "True" ' - 'under\n' - 'normal circumstances, "False" when optimization is requested ' - '(command\n' - 'line option -O). The current code generator emits no code for ' - 'an\n' - 'assert statement when optimization is requested at compile ' - 'time. Note\n' - 'that it is unnecessary to include the source code for the ' - 'expression\n' - 'that failed in the error message; it will be displayed as part ' - 'of the\n' - 'stack trace.\n' - '\n' - 'Assignments to "__debug__" are illegal. The value for the ' - 'built-in\n' - 'variable is determined when the interpreter starts.\n', - 'assignment': '\n' - 'Assignment statements\n' - '*********************\n' - '\n' - 'Assignment statements are used to (re)bind names to values ' - 'and to\n' - 'modify attributes or items of mutable objects:\n' - '\n' - ' assignment_stmt ::= (target_list "=")+ (expression_list | ' - 'yield_expression)\n' - ' target_list ::= target ("," target)* [","]\n' - ' target ::= identifier\n' - ' | "(" target_list ")"\n' - ' | "[" target_list "]"\n' - ' | attributeref\n' - ' | subscription\n' - ' | slicing\n' - ' | "*" target\n' - '\n' - '(See section *Primaries* for the syntax definitions for\n' - '*attributeref*, *subscription*, and *slicing*.)\n' - '\n' - 'An assignment statement evaluates the expression list ' - '(remember that\n' - 'this can be a single expression or a comma-separated list, ' - 'the latter\n' - 'yielding a tuple) and assigns the single resulting object to ' - 'each of\n' - 'the target lists, from left to right.\n' - '\n' - 'Assignment is defined recursively depending on the form of ' - 'the target\n' - '(list). When a target is part of a mutable object (an ' - 'attribute\n' - 'reference, subscription or slicing), the mutable object ' - 'must\n' - 'ultimately perform the assignment and decide about its ' - 'validity, and\n' - 'may raise an exception if the assignment is unacceptable. ' - 'The rules\n' - 'observed by various types and the exceptions raised are ' - 'given with the\n' - 'definition of the object types (see section *The standard ' - 'type\n' - 'hierarchy*).\n' - '\n' - 'Assignment of an object to a target list, optionally ' - 'enclosed in\n' - 'parentheses or square brackets, is recursively defined as ' - 'follows.\n' - '\n' - '* If the target list is a single target: The object is ' - 'assigned to\n' - ' that target.\n' - '\n' - '* If the target list is a comma-separated list of targets: ' - 'The\n' - ' object must be an iterable with the same number of items ' - 'as there\n' - ' are targets in the target list, and the items are ' - 'assigned, from\n' - ' left to right, to the corresponding targets.\n' - '\n' - ' * If the target list contains one target prefixed with an\n' - ' asterisk, called a "starred" target: The object must be ' - 'a sequence\n' - ' with at least as many items as there are targets in the ' - 'target\n' - ' list, minus one. The first items of the sequence are ' - 'assigned,\n' - ' from left to right, to the targets before the starred ' - 'target. The\n' - ' final items of the sequence are assigned to the targets ' - 'after the\n' - ' starred target. A list of the remaining items in the ' - 'sequence is\n' - ' then assigned to the starred target (the list can be ' - 'empty).\n' - '\n' - ' * Else: The object must be a sequence with the same number ' - 'of\n' - ' items as there are targets in the target list, and the ' - 'items are\n' - ' assigned, from left to right, to the corresponding ' - 'targets.\n' - '\n' - 'Assignment of an object to a single target is recursively ' - 'defined as\n' - 'follows.\n' - '\n' - '* If the target is an identifier (name):\n' - '\n' - ' * If the name does not occur in a "global" or "nonlocal" ' - 'statement\n' - ' in the current code block: the name is bound to the ' - 'object in the\n' - ' current local namespace.\n' - '\n' - ' * Otherwise: the name is bound to the object in the ' - 'global\n' - ' namespace or the outer namespace determined by ' - '"nonlocal",\n' - ' respectively.\n' - '\n' - ' The name is rebound if it was already bound. This may ' - 'cause the\n' - ' reference count for the object previously bound to the ' - 'name to reach\n' - ' zero, causing the object to be deallocated and its ' - 'destructor (if it\n' - ' has one) to be called.\n' - '\n' - '* If the target is a target list enclosed in parentheses or ' - 'in\n' - ' square brackets: The object must be an iterable with the ' - 'same number\n' - ' of items as there are targets in the target list, and its ' - 'items are\n' - ' assigned, from left to right, to the corresponding ' - 'targets.\n' - '\n' - '* If the target is an attribute reference: The primary ' - 'expression in\n' - ' the reference is evaluated. It should yield an object ' - 'with\n' - ' assignable attributes; if this is not the case, ' - '"TypeError" is\n' - ' raised. That object is then asked to assign the assigned ' - 'object to\n' - ' the given attribute; if it cannot perform the assignment, ' - 'it raises\n' - ' an exception (usually but not necessarily ' - '"AttributeError").\n' - '\n' - ' Note: If the object is a class instance and the attribute ' - 'reference\n' - ' occurs on both sides of the assignment operator, the RHS ' - 'expression,\n' - ' "a.x" can access either an instance attribute or (if no ' - 'instance\n' - ' attribute exists) a class attribute. The LHS target "a.x" ' - 'is always\n' - ' set as an instance attribute, creating it if necessary. ' - 'Thus, the\n' - ' two occurrences of "a.x" do not necessarily refer to the ' - 'same\n' - ' attribute: if the RHS expression refers to a class ' - 'attribute, the\n' - ' LHS creates a new instance attribute as the target of the\n' - ' assignment:\n' - '\n' - ' class Cls:\n' - ' x = 3 # class variable\n' - ' inst = Cls()\n' - ' inst.x = inst.x + 1 # writes inst.x as 4 leaving ' - 'Cls.x as 3\n' - '\n' - ' This description does not necessarily apply to descriptor\n' - ' attributes, such as properties created with "property()".\n' - '\n' - '* If the target is a subscription: The primary expression in ' - 'the\n' - ' reference is evaluated. It should yield either a mutable ' - 'sequence\n' - ' object (such as a list) or a mapping object (such as a ' - 'dictionary).\n' - ' Next, the subscript expression is evaluated.\n' - '\n' - ' If the primary is a mutable sequence object (such as a ' - 'list), the\n' - ' subscript must yield an integer. If it is negative, the ' - "sequence's\n" - ' length is added to it. The resulting value must be a ' - 'nonnegative\n' - " integer less than the sequence's length, and the sequence " - 'is asked\n' - ' to assign the assigned object to its item with that ' - 'index. If the\n' - ' index is out of range, "IndexError" is raised (assignment ' - 'to a\n' - ' subscripted sequence cannot add new items to a list).\n' - '\n' - ' If the primary is a mapping object (such as a dictionary), ' - 'the\n' - " subscript must have a type compatible with the mapping's " - 'key type,\n' - ' and the mapping is then asked to create a key/datum pair ' - 'which maps\n' - ' the subscript to the assigned object. This can either ' - 'replace an\n' - ' existing key/value pair with the same key value, or insert ' - 'a new\n' - ' key/value pair (if no key with the same value existed).\n' - '\n' - ' For user-defined objects, the "__setitem__()" method is ' - 'called with\n' - ' appropriate arguments.\n' - '\n' - '* If the target is a slicing: The primary expression in the\n' - ' reference is evaluated. It should yield a mutable ' - 'sequence object\n' - ' (such as a list). The assigned object should be a ' - 'sequence object\n' - ' of the same type. Next, the lower and upper bound ' - 'expressions are\n' - ' evaluated, insofar they are present; defaults are zero and ' - 'the\n' - " sequence's length. The bounds should evaluate to " - 'integers. If\n' - " either bound is negative, the sequence's length is added " - 'to it. The\n' - ' resulting bounds are clipped to lie between zero and the ' - "sequence's\n" - ' length, inclusive. Finally, the sequence object is asked ' - 'to replace\n' - ' the slice with the items of the assigned sequence. The ' - 'length of\n' - ' the slice may be different from the length of the assigned ' - 'sequence,\n' - ' thus changing the length of the target sequence, if the ' - 'target\n' - ' sequence allows it.\n' - '\n' - '**CPython implementation detail:** In the current ' - 'implementation, the\n' - 'syntax for targets is taken to be the same as for ' - 'expressions, and\n' - 'invalid syntax is rejected during the code generation phase, ' - 'causing\n' - 'less detailed error messages.\n' - '\n' - 'Although the definition of assignment implies that overlaps ' - 'between\n' - 'the left-hand side and the right-hand side are ' - "'simultanenous' (for\n" - 'example "a, b = b, a" swaps two variables), overlaps ' - '*within* the\n' - 'collection of assigned-to variables occur left-to-right, ' - 'sometimes\n' - 'resulting in confusion. For instance, the following program ' - 'prints\n' - '"[0, 2]":\n' - '\n' - ' x = [0, 1]\n' - ' i = 0\n' - ' i, x[i] = 1, 2 # i is updated, then x[i] is ' - 'updated\n' - ' print(x)\n' - '\n' - 'See also: **PEP 3132** - Extended Iterable Unpacking\n' - '\n' - ' The specification for the "*target" feature.\n' - '\n' - '\n' - 'Augmented assignment statements\n' - '===============================\n' - '\n' - 'Augmented assignment is the combination, in a single ' - 'statement, of a\n' - 'binary operation and an assignment statement:\n' - '\n' - ' augmented_assignment_stmt ::= augtarget augop ' - '(expression_list | yield_expression)\n' - ' augtarget ::= identifier | attributeref | ' - 'subscription | slicing\n' - ' augop ::= "+=" | "-=" | "*=" | "@=" | ' - '"/=" | "//=" | "%=" | "**="\n' - ' | ">>=" | "<<=" | "&=" | "^=" | "|="\n' - '\n' - '(See section *Primaries* for the syntax definitions of the ' - 'last three\n' - 'symbols.)\n' - '\n' - 'An augmented assignment evaluates the target (which, unlike ' - 'normal\n' - 'assignment statements, cannot be an unpacking) and the ' - 'expression\n' - 'list, performs the binary operation specific to the type of ' - 'assignment\n' - 'on the two operands, and assigns the result to the original ' - 'target.\n' - 'The target is only evaluated once.\n' - '\n' - 'An augmented assignment expression like "x += 1" can be ' - 'rewritten as\n' - '"x = x + 1" to achieve a similar, but not exactly equal ' - 'effect. In the\n' - 'augmented version, "x" is only evaluated once. Also, when ' - 'possible,\n' - 'the actual operation is performed *in-place*, meaning that ' - 'rather than\n' - 'creating a new object and assigning that to the target, the ' - 'old object\n' - 'is modified instead.\n' - '\n' - 'Unlike normal assignments, augmented assignments evaluate ' - 'the left-\n' - 'hand side *before* evaluating the right-hand side. For ' - 'example, "a[i]\n' - '+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and ' - 'performs\n' - 'the addition, and lastly, it writes the result back to ' - '"a[i]".\n' - '\n' - 'With the exception of assigning to tuples and multiple ' - 'targets in a\n' - 'single statement, the assignment done by augmented ' - 'assignment\n' - 'statements is handled the same way as normal assignments. ' - 'Similarly,\n' - 'with the exception of the possible *in-place* behavior, the ' - 'binary\n' - 'operation performed by augmented assignment is the same as ' - 'the normal\n' - 'binary operations.\n' - '\n' - 'For targets which are attribute references, the same *caveat ' - 'about\n' - 'class and instance attributes* applies as for regular ' - 'assignments.\n', - 'atom-identifiers': '\n' - 'Identifiers (Names)\n' - '*******************\n' - '\n' - 'An identifier occurring as an atom is a name. See ' - 'section\n' - '*Identifiers and keywords* for lexical definition and ' - 'section *Naming\n' - 'and binding* for documentation of naming and binding.\n' - '\n' - 'When the name is bound to an object, evaluation of the ' - 'atom yields\n' - 'that object. When a name is not bound, an attempt to ' - 'evaluate it\n' - 'raises a "NameError" exception.\n' - '\n' - '**Private name mangling:** When an identifier that ' - 'textually occurs in\n' - 'a class definition begins with two or more underscore ' - 'characters and\n' - 'does not end in two or more underscores, it is ' - 'considered a *private\n' - 'name* of that class. Private names are transformed to ' - 'a longer form\n' - 'before code is generated for them. The transformation ' - 'inserts the\n' - 'class name, with leading underscores removed and a ' - 'single underscore\n' - 'inserted, in front of the name. For example, the ' - 'identifier "__spam"\n' - 'occurring in a class named "Ham" will be transformed ' - 'to "_Ham__spam".\n' - 'This transformation is independent of the syntactical ' - 'context in which\n' - 'the identifier is used. If the transformed name is ' - 'extremely long\n' - '(longer than 255 characters), implementation defined ' - 'truncation may\n' - 'happen. If the class name consists only of ' - 'underscores, no\n' - 'transformation is done.\n', - 'atom-literals': '\n' - 'Literals\n' - '********\n' - '\n' - 'Python supports string and bytes literals and various ' - 'numeric\n' - 'literals:\n' - '\n' - ' literal ::= stringliteral | bytesliteral\n' - ' | integer | floatnumber | imagnumber\n' - '\n' - 'Evaluation of a literal yields an object of the given ' - 'type (string,\n' - 'bytes, integer, floating point number, complex number) ' - 'with the given\n' - 'value. The value may be approximated in the case of ' - 'floating point\n' - 'and imaginary (complex) literals. See section *Literals* ' - 'for details.\n' - '\n' - 'All literals correspond to immutable data types, and ' - 'hence the\n' - "object's identity is less important than its value. " - 'Multiple\n' - 'evaluations of literals with the same value (either the ' - 'same\n' - 'occurrence in the program text or a different occurrence) ' - 'may obtain\n' - 'the same object or a different object with the same ' - 'value.\n', - 'attribute-access': '\n' - 'Customizing attribute access\n' - '****************************\n' - '\n' - 'The following methods can be defined to customize the ' - 'meaning of\n' - 'attribute access (use of, assignment to, or deletion ' - 'of "x.name") for\n' - 'class instances.\n' - '\n' - 'object.__getattr__(self, name)\n' - '\n' - ' Called when an attribute lookup has not found the ' - 'attribute in the\n' - ' usual places (i.e. it is not an instance attribute ' - 'nor is it found\n' - ' in the class tree for "self"). "name" is the ' - 'attribute name. This\n' - ' method should return the (computed) attribute value ' - 'or raise an\n' - ' "AttributeError" exception.\n' - '\n' - ' Note that if the attribute is found through the ' - 'normal mechanism,\n' - ' "__getattr__()" is not called. (This is an ' - 'intentional asymmetry\n' - ' between "__getattr__()" and "__setattr__()".) This ' - 'is done both for\n' - ' efficiency reasons and because otherwise ' - '"__getattr__()" would have\n' - ' no way to access other attributes of the instance. ' - 'Note that at\n' - ' least for instance variables, you can fake total ' - 'control by not\n' - ' inserting any values in the instance attribute ' - 'dictionary (but\n' - ' instead inserting them in another object). See ' - 'the\n' - ' "__getattribute__()" method below for a way to ' - 'actually get total\n' - ' control over attribute access.\n' - '\n' - 'object.__getattribute__(self, name)\n' - '\n' - ' Called unconditionally to implement attribute ' - 'accesses for\n' - ' instances of the class. If the class also defines ' - '"__getattr__()",\n' - ' the latter will not be called unless ' - '"__getattribute__()" either\n' - ' calls it explicitly or raises an "AttributeError". ' - 'This method\n' - ' should return the (computed) attribute value or ' - 'raise an\n' - ' "AttributeError" exception. In order to avoid ' - 'infinite recursion in\n' - ' this method, its implementation should always call ' - 'the base class\n' - ' method with the same name to access any attributes ' - 'it needs, for\n' - ' example, "object.__getattribute__(self, name)".\n' - '\n' - ' Note: This method may still be bypassed when ' - 'looking up special\n' - ' methods as the result of implicit invocation via ' - 'language syntax\n' - ' or built-in functions. See *Special method ' - 'lookup*.\n' - '\n' - 'object.__setattr__(self, name, value)\n' - '\n' - ' Called when an attribute assignment is attempted. ' - 'This is called\n' - ' instead of the normal mechanism (i.e. store the ' - 'value in the\n' - ' instance dictionary). *name* is the attribute name, ' - '*value* is the\n' - ' value to be assigned to it.\n' - '\n' - ' If "__setattr__()" wants to assign to an instance ' - 'attribute, it\n' - ' should call the base class method with the same ' - 'name, for example,\n' - ' "object.__setattr__(self, name, value)".\n' - '\n' - 'object.__delattr__(self, name)\n' - '\n' - ' Like "__setattr__()" but for attribute deletion ' - 'instead of\n' - ' assignment. This should only be implemented if ' - '"del obj.name" is\n' - ' meaningful for the object.\n' - '\n' - 'object.__dir__(self)\n' - '\n' - ' Called when "dir()" is called on the object. A ' - 'sequence must be\n' - ' returned. "dir()" converts the returned sequence to ' - 'a list and\n' - ' sorts it.\n' - '\n' - '\n' - 'Implementing Descriptors\n' - '========================\n' - '\n' - 'The following methods only apply when an instance of ' - 'the class\n' - 'containing the method (a so-called *descriptor* class) ' - 'appears in an\n' - '*owner* class (the descriptor must be in either the ' - "owner's class\n" - 'dictionary or in the class dictionary for one of its ' - 'parents). In the\n' - 'examples below, "the attribute" refers to the ' - 'attribute whose name is\n' - "the key of the property in the owner class' " - '"__dict__".\n' - '\n' - 'object.__get__(self, instance, owner)\n' - '\n' - ' Called to get the attribute of the owner class ' - '(class attribute\n' - ' access) or of an instance of that class (instance ' - 'attribute\n' - ' access). *owner* is always the owner class, while ' - '*instance* is the\n' - ' instance that the attribute was accessed through, ' - 'or "None" when\n' - ' the attribute is accessed through the *owner*. ' - 'This method should\n' - ' return the (computed) attribute value or raise an ' - '"AttributeError"\n' - ' exception.\n' - '\n' - 'object.__set__(self, instance, value)\n' - '\n' - ' Called to set the attribute on an instance ' - '*instance* of the owner\n' - ' class to a new value, *value*.\n' - '\n' - 'object.__delete__(self, instance)\n' - '\n' - ' Called to delete the attribute on an instance ' - '*instance* of the\n' - ' owner class.\n' - '\n' - 'The attribute "__objclass__" is interpreted by the ' - '"inspect" module as\n' - 'specifying the class where this object was defined ' - '(setting this\n' - 'appropriately can assist in runtime introspection of ' - 'dynamic class\n' - 'attributes). For callables, it may indicate that an ' - 'instance of the\n' - 'given type (or a subclass) is expected or required as ' - 'the first\n' - 'positional argument (for example, CPython sets this ' - 'attribute for\n' - 'unbound methods that are implemented in C).\n' - '\n' - '\n' - 'Invoking Descriptors\n' - '====================\n' - '\n' - 'In general, a descriptor is an object attribute with ' - '"binding\n' - 'behavior", one whose attribute access has been ' - 'overridden by methods\n' - 'in the descriptor protocol: "__get__()", "__set__()", ' - 'and\n' - '"__delete__()". If any of those methods are defined ' - 'for an object, it\n' - 'is said to be a descriptor.\n' - '\n' - 'The default behavior for attribute access is to get, ' - 'set, or delete\n' - "the attribute from an object's dictionary. For " - 'instance, "a.x" has a\n' - 'lookup chain starting with "a.__dict__[\'x\']", then\n' - '"type(a).__dict__[\'x\']", and continuing through the ' - 'base classes of\n' - '"type(a)" excluding metaclasses.\n' - '\n' - 'However, if the looked-up value is an object defining ' - 'one of the\n' - 'descriptor methods, then Python may override the ' - 'default behavior and\n' - 'invoke the descriptor method instead. Where this ' - 'occurs in the\n' - 'precedence chain depends on which descriptor methods ' - 'were defined and\n' - 'how they were called.\n' - '\n' - 'The starting point for descriptor invocation is a ' - 'binding, "a.x". How\n' - 'the arguments are assembled depends on "a":\n' - '\n' - 'Direct Call\n' - ' The simplest and least common call is when user ' - 'code directly\n' - ' invokes a descriptor method: "x.__get__(a)".\n' - '\n' - 'Instance Binding\n' - ' If binding to an object instance, "a.x" is ' - 'transformed into the\n' - ' call: "type(a).__dict__[\'x\'].__get__(a, ' - 'type(a))".\n' - '\n' - 'Class Binding\n' - ' If binding to a class, "A.x" is transformed into ' - 'the call:\n' - ' "A.__dict__[\'x\'].__get__(None, A)".\n' - '\n' - 'Super Binding\n' - ' If "a" is an instance of "super", then the binding ' - '"super(B,\n' - ' obj).m()" searches "obj.__class__.__mro__" for the ' - 'base class "A"\n' - ' immediately preceding "B" and then invokes the ' - 'descriptor with the\n' - ' call: "A.__dict__[\'m\'].__get__(obj, ' - 'obj.__class__)".\n' - '\n' - 'For instance bindings, the precedence of descriptor ' - 'invocation depends\n' - 'on the which descriptor methods are defined. A ' - 'descriptor can define\n' - 'any combination of "__get__()", "__set__()" and ' - '"__delete__()". If it\n' - 'does not define "__get__()", then accessing the ' - 'attribute will return\n' - 'the descriptor object itself unless there is a value ' - "in the object's\n" - 'instance dictionary. If the descriptor defines ' - '"__set__()" and/or\n' - '"__delete__()", it is a data descriptor; if it defines ' - 'neither, it is\n' - 'a non-data descriptor. Normally, data descriptors ' - 'define both\n' - '"__get__()" and "__set__()", while non-data ' - 'descriptors have just the\n' - '"__get__()" method. Data descriptors with "__set__()" ' - 'and "__get__()"\n' - 'defined always override a redefinition in an instance ' - 'dictionary. In\n' - 'contrast, non-data descriptors can be overridden by ' - 'instances.\n' - '\n' - 'Python methods (including "staticmethod()" and ' - '"classmethod()") are\n' - 'implemented as non-data descriptors. Accordingly, ' - 'instances can\n' - 'redefine and override methods. This allows individual ' - 'instances to\n' - 'acquire behaviors that differ from other instances of ' - 'the same class.\n' - '\n' - 'The "property()" function is implemented as a data ' - 'descriptor.\n' - 'Accordingly, instances cannot override the behavior of ' - 'a property.\n' - '\n' - '\n' - '__slots__\n' - '=========\n' - '\n' - 'By default, instances of classes have a dictionary for ' - 'attribute\n' - 'storage. This wastes space for objects having very ' - 'few instance\n' - 'variables. The space consumption can become acute ' - 'when creating large\n' - 'numbers of instances.\n' - '\n' - 'The default can be overridden by defining *__slots__* ' - 'in a class\n' - 'definition. The *__slots__* declaration takes a ' - 'sequence of instance\n' - 'variables and reserves just enough space in each ' - 'instance to hold a\n' - 'value for each variable. Space is saved because ' - '*__dict__* is not\n' - 'created for each instance.\n' - '\n' - 'object.__slots__\n' - '\n' - ' This class variable can be assigned a string, ' - 'iterable, or sequence\n' - ' of strings with variable names used by instances. ' - '*__slots__*\n' - ' reserves space for the declared variables and ' - 'prevents the\n' - ' automatic creation of *__dict__* and *__weakref__* ' - 'for each\n' - ' instance.\n' - '\n' - '\n' - 'Notes on using *__slots__*\n' - '--------------------------\n' - '\n' - '* When inheriting from a class without *__slots__*, ' - 'the *__dict__*\n' - ' attribute of that class will always be accessible, ' - 'so a *__slots__*\n' - ' definition in the subclass is meaningless.\n' - '\n' - '* Without a *__dict__* variable, instances cannot be ' - 'assigned new\n' - ' variables not listed in the *__slots__* definition. ' - 'Attempts to\n' - ' assign to an unlisted variable name raises ' - '"AttributeError". If\n' - ' dynamic assignment of new variables is desired, then ' - 'add\n' - ' "\'__dict__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' - '\n' - '* Without a *__weakref__* variable for each instance, ' - 'classes\n' - ' defining *__slots__* do not support weak references ' - 'to its\n' - ' instances. If weak reference support is needed, then ' - 'add\n' - ' "\'__weakref__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' - '\n' - '* *__slots__* are implemented at the class level by ' - 'creating\n' - ' descriptors (*Implementing Descriptors*) for each ' - 'variable name. As\n' - ' a result, class attributes cannot be used to set ' - 'default values for\n' - ' instance variables defined by *__slots__*; ' - 'otherwise, the class\n' - ' attribute would overwrite the descriptor ' - 'assignment.\n' - '\n' - '* The action of a *__slots__* declaration is limited ' - 'to the class\n' - ' where it is defined. As a result, subclasses will ' - 'have a *__dict__*\n' - ' unless they also define *__slots__* (which must only ' - 'contain names\n' - ' of any *additional* slots).\n' - '\n' - '* If a class defines a slot also defined in a base ' - 'class, the\n' - ' instance variable defined by the base class slot is ' - 'inaccessible\n' - ' (except by retrieving its descriptor directly from ' - 'the base class).\n' - ' This renders the meaning of the program undefined. ' - 'In the future, a\n' - ' check may be added to prevent this.\n' - '\n' - '* Nonempty *__slots__* does not work for classes ' - 'derived from\n' - ' "variable-length" built-in types such as "int", ' - '"bytes" and "tuple".\n' - '\n' - '* Any non-string iterable may be assigned to ' - '*__slots__*. Mappings\n' - ' may also be used; however, in the future, special ' - 'meaning may be\n' - ' assigned to the values corresponding to each key.\n' - '\n' - '* *__class__* assignment works only if both classes ' - 'have the same\n' - ' *__slots__*.\n', - 'attribute-references': '\n' - 'Attribute references\n' - '********************\n' - '\n' - 'An attribute reference is a primary followed by a ' - 'period and a name:\n' - '\n' - ' attributeref ::= primary "." identifier\n' - '\n' - 'The primary must evaluate to an object of a type ' - 'that supports\n' - 'attribute references, which most objects do. This ' - 'object is then\n' - 'asked to produce the attribute whose name is the ' - 'identifier. This\n' - 'production can be customized by overriding the ' - '"__getattr__()" method.\n' - 'If this attribute is not available, the exception ' - '"AttributeError" is\n' - 'raised. Otherwise, the type and value of the ' - 'object produced is\n' - 'determined by the object. Multiple evaluations of ' - 'the same attribute\n' - 'reference may yield different objects.\n', - 'augassign': '\n' - 'Augmented assignment statements\n' - '*******************************\n' - '\n' - 'Augmented assignment is the combination, in a single ' - 'statement, of a\n' - 'binary operation and an assignment statement:\n' - '\n' - ' augmented_assignment_stmt ::= augtarget augop ' - '(expression_list | yield_expression)\n' - ' augtarget ::= identifier | attributeref | ' - 'subscription | slicing\n' - ' augop ::= "+=" | "-=" | "*=" | "@=" | ' - '"/=" | "//=" | "%=" | "**="\n' - ' | ">>=" | "<<=" | "&=" | "^=" | "|="\n' - '\n' - '(See section *Primaries* for the syntax definitions of the ' - 'last three\n' - 'symbols.)\n' - '\n' - 'An augmented assignment evaluates the target (which, unlike ' - 'normal\n' - 'assignment statements, cannot be an unpacking) and the ' - 'expression\n' - 'list, performs the binary operation specific to the type of ' - 'assignment\n' - 'on the two operands, and assigns the result to the original ' - 'target.\n' - 'The target is only evaluated once.\n' - '\n' - 'An augmented assignment expression like "x += 1" can be ' - 'rewritten as\n' - '"x = x + 1" to achieve a similar, but not exactly equal ' - 'effect. In the\n' - 'augmented version, "x" is only evaluated once. Also, when ' - 'possible,\n' - 'the actual operation is performed *in-place*, meaning that ' - 'rather than\n' - 'creating a new object and assigning that to the target, the ' - 'old object\n' - 'is modified instead.\n' - '\n' - 'Unlike normal assignments, augmented assignments evaluate the ' - 'left-\n' - 'hand side *before* evaluating the right-hand side. For ' - 'example, "a[i]\n' - '+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and ' - 'performs\n' - 'the addition, and lastly, it writes the result back to ' - '"a[i]".\n' - '\n' - 'With the exception of assigning to tuples and multiple ' - 'targets in a\n' - 'single statement, the assignment done by augmented ' - 'assignment\n' - 'statements is handled the same way as normal assignments. ' - 'Similarly,\n' - 'with the exception of the possible *in-place* behavior, the ' - 'binary\n' - 'operation performed by augmented assignment is the same as ' - 'the normal\n' - 'binary operations.\n' - '\n' - 'For targets which are attribute references, the same *caveat ' - 'about\n' - 'class and instance attributes* applies as for regular ' - 'assignments.\n', - 'binary': '\n' - 'Binary arithmetic operations\n' - '****************************\n' - '\n' - 'The binary arithmetic operations have the conventional priority\n' - 'levels. Note that some of these operations also apply to ' - 'certain non-\n' - 'numeric types. Apart from the power operator, there are only ' - 'two\n' - 'levels, one for multiplicative operators and one for additive\n' - 'operators:\n' - '\n' - ' m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |\n' - ' m_expr "//" u_expr| m_expr "/" u_expr |\n' - ' m_expr "%" u_expr\n' - ' a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n' - '\n' - 'The "*" (multiplication) operator yields the product of its ' - 'arguments.\n' - 'The arguments must either both be numbers, or one argument must ' - 'be an\n' - 'integer and the other must be a sequence. In the former case, ' - 'the\n' - 'numbers are converted to a common type and then multiplied ' - 'together.\n' - 'In the latter case, sequence repetition is performed; a ' - 'negative\n' - 'repetition factor yields an empty sequence.\n' - '\n' - 'The "@" (at) operator is intended to be used for matrix\n' - 'multiplication. No builtin Python types implement this ' - 'operator.\n' - '\n' - 'New in version 3.5.\n' - '\n' - 'The "/" (division) and "//" (floor division) operators yield ' - 'the\n' - 'quotient of their arguments. The numeric arguments are first\n' - 'converted to a common type. Division of integers yields a float, ' - 'while\n' - 'floor division of integers results in an integer; the result is ' - 'that\n' - "of mathematical division with the 'floor' function applied to " - 'the\n' - 'result. Division by zero raises the "ZeroDivisionError" ' - 'exception.\n' - '\n' - 'The "%" (modulo) operator yields the remainder from the division ' - 'of\n' - 'the first argument by the second. The numeric arguments are ' - 'first\n' - 'converted to a common type. A zero right argument raises the\n' - '"ZeroDivisionError" exception. The arguments may be floating ' - 'point\n' - 'numbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals ' - '"4*0.7 +\n' - '0.34".) The modulo operator always yields a result with the ' - 'same sign\n' - 'as its second operand (or zero); the absolute value of the ' - 'result is\n' - 'strictly smaller than the absolute value of the second operand ' - '[1].\n' - '\n' - 'The floor division and modulo operators are connected by the ' - 'following\n' - 'identity: "x == (x//y)*y + (x%y)". Floor division and modulo ' - 'are also\n' - 'connected with the built-in function "divmod()": "divmod(x, y) ' - '==\n' - '(x//y, x%y)". [2].\n' - '\n' - 'In addition to performing the modulo operation on numbers, the ' - '"%"\n' - 'operator is also overloaded by string objects to perform ' - 'old-style\n' - 'string formatting (also known as interpolation). The syntax ' - 'for\n' - 'string formatting is described in the Python Library Reference,\n' - 'section *printf-style String Formatting*.\n' - '\n' - 'The floor division operator, the modulo operator, and the ' - '"divmod()"\n' - 'function are not defined for complex numbers. Instead, convert ' - 'to a\n' - 'floating point number using the "abs()" function if ' - 'appropriate.\n' - '\n' - 'The "+" (addition) operator yields the sum of its arguments. ' - 'The\n' - 'arguments must either both be numbers or both be sequences of ' - 'the same\n' - 'type. In the former case, the numbers are converted to a common ' - 'type\n' - 'and then added together. In the latter case, the sequences are\n' - 'concatenated.\n' - '\n' - 'The "-" (subtraction) operator yields the difference of its ' - 'arguments.\n' - 'The numeric arguments are first converted to a common type.\n', - 'bitwise': '\n' - 'Binary bitwise operations\n' - '*************************\n' - '\n' - 'Each of the three bitwise operations has a different priority ' - 'level:\n' - '\n' - ' and_expr ::= shift_expr | and_expr "&" shift_expr\n' - ' xor_expr ::= and_expr | xor_expr "^" and_expr\n' - ' or_expr ::= xor_expr | or_expr "|" xor_expr\n' - '\n' - 'The "&" operator yields the bitwise AND of its arguments, which ' - 'must\n' - 'be integers.\n' - '\n' - 'The "^" operator yields the bitwise XOR (exclusive OR) of its\n' - 'arguments, which must be integers.\n' - '\n' - 'The "|" operator yields the bitwise (inclusive) OR of its ' - 'arguments,\n' - 'which must be integers.\n', - 'bltin-code-objects': '\n' - 'Code Objects\n' - '************\n' - '\n' - 'Code objects are used by the implementation to ' - 'represent "pseudo-\n' - 'compiled" executable Python code such as a function ' - 'body. They differ\n' - "from function objects because they don't contain a " - 'reference to their\n' - 'global execution environment. Code objects are ' - 'returned by the built-\n' - 'in "compile()" function and can be extracted from ' - 'function objects\n' - 'through their "__code__" attribute. See also the ' - '"code" module.\n' - '\n' - 'A code object can be executed or evaluated by ' - 'passing it (instead of a\n' - 'source string) to the "exec()" or "eval()" built-in ' - 'functions.\n' - '\n' - 'See *The standard type hierarchy* for more ' - 'information.\n', - 'bltin-ellipsis-object': '\n' - 'The Ellipsis Object\n' - '*******************\n' - '\n' - 'This object is commonly used by slicing (see ' - '*Slicings*). It supports\n' - 'no special operations. There is exactly one ' - 'ellipsis object, named\n' - '"Ellipsis" (a built-in name). "type(Ellipsis)()" ' - 'produces the\n' - '"Ellipsis" singleton.\n' - '\n' - 'It is written as "Ellipsis" or "...".\n', - 'bltin-null-object': '\n' - 'The Null Object\n' - '***************\n' - '\n' - "This object is returned by functions that don't " - 'explicitly return a\n' - 'value. It supports no special operations. There is ' - 'exactly one null\n' - 'object, named "None" (a built-in name). ' - '"type(None)()" produces the\n' - 'same singleton.\n' - '\n' - 'It is written as "None".\n', - 'bltin-type-objects': '\n' - 'Type Objects\n' - '************\n' - '\n' - 'Type objects represent the various object types. An ' - "object's type is\n" - 'accessed by the built-in function "type()". There ' - 'are no special\n' - 'operations on types. The standard module "types" ' - 'defines names for\n' - 'all standard built-in types.\n' - '\n' - 'Types are written like this: "".\n', - 'booleans': '\n' - 'Boolean operations\n' - '******************\n' - '\n' - ' or_test ::= and_test | or_test "or" and_test\n' - ' and_test ::= not_test | and_test "and" not_test\n' - ' not_test ::= comparison | "not" not_test\n' - '\n' - 'In the context of Boolean operations, and also when ' - 'expressions are\n' - 'used by control flow statements, the following values are ' - 'interpreted\n' - 'as false: "False", "None", numeric zero of all types, and ' - 'empty\n' - 'strings and containers (including strings, tuples, lists,\n' - 'dictionaries, sets and frozensets). All other values are ' - 'interpreted\n' - 'as true. User-defined objects can customize their truth value ' - 'by\n' - 'providing a "__bool__()" method.\n' - '\n' - 'The operator "not" yields "True" if its argument is false, ' - '"False"\n' - 'otherwise.\n' - '\n' - 'The expression "x and y" first evaluates *x*; if *x* is false, ' - 'its\n' - 'value is returned; otherwise, *y* is evaluated and the ' - 'resulting value\n' - 'is returned.\n' - '\n' - 'The expression "x or y" first evaluates *x*; if *x* is true, ' - 'its value\n' - 'is returned; otherwise, *y* is evaluated and the resulting ' - 'value is\n' - 'returned.\n' - '\n' - '(Note that neither "and" nor "or" restrict the value and type ' - 'they\n' - 'return to "False" and "True", but rather return the last ' - 'evaluated\n' - 'argument. This is sometimes useful, e.g., if "s" is a string ' - 'that\n' - 'should be replaced by a default value if it is empty, the ' - 'expression\n' - '"s or \'foo\'" yields the desired value. Because "not" has to ' - 'create a\n' - 'new value, it returns a boolean value regardless of the type ' - 'of its\n' - 'argument (for example, "not \'foo\'" produces "False" rather ' - 'than "\'\'".)\n', - 'break': '\n' - 'The "break" statement\n' - '*********************\n' - '\n' - ' break_stmt ::= "break"\n' - '\n' - '"break" may only occur syntactically nested in a "for" or ' - '"while"\n' - 'loop, but not nested in a function or class definition within ' - 'that\n' - 'loop.\n' - '\n' - 'It terminates the nearest enclosing loop, skipping the optional ' - '"else"\n' - 'clause if the loop has one.\n' - '\n' - 'If a "for" loop is terminated by "break", the loop control ' - 'target\n' - 'keeps its current value.\n' - '\n' - 'When "break" passes control out of a "try" statement with a ' - '"finally"\n' - 'clause, that "finally" clause is executed before really leaving ' - 'the\n' - 'loop.\n', - 'callable-types': '\n' - 'Emulating callable objects\n' - '**************************\n' - '\n' - 'object.__call__(self[, args...])\n' - '\n' - ' Called when the instance is "called" as a function; ' - 'if this method\n' - ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' - ' "x.__call__(arg1, arg2, ...)".\n', - 'calls': '\n' - 'Calls\n' - '*****\n' - '\n' - 'A call calls a callable object (e.g., a *function*) with a ' - 'possibly\n' - 'empty series of *arguments*:\n' - '\n' - ' call ::= primary "(" [argument_list [","] | ' - 'comprehension] ")"\n' - ' argument_list ::= positional_arguments ["," ' - 'keyword_arguments]\n' - ' ["," "*" expression] ["," ' - 'keyword_arguments]\n' - ' ["," "**" expression]\n' - ' | keyword_arguments ["," "*" expression]\n' - ' ["," keyword_arguments] ["," "**" ' - 'expression]\n' - ' | "*" expression ["," keyword_arguments] ' - '["," "**" expression]\n' - ' | "**" expression\n' - ' positional_arguments ::= expression ("," expression)*\n' - ' keyword_arguments ::= keyword_item ("," keyword_item)*\n' - ' keyword_item ::= identifier "=" expression\n' - '\n' - 'An optional trailing comma may be present after the positional ' - 'and\n' - 'keyword arguments but does not affect the semantics.\n' - '\n' - 'The primary must evaluate to a callable object (user-defined\n' - 'functions, built-in functions, methods of built-in objects, ' - 'class\n' - 'objects, methods of class instances, and all objects having a\n' - '"__call__()" method are callable). All argument expressions are\n' - 'evaluated before the call is attempted. Please refer to section\n' - '*Function definitions* for the syntax of formal *parameter* ' - 'lists.\n' - '\n' - 'If keyword arguments are present, they are first converted to\n' - 'positional arguments, as follows. First, a list of unfilled ' - 'slots is\n' - 'created for the formal parameters. If there are N positional\n' - 'arguments, they are placed in the first N slots. Next, for each\n' - 'keyword argument, the identifier is used to determine the\n' - 'corresponding slot (if the identifier is the same as the first ' - 'formal\n' - 'parameter name, the first slot is used, and so on). If the slot ' - 'is\n' - 'already filled, a "TypeError" exception is raised. Otherwise, ' - 'the\n' - 'value of the argument is placed in the slot, filling it (even if ' - 'the\n' - 'expression is "None", it fills the slot). When all arguments ' - 'have\n' - 'been processed, the slots that are still unfilled are filled with ' - 'the\n' - 'corresponding default value from the function definition. ' - '(Default\n' - 'values are calculated, once, when the function is defined; thus, ' - 'a\n' - 'mutable object such as a list or dictionary used as default value ' - 'will\n' - "be shared by all calls that don't specify an argument value for " - 'the\n' - 'corresponding slot; this should usually be avoided.) If there ' - 'are any\n' - 'unfilled slots for which no default value is specified, a ' - '"TypeError"\n' - 'exception is raised. Otherwise, the list of filled slots is used ' - 'as\n' - 'the argument list for the call.\n' - '\n' - '**CPython implementation detail:** An implementation may provide\n' - 'built-in functions whose positional parameters do not have names, ' - 'even\n' - "if they are 'named' for the purpose of documentation, and which\n" - 'therefore cannot be supplied by keyword. In CPython, this is the ' - 'case\n' - 'for functions implemented in C that use "PyArg_ParseTuple()" to ' - 'parse\n' - 'their arguments.\n' - '\n' - 'If there are more positional arguments than there are formal ' - 'parameter\n' - 'slots, a "TypeError" exception is raised, unless a formal ' - 'parameter\n' - 'using the syntax "*identifier" is present; in this case, that ' - 'formal\n' - 'parameter receives a tuple containing the excess positional ' - 'arguments\n' - '(or an empty tuple if there were no excess positional ' - 'arguments).\n' - '\n' - 'If any keyword argument does not correspond to a formal ' - 'parameter\n' - 'name, a "TypeError" exception is raised, unless a formal ' - 'parameter\n' - 'using the syntax "**identifier" is present; in this case, that ' - 'formal\n' - 'parameter receives a dictionary containing the excess keyword\n' - 'arguments (using the keywords as keys and the argument values as\n' - 'corresponding values), or a (new) empty dictionary if there were ' - 'no\n' - 'excess keyword arguments.\n' - '\n' - 'If the syntax "*expression" appears in the function call, ' - '"expression"\n' - 'must evaluate to an iterable. Elements from this iterable are ' - 'treated\n' - 'as if they were additional positional arguments; if there are\n' - 'positional arguments *x1*, ..., *xN*, and "expression" evaluates ' - 'to a\n' - 'sequence *y1*, ..., *yM*, this is equivalent to a call with M+N\n' - 'positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n' - '\n' - 'A consequence of this is that although the "*expression" syntax ' - 'may\n' - 'appear *after* some keyword arguments, it is processed *before* ' - 'the\n' - 'keyword arguments (and the "**expression" argument, if any -- ' - 'see\n' - 'below). So:\n' - '\n' - ' >>> def f(a, b):\n' - ' ... print(a, b)\n' - ' ...\n' - ' >>> f(b=1, *(2,))\n' - ' 2 1\n' - ' >>> f(a=1, *(2,))\n' - ' Traceback (most recent call last):\n' - ' File "", line 1, in ?\n' - " TypeError: f() got multiple values for keyword argument 'a'\n" - ' >>> f(1, *(2,))\n' - ' 1 2\n' - '\n' - 'It is unusual for both keyword arguments and the "*expression" ' - 'syntax\n' - 'to be used in the same call, so in practice this confusion does ' - 'not\n' - 'arise.\n' - '\n' - 'If the syntax "**expression" appears in the function call,\n' - '"expression" must evaluate to a mapping, the contents of which ' - 'are\n' - 'treated as additional keyword arguments. In the case of a ' - 'keyword\n' - 'appearing in both "expression" and as an explicit keyword ' - 'argument, a\n' - '"TypeError" exception is raised.\n' - '\n' - 'Formal parameters using the syntax "*identifier" or ' - '"**identifier"\n' - 'cannot be used as positional argument slots or as keyword ' - 'argument\n' - 'names.\n' - '\n' - 'A call always returns some value, possibly "None", unless it ' - 'raises an\n' - 'exception. How this value is computed depends on the type of ' - 'the\n' - 'callable object.\n' - '\n' - 'If it is---\n' - '\n' - 'a user-defined function:\n' - ' The code block for the function is executed, passing it the\n' - ' argument list. The first thing the code block will do is bind ' - 'the\n' - ' formal parameters to the arguments; this is described in ' - 'section\n' - ' *Function definitions*. When the code block executes a ' - '"return"\n' - ' statement, this specifies the return value of the function ' - 'call.\n' - '\n' - 'a built-in function or method:\n' - ' The result is up to the interpreter; see *Built-in Functions* ' - 'for\n' - ' the descriptions of built-in functions and methods.\n' - '\n' - 'a class object:\n' - ' A new instance of that class is returned.\n' - '\n' - 'a class instance method:\n' - ' The corresponding user-defined function is called, with an ' - 'argument\n' - ' list that is one longer than the argument list of the call: ' - 'the\n' - ' instance becomes the first argument.\n' - '\n' - 'a class instance:\n' - ' The class must define a "__call__()" method; the effect is ' - 'then the\n' - ' same as if that method was called.\n', - 'class': '\n' - 'Class definitions\n' - '*****************\n' - '\n' - 'A class definition defines a class object (see section *The ' - 'standard\n' - 'type hierarchy*):\n' - '\n' - ' classdef ::= [decorators] "class" classname [inheritance] ' - '":" suite\n' - ' inheritance ::= "(" [parameter_list] ")"\n' - ' classname ::= identifier\n' - '\n' - 'A class definition is an executable statement. The inheritance ' - 'list\n' - 'usually gives a list of base classes (see *Customizing class ' - 'creation*\n' - 'for more advanced uses), so each item in the list should evaluate ' - 'to a\n' - 'class object which allows subclassing. Classes without an ' - 'inheritance\n' - 'list inherit, by default, from the base class "object"; hence,\n' - '\n' - ' class Foo:\n' - ' pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' class Foo(object):\n' - ' pass\n' - '\n' - "The class's suite is then executed in a new execution frame (see\n" - '*Naming and binding*), using a newly created local namespace and ' - 'the\n' - 'original global namespace. (Usually, the suite contains mostly\n' - "function definitions.) When the class's suite finishes " - 'execution, its\n' - 'execution frame is discarded but its local namespace is saved. ' - '[4] A\n' - 'class object is then created using the inheritance list for the ' - 'base\n' - 'classes and the saved local namespace for the attribute ' - 'dictionary.\n' - 'The class name is bound to this class object in the original ' - 'local\n' - 'namespace.\n' - '\n' - 'Class creation can be customized heavily using *metaclasses*.\n' - '\n' - 'Classes can also be decorated: just like when decorating ' - 'functions,\n' - '\n' - ' @f1(arg)\n' - ' @f2\n' - ' class Foo: pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' class Foo: pass\n' - ' Foo = f1(arg)(f2(Foo))\n' - '\n' - 'The evaluation rules for the decorator expressions are the same ' - 'as for\n' - 'function decorators. The result must be a class object, which is ' - 'then\n' - 'bound to the class name.\n' - '\n' - "**Programmer's note:** Variables defined in the class definition " - 'are\n' - 'class attributes; they are shared by instances. Instance ' - 'attributes\n' - 'can be set in a method with "self.name = value". Both class and\n' - 'instance attributes are accessible through the notation ' - '""self.name"",\n' - 'and an instance attribute hides a class attribute with the same ' - 'name\n' - 'when accessed in this way. Class attributes can be used as ' - 'defaults\n' - 'for instance attributes, but using mutable values there can lead ' - 'to\n' - 'unexpected results. *Descriptors* can be used to create ' - 'instance\n' - 'variables with different implementation details.\n' - '\n' - 'See also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n' - ' Class Decorators\n', - 'comparisons': '\n' - 'Comparisons\n' - '***********\n' - '\n' - 'Unlike C, all comparison operations in Python have the same ' - 'priority,\n' - 'which is lower than that of any arithmetic, shifting or ' - 'bitwise\n' - 'operation. Also unlike C, expressions like "a < b < c" ' - 'have the\n' - 'interpretation that is conventional in mathematics:\n' - '\n' - ' comparison ::= or_expr ( comp_operator or_expr )*\n' - ' comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n' - ' | "is" ["not"] | ["not"] "in"\n' - '\n' - 'Comparisons yield boolean values: "True" or "False".\n' - '\n' - 'Comparisons can be chained arbitrarily, e.g., "x < y <= z" ' - 'is\n' - 'equivalent to "x < y and y <= z", except that "y" is ' - 'evaluated only\n' - 'once (but in both cases "z" is not evaluated at all when "x ' - '< y" is\n' - 'found to be false).\n' - '\n' - 'Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions ' - 'and *op1*,\n' - '*op2*, ..., *opN* are comparison operators, then "a op1 b ' - 'op2 c ... y\n' - 'opN z" is equivalent to "a op1 b and b op2 c and ... y opN ' - 'z", except\n' - 'that each expression is evaluated at most once.\n' - '\n' - 'Note that "a op1 b op2 c" doesn\'t imply any kind of ' - 'comparison between\n' - '*a* and *c*, so that, e.g., "x < y > z" is perfectly legal ' - '(though\n' - 'perhaps not pretty).\n' - '\n' - 'The operators "<", ">", "==", ">=", "<=", and "!=" compare ' - 'the values\n' - 'of two objects. The objects need not have the same type. ' - 'If both are\n' - 'numbers, they are converted to a common type. Otherwise, ' - 'the "==" and\n' - '"!=" operators *always* consider objects of different types ' - 'to be\n' - 'unequal, while the "<", ">", ">=" and "<=" operators raise ' - 'a\n' - '"TypeError" when comparing objects of different types that ' - 'do not\n' - 'implement these operators for the given pair of types. You ' - 'can\n' - 'control comparison behavior of objects of non-built-in ' - 'types by\n' - 'defining rich comparison methods like "__gt__()", described ' - 'in section\n' - '*Basic customization*.\n' - '\n' - 'Comparison of objects of the same type depends on the ' - 'type:\n' - '\n' - '* Numbers are compared arithmetically.\n' - '\n' - '* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are ' - 'special. They\n' - ' are identical to themselves, "x is x" but are not equal ' - 'to\n' - ' themselves, "x != x". Additionally, comparing any value ' - 'to a\n' - ' not-a-number value will return "False". For example, ' - 'both "3 <\n' - ' float(\'NaN\')" and "float(\'NaN\') < 3" will return ' - '"False".\n' - '\n' - '* Bytes objects are compared lexicographically using the ' - 'numeric\n' - ' values of their elements.\n' - '\n' - '* Strings are compared lexicographically using the numeric\n' - ' equivalents (the result of the built-in function "ord()") ' - 'of their\n' - " characters. [3] String and bytes object can't be " - 'compared!\n' - '\n' - '* Tuples and lists are compared lexicographically using ' - 'comparison\n' - ' of corresponding elements. This means that to compare ' - 'equal, each\n' - ' element must compare equal and the two sequences must be ' - 'of the same\n' - ' type and have the same length.\n' - '\n' - ' If not equal, the sequences are ordered the same as their ' - 'first\n' - ' differing elements. For example, "[1,2,x] <= [1,2,y]" ' - 'has the same\n' - ' value as "x <= y". If the corresponding element does not ' - 'exist, the\n' - ' shorter sequence is ordered first (for example, "[1,2] < ' - '[1,2,3]").\n' - '\n' - '* Mappings (dictionaries) compare equal if and only if they ' - 'have the\n' - ' same "(key, value)" pairs. Order comparisons "(\'<\', ' - "'<=', '>=',\n" - ' \'>\')" raise "TypeError".\n' - '\n' - '* Sets and frozensets define comparison operators to mean ' - 'subset and\n' - ' superset tests. Those relations do not define total ' - 'orderings (the\n' - ' two sets "{1,2}" and "{2,3}" are not equal, nor subsets ' - 'of one\n' - ' another, nor supersets of one another). Accordingly, ' - 'sets are not\n' - ' appropriate arguments for functions which depend on total ' - 'ordering.\n' - ' For example, "min()", "max()", and "sorted()" produce ' - 'undefined\n' - ' results given a list of sets as inputs.\n' - '\n' - '* Most other objects of built-in types compare unequal ' - 'unless they\n' - ' are the same object; the choice whether one object is ' - 'considered\n' - ' smaller or larger than another one is made arbitrarily ' - 'but\n' - ' consistently within one execution of a program.\n' - '\n' - 'Comparison of objects of differing types depends on whether ' - 'either of\n' - 'the types provide explicit support for the comparison. ' - 'Most numeric\n' - 'types can be compared with one another. When cross-type ' - 'comparison is\n' - 'not supported, the comparison method returns ' - '"NotImplemented".\n' - '\n' - 'The operators "in" and "not in" test for membership. "x in ' - 's"\n' - 'evaluates to true if *x* is a member of *s*, and false ' - 'otherwise. "x\n' - 'not in s" returns the negation of "x in s". All built-in ' - 'sequences\n' - 'and set types support this as well as dictionary, for which ' - '"in" tests\n' - 'whether the dictionary has a given key. For container types ' - 'such as\n' - 'list, tuple, set, frozenset, dict, or collections.deque, ' - 'the\n' - 'expression "x in y" is equivalent to "any(x is e or x == e ' - 'for e in\n' - 'y)".\n' - '\n' - 'For the string and bytes types, "x in y" is true if and ' - 'only if *x* is\n' - 'a substring of *y*. An equivalent test is "y.find(x) != ' - '-1". Empty\n' - 'strings are always considered to be a substring of any ' - 'other string,\n' - 'so """ in "abc"" will return "True".\n' - '\n' - 'For user-defined classes which define the "__contains__()" ' - 'method, "x\n' - 'in y" is true if and only if "y.__contains__(x)" is true.\n' - '\n' - 'For user-defined classes which do not define ' - '"__contains__()" but do\n' - 'define "__iter__()", "x in y" is true if some value "z" ' - 'with "x == z"\n' - 'is produced while iterating over "y". If an exception is ' - 'raised\n' - 'during the iteration, it is as if "in" raised that ' - 'exception.\n' - '\n' - 'Lastly, the old-style iteration protocol is tried: if a ' - 'class defines\n' - '"__getitem__()", "x in y" is true if and only if there is a ' - 'non-\n' - 'negative integer index *i* such that "x == y[i]", and all ' - 'lower\n' - 'integer indices do not raise "IndexError" exception. (If ' - 'any other\n' - 'exception is raised, it is as if "in" raised that ' - 'exception).\n' - '\n' - 'The operator "not in" is defined to have the inverse true ' - 'value of\n' - '"in".\n' - '\n' - 'The operators "is" and "is not" test for object identity: ' - '"x is y" is\n' - 'true if and only if *x* and *y* are the same object. "x is ' - 'not y"\n' - 'yields the inverse truth value. [4]\n', - 'compound': '\n' - 'Compound statements\n' - '*******************\n' - '\n' - 'Compound statements contain (groups of) other statements; they ' - 'affect\n' - 'or control the execution of those other statements in some ' - 'way. In\n' - 'general, compound statements span multiple lines, although in ' - 'simple\n' - 'incarnations a whole compound statement may be contained in ' - 'one line.\n' - '\n' - 'The "if", "while" and "for" statements implement traditional ' - 'control\n' - 'flow constructs. "try" specifies exception handlers and/or ' - 'cleanup\n' - 'code for a group of statements, while the "with" statement ' - 'allows the\n' - 'execution of initialization and finalization code around a ' - 'block of\n' - 'code. Function and class definitions are also syntactically ' - 'compound\n' - 'statements.\n' - '\n' - "A compound statement consists of one or more 'clauses.' A " - 'clause\n' - "consists of a header and a 'suite.' The clause headers of a\n" - 'particular compound statement are all at the same indentation ' - 'level.\n' - 'Each clause header begins with a uniquely identifying keyword ' - 'and ends\n' - 'with a colon. A suite is a group of statements controlled by ' - 'a\n' - 'clause. A suite can be one or more semicolon-separated ' - 'simple\n' - 'statements on the same line as the header, following the ' - "header's\n" - 'colon, or it can be one or more indented statements on ' - 'subsequent\n' - 'lines. Only the latter form of a suite can contain nested ' - 'compound\n' - 'statements; the following is illegal, mostly because it ' - "wouldn't be\n" - 'clear to which "if" clause a following "else" clause would ' - 'belong:\n' - '\n' - ' if test1: if test2: print(x)\n' - '\n' - 'Also note that the semicolon binds tighter than the colon in ' - 'this\n' - 'context, so that in the following example, either all or none ' - 'of the\n' - '"print()" calls are executed:\n' - '\n' - ' if x < y < z: print(x); print(y); print(z)\n' - '\n' - 'Summarizing:\n' - '\n' - ' compound_stmt ::= if_stmt\n' - ' | while_stmt\n' - ' | for_stmt\n' - ' | try_stmt\n' - ' | with_stmt\n' - ' | funcdef\n' - ' | classdef\n' - ' | async_with_stmt\n' - ' | async_for_stmt\n' - ' | async_funcdef\n' - ' suite ::= stmt_list NEWLINE | NEWLINE INDENT ' - 'statement+ DEDENT\n' - ' statement ::= stmt_list NEWLINE | compound_stmt\n' - ' stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n' - '\n' - 'Note that statements always end in a "NEWLINE" possibly ' - 'followed by a\n' - '"DEDENT". Also note that optional continuation clauses always ' - 'begin\n' - 'with a keyword that cannot start a statement, thus there are ' - 'no\n' - 'ambiguities (the \'dangling "else"\' problem is solved in ' - 'Python by\n' - 'requiring nested "if" statements to be indented).\n' - '\n' - 'The formatting of the grammar rules in the following sections ' - 'places\n' - 'each clause on a separate line for clarity.\n' - '\n' - '\n' - 'The "if" statement\n' - '==================\n' - '\n' - 'The "if" statement is used for conditional execution:\n' - '\n' - ' if_stmt ::= "if" expression ":" suite\n' - ' ( "elif" expression ":" suite )*\n' - ' ["else" ":" suite]\n' - '\n' - 'It selects exactly one of the suites by evaluating the ' - 'expressions one\n' - 'by one until one is found to be true (see section *Boolean ' - 'operations*\n' - 'for the definition of true and false); then that suite is ' - 'executed\n' - '(and no other part of the "if" statement is executed or ' - 'evaluated).\n' - 'If all expressions are false, the suite of the "else" clause, ' - 'if\n' - 'present, is executed.\n' - '\n' - '\n' - 'The "while" statement\n' - '=====================\n' - '\n' - 'The "while" statement is used for repeated execution as long ' - 'as an\n' - 'expression is true:\n' - '\n' - ' while_stmt ::= "while" expression ":" suite\n' - ' ["else" ":" suite]\n' - '\n' - 'This repeatedly tests the expression and, if it is true, ' - 'executes the\n' - 'first suite; if the expression is false (which may be the ' - 'first time\n' - 'it is tested) the suite of the "else" clause, if present, is ' - 'executed\n' - 'and the loop terminates.\n' - '\n' - 'A "break" statement executed in the first suite terminates the ' - 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' - 'statement\n' - 'executed in the first suite skips the rest of the suite and ' - 'goes back\n' - 'to testing the expression.\n' - '\n' - '\n' - 'The "for" statement\n' - '===================\n' - '\n' - 'The "for" statement is used to iterate over the elements of a ' - 'sequence\n' - '(such as a string, tuple or list) or other iterable object:\n' - '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" ' - 'suite\n' - ' ["else" ":" suite]\n' - '\n' - 'The expression list is evaluated once; it should yield an ' - 'iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each ' - 'item\n' - 'provided by the iterator, in the order returned by the ' - 'iterator. Each\n' - 'item in turn is assigned to the target list using the standard ' - 'rules\n' - 'for assignments (see *Assignment statements*), and then the ' - 'suite is\n' - 'executed. When the items are exhausted (which is immediately ' - 'when the\n' - 'sequence is empty or an iterator raises a "StopIteration" ' - 'exception),\n' - 'the suite in the "else" clause, if present, is executed, and ' - 'the loop\n' - 'terminates.\n' - '\n' - 'A "break" statement executed in the first suite terminates the ' - 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' - 'statement\n' - 'executed in the first suite skips the rest of the suite and ' - 'continues\n' - 'with the next item, or with the "else" clause if there is no ' - 'next\n' - 'item.\n' - '\n' - 'The for-loop makes assignments to the variables(s) in the ' - 'target list.\n' - 'This overwrites all previous assignments to those variables ' - 'including\n' - 'those made in the suite of the for-loop:\n' - '\n' - ' for i in range(10):\n' - ' print(i)\n' - ' i = 5 # this will not affect the for-loop\n' - ' # because i will be overwritten with ' - 'the next\n' - ' # index in the range\n' - '\n' - 'Names in the target list are not deleted when the loop is ' - 'finished,\n' - 'but if the sequence is empty, they will not have been assigned ' - 'to at\n' - 'all by the loop. Hint: the built-in function "range()" ' - 'returns an\n' - 'iterator of integers suitable to emulate the effect of ' - 'Pascal\'s "for i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' - '2]".\n' - '\n' - 'Note: There is a subtlety when the sequence is being modified ' - 'by the\n' - ' loop (this can only occur for mutable sequences, i.e. ' - 'lists). An\n' - ' internal counter is used to keep track of which item is used ' - 'next,\n' - ' and this is incremented on each iteration. When this ' - 'counter has\n' - ' reached the length of the sequence the loop terminates. ' - 'This means\n' - ' that if the suite deletes the current (or a previous) item ' - 'from the\n' - ' sequence, the next item will be skipped (since it gets the ' - 'index of\n' - ' the current item which has already been treated). Likewise, ' - 'if the\n' - ' suite inserts an item in the sequence before the current ' - 'item, the\n' - ' current item will be treated again the next time through the ' - 'loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n' - '\n' - '\n' - 'The "try" statement\n' - '===================\n' - '\n' - 'The "try" statement specifies exception handlers and/or ' - 'cleanup code\n' - 'for a group of statements:\n' - '\n' - ' try_stmt ::= try1_stmt | try2_stmt\n' - ' try1_stmt ::= "try" ":" suite\n' - ' ("except" [expression ["as" identifier]] ":" ' - 'suite)+\n' - ' ["else" ":" suite]\n' - ' ["finally" ":" suite]\n' - ' try2_stmt ::= "try" ":" suite\n' - ' "finally" ":" suite\n' - '\n' - 'The "except" clause(s) specify one or more exception handlers. ' - 'When no\n' - 'exception occurs in the "try" clause, no exception handler is\n' - 'executed. When an exception occurs in the "try" suite, a ' - 'search for an\n' - 'exception handler is started. This search inspects the except ' - 'clauses\n' - 'in turn until one is found that matches the exception. An ' - 'expression-\n' - 'less except clause, if present, must be last; it matches any\n' - 'exception. For an except clause with an expression, that ' - 'expression\n' - 'is evaluated, and the clause matches the exception if the ' - 'resulting\n' - 'object is "compatible" with the exception. An object is ' - 'compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object or a tuple containing an item compatible with the ' - 'exception.\n' - '\n' - 'If no except clause matches the exception, the search for an ' - 'exception\n' - 'handler continues in the surrounding code and on the ' - 'invocation stack.\n' - '[1]\n' - '\n' - 'If the evaluation of an expression in the header of an except ' - 'clause\n' - 'raises an exception, the original search for a handler is ' - 'canceled and\n' - 'a search starts for the new exception in the surrounding code ' - 'and on\n' - 'the call stack (it is treated as if the entire "try" statement ' - 'raised\n' - 'the exception).\n' - '\n' - 'When a matching except clause is found, the exception is ' - 'assigned to\n' - 'the target specified after the "as" keyword in that except ' - 'clause, if\n' - "present, and the except clause's suite is executed. All " - 'except\n' - 'clauses must have an executable block. When the end of this ' - 'block is\n' - 'reached, execution continues normally after the entire try ' - 'statement.\n' - '(This means that if two nested handlers exist for the same ' - 'exception,\n' - 'and the exception occurs in the try clause of the inner ' - 'handler, the\n' - 'outer handler will not handle the exception.)\n' - '\n' - 'When an exception has been assigned using "as target", it is ' - 'cleared\n' - 'at the end of the except clause. This is as if\n' - '\n' - ' except E as N:\n' - ' foo\n' - '\n' - 'was translated to\n' - '\n' - ' except E as N:\n' - ' try:\n' - ' foo\n' - ' finally:\n' - ' del N\n' - '\n' - 'This means the exception must be assigned to a different name ' - 'to be\n' - 'able to refer to it after the except clause. Exceptions are ' - 'cleared\n' - 'because with the traceback attached to them, they form a ' - 'reference\n' - 'cycle with the stack frame, keeping all locals in that frame ' - 'alive\n' - 'until the next garbage collection occurs.\n' - '\n' - "Before an except clause's suite is executed, details about " - 'the\n' - 'exception are stored in the "sys" module and can be accessed ' - 'via\n' - '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple ' - 'consisting of the\n' - 'exception class, the exception instance and a traceback object ' - '(see\n' - 'section *The standard type hierarchy*) identifying the point ' - 'in the\n' - 'program where the exception occurred. "sys.exc_info()" values ' - 'are\n' - 'restored to their previous values (before the call) when ' - 'returning\n' - 'from a function that handled an exception.\n' - '\n' - 'The optional "else" clause is executed if and when control ' - 'flows off\n' - 'the end of the "try" clause. [2] Exceptions in the "else" ' - 'clause are\n' - 'not handled by the preceding "except" clauses.\n' - '\n' - 'If "finally" is present, it specifies a \'cleanup\' handler. ' - 'The "try"\n' - 'clause is executed, including any "except" and "else" ' - 'clauses. If an\n' - 'exception occurs in any of the clauses and is not handled, ' - 'the\n' - 'exception is temporarily saved. The "finally" clause is ' - 'executed. If\n' - 'there is a saved exception it is re-raised at the end of the ' - '"finally"\n' - 'clause. If the "finally" clause raises another exception, the ' - 'saved\n' - 'exception is set as the context of the new exception. If the ' - '"finally"\n' - 'clause executes a "return" or "break" statement, the saved ' - 'exception\n' - 'is discarded:\n' - '\n' - ' >>> def f():\n' - ' ... try:\n' - ' ... 1/0\n' - ' ... finally:\n' - ' ... return 42\n' - ' ...\n' - ' >>> f()\n' - ' 42\n' - '\n' - 'The exception information is not available to the program ' - 'during\n' - 'execution of the "finally" clause.\n' - '\n' - 'When a "return", "break" or "continue" statement is executed ' - 'in the\n' - '"try" suite of a "try"..."finally" statement, the "finally" ' - 'clause is\n' - 'also executed \'on the way out.\' A "continue" statement is ' - 'illegal in\n' - 'the "finally" clause. (The reason is a problem with the ' - 'current\n' - 'implementation --- this restriction may be lifted in the ' - 'future).\n' - '\n' - 'The return value of a function is determined by the last ' - '"return"\n' - 'statement executed. Since the "finally" clause always ' - 'executes, a\n' - '"return" statement executed in the "finally" clause will ' - 'always be the\n' - 'last one executed:\n' - '\n' - ' >>> def foo():\n' - ' ... try:\n' - " ... return 'try'\n" - ' ... finally:\n' - " ... return 'finally'\n" - ' ...\n' - ' >>> foo()\n' - " 'finally'\n" - '\n' - 'Additional information on exceptions can be found in section\n' - '*Exceptions*, and information on using the "raise" statement ' - 'to\n' - 'generate exceptions may be found in section *The raise ' - 'statement*.\n' - '\n' - '\n' - 'The "with" statement\n' - '====================\n' - '\n' - 'The "with" statement is used to wrap the execution of a block ' - 'with\n' - 'methods defined by a context manager (see section *With ' - 'Statement\n' - 'Context Managers*). This allows common ' - '"try"..."except"..."finally"\n' - 'usage patterns to be encapsulated for convenient reuse.\n' - '\n' - ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' - ' with_item ::= expression ["as" target]\n' - '\n' - 'The execution of the "with" statement with one "item" proceeds ' - 'as\n' - 'follows:\n' - '\n' - '1. The context expression (the expression given in the ' - '"with_item")\n' - ' is evaluated to obtain a context manager.\n' - '\n' - '2. The context manager\'s "__exit__()" is loaded for later ' - 'use.\n' - '\n' - '3. The context manager\'s "__enter__()" method is invoked.\n' - '\n' - '4. If a target was included in the "with" statement, the ' - 'return\n' - ' value from "__enter__()" is assigned to it.\n' - '\n' - ' Note: The "with" statement guarantees that if the ' - '"__enter__()"\n' - ' method returns without an error, then "__exit__()" will ' - 'always be\n' - ' called. Thus, if an error occurs during the assignment to ' - 'the\n' - ' target list, it will be treated the same as an error ' - 'occurring\n' - ' within the suite would be. See step 6 below.\n' - '\n' - '5. The suite is executed.\n' - '\n' - '6. The context manager\'s "__exit__()" method is invoked. If ' - 'an\n' - ' exception caused the suite to be exited, its type, value, ' - 'and\n' - ' traceback are passed as arguments to "__exit__()". ' - 'Otherwise, three\n' - ' "None" arguments are supplied.\n' - '\n' - ' If the suite was exited due to an exception, and the return ' - 'value\n' - ' from the "__exit__()" method was false, the exception is ' - 'reraised.\n' - ' If the return value was true, the exception is suppressed, ' - 'and\n' - ' execution continues with the statement following the ' - '"with"\n' - ' statement.\n' - '\n' - ' If the suite was exited for any reason other than an ' - 'exception, the\n' - ' return value from "__exit__()" is ignored, and execution ' - 'proceeds\n' - ' at the normal location for the kind of exit that was ' - 'taken.\n' - '\n' - 'With more than one item, the context managers are processed as ' - 'if\n' - 'multiple "with" statements were nested:\n' - '\n' - ' with A() as a, B() as b:\n' - ' suite\n' - '\n' - 'is equivalent to\n' - '\n' - ' with A() as a:\n' - ' with B() as b:\n' - ' suite\n' - '\n' - 'Changed in version 3.1: Support for multiple context ' - 'expressions.\n' - '\n' - 'See also: **PEP 0343** - The "with" statement\n' - '\n' - ' The specification, background, and examples for the ' - 'Python "with"\n' - ' statement.\n' - '\n' - '\n' - 'Function definitions\n' - '====================\n' - '\n' - 'A function definition defines a user-defined function object ' - '(see\n' - 'section *The standard type hierarchy*):\n' - '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")" ["->" expression] ":" suite\n' - ' decorators ::= decorator+\n' - ' decorator ::= "@" dotted_name ["(" [parameter_list ' - '[","]] ")"] NEWLINE\n' - ' dotted_name ::= identifier ("." identifier)*\n' - ' parameter_list ::= (defparameter ",")*\n' - ' | "*" [parameter] ("," defparameter)* ' - '["," "**" parameter]\n' - ' | "**" parameter\n' - ' | defparameter [","] )\n' - ' parameter ::= identifier [":" expression]\n' - ' defparameter ::= parameter ["=" expression]\n' - ' funcname ::= identifier\n' - '\n' - 'A function definition is an executable statement. Its ' - 'execution binds\n' - 'the function name in the current local namespace to a function ' - 'object\n' - '(a wrapper around the executable code for the function). ' - 'This\n' - 'function object contains a reference to the current global ' - 'namespace\n' - 'as the global namespace to be used when the function is ' - 'called.\n' - '\n' - 'The function definition does not execute the function body; ' - 'this gets\n' - 'executed only when the function is called. [3]\n' - '\n' - 'A function definition may be wrapped by one or more ' - '*decorator*\n' - 'expressions. Decorator expressions are evaluated when the ' - 'function is\n' - 'defined, in the scope that contains the function definition. ' - 'The\n' - 'result must be a callable, which is invoked with the function ' - 'object\n' - 'as the only argument. The returned value is bound to the ' - 'function name\n' - 'instead of the function object. Multiple decorators are ' - 'applied in\n' - 'nested fashion. For example, the following code\n' - '\n' - ' @f1(arg)\n' - ' @f2\n' - ' def func(): pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' def func(): pass\n' - ' func = f1(arg)(f2(func))\n' - '\n' - 'When one or more *parameters* have the form *parameter* "="\n' - '*expression*, the function is said to have "default parameter ' - 'values."\n' - 'For a parameter with a default value, the corresponding ' - '*argument* may\n' - "be omitted from a call, in which case the parameter's default " - 'value is\n' - 'substituted. If a parameter has a default value, all ' - 'following\n' - 'parameters up until the ""*"" must also have a default value ' - '--- this\n' - 'is a syntactic restriction that is not expressed by the ' - 'grammar.\n' - '\n' - '**Default parameter values are evaluated from left to right ' - 'when the\n' - 'function definition is executed.** This means that the ' - 'expression is\n' - 'evaluated once, when the function is defined, and that the ' - 'same "pre-\n' - 'computed" value is used for each call. This is especially ' - 'important\n' - 'to understand when a default parameter is a mutable object, ' - 'such as a\n' - 'list or a dictionary: if the function modifies the object ' - '(e.g. by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body ' - 'of the\n' - 'function, e.g.:\n' - '\n' - ' def whats_on_the_telly(penguin=None):\n' - ' if penguin is None:\n' - ' penguin = []\n' - ' penguin.append("property of the zoo")\n' - ' return penguin\n' - '\n' - 'Function call semantics are described in more detail in ' - 'section\n' - '*Calls*. A function call always assigns values to all ' - 'parameters\n' - 'mentioned in the parameter list, either from position ' - 'arguments, from\n' - 'keyword arguments, or from default values. If the form\n' - '""*identifier"" is present, it is initialized to a tuple ' - 'receiving any\n' - 'excess positional parameters, defaulting to the empty tuple. ' - 'If the\n' - 'form ""**identifier"" is present, it is initialized to a new\n' - 'dictionary receiving any excess keyword arguments, defaulting ' - 'to a new\n' - 'empty dictionary. Parameters after ""*"" or ""*identifier"" ' - 'are\n' - 'keyword-only parameters and may only be passed used keyword ' - 'arguments.\n' - '\n' - 'Parameters may have annotations of the form "": expression"" ' - 'following\n' - 'the parameter name. Any parameter may have an annotation even ' - 'those\n' - 'of the form "*identifier" or "**identifier". Functions may ' - 'have\n' - '"return" annotation of the form ""-> expression"" after the ' - 'parameter\n' - 'list. These annotations can be any valid Python expression ' - 'and are\n' - 'evaluated when the function definition is executed. ' - 'Annotations may\n' - 'be evaluated in a different order than they appear in the ' - 'source code.\n' - 'The presence of annotations does not change the semantics of ' - 'a\n' - 'function. The annotation values are available as values of a\n' - "dictionary keyed by the parameters' names in the " - '"__annotations__"\n' - 'attribute of the function object.\n' - '\n' - 'It is also possible to create anonymous functions (functions ' - 'not bound\n' - 'to a name), for immediate use in expressions. This uses ' - 'lambda\n' - 'expressions, described in section *Lambdas*. Note that the ' - 'lambda\n' - 'expression is merely a shorthand for a simplified function ' - 'definition;\n' - 'a function defined in a ""def"" statement can be passed around ' - 'or\n' - 'assigned to another name just like a function defined by a ' - 'lambda\n' - 'expression. The ""def"" form is actually more powerful since ' - 'it\n' - 'allows the execution of multiple statements and annotations.\n' - '\n' - "**Programmer's note:** Functions are first-class objects. A " - '""def""\n' - 'statement executed inside a function definition defines a ' - 'local\n' - 'function that can be returned or passed around. Free ' - 'variables used\n' - 'in the nested function can access the local variables of the ' - 'function\n' - 'containing the def. See section *Naming and binding* for ' - 'details.\n' - '\n' - 'See also: **PEP 3107** - Function Annotations\n' - '\n' - ' The original specification for function annotations.\n' - '\n' - '\n' - 'Class definitions\n' - '=================\n' - '\n' - 'A class definition defines a class object (see section *The ' - 'standard\n' - 'type hierarchy*):\n' - '\n' - ' classdef ::= [decorators] "class" classname ' - '[inheritance] ":" suite\n' - ' inheritance ::= "(" [parameter_list] ")"\n' - ' classname ::= identifier\n' - '\n' - 'A class definition is an executable statement. The ' - 'inheritance list\n' - 'usually gives a list of base classes (see *Customizing class ' - 'creation*\n' - 'for more advanced uses), so each item in the list should ' - 'evaluate to a\n' - 'class object which allows subclassing. Classes without an ' - 'inheritance\n' - 'list inherit, by default, from the base class "object"; ' - 'hence,\n' - '\n' - ' class Foo:\n' - ' pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' class Foo(object):\n' - ' pass\n' - '\n' - "The class's suite is then executed in a new execution frame " - '(see\n' - '*Naming and binding*), using a newly created local namespace ' - 'and the\n' - 'original global namespace. (Usually, the suite contains ' - 'mostly\n' - "function definitions.) When the class's suite finishes " - 'execution, its\n' - 'execution frame is discarded but its local namespace is saved. ' - '[4] A\n' - 'class object is then created using the inheritance list for ' - 'the base\n' - 'classes and the saved local namespace for the attribute ' - 'dictionary.\n' - 'The class name is bound to this class object in the original ' - 'local\n' - 'namespace.\n' - '\n' - 'Class creation can be customized heavily using *metaclasses*.\n' - '\n' - 'Classes can also be decorated: just like when decorating ' - 'functions,\n' - '\n' - ' @f1(arg)\n' - ' @f2\n' - ' class Foo: pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' class Foo: pass\n' - ' Foo = f1(arg)(f2(Foo))\n' - '\n' - 'The evaluation rules for the decorator expressions are the ' - 'same as for\n' - 'function decorators. The result must be a class object, which ' - 'is then\n' - 'bound to the class name.\n' - '\n' - "**Programmer's note:** Variables defined in the class " - 'definition are\n' - 'class attributes; they are shared by instances. Instance ' - 'attributes\n' - 'can be set in a method with "self.name = value". Both class ' - 'and\n' - 'instance attributes are accessible through the notation ' - '""self.name"",\n' - 'and an instance attribute hides a class attribute with the ' - 'same name\n' - 'when accessed in this way. Class attributes can be used as ' - 'defaults\n' - 'for instance attributes, but using mutable values there can ' - 'lead to\n' - 'unexpected results. *Descriptors* can be used to create ' - 'instance\n' - 'variables with different implementation details.\n' - '\n' - 'See also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** ' - '-\n' - ' Class Decorators\n' - '\n' - '\n' - 'Coroutines\n' - '==========\n' - '\n' - 'New in version 3.5.\n' - '\n' - '\n' - 'Coroutine function definition\n' - '-----------------------------\n' - '\n' - ' async_funcdef ::= [decorators] "async" "def" funcname "(" ' - '[parameter_list] ")" ["->" expression] ":" suite\n' - '\n' - 'Execution of Python coroutines can be suspended and resumed at ' - 'many\n' - 'points (see *coroutine*). In the body of a coroutine, any ' - '"await" and\n' - '"async" identifiers become reserved keywords; "await" ' - 'expressions,\n' - '"async for" and "async with" can only be used in coroutine ' - 'bodies.\n' - '\n' - 'Functions defined with "async def" syntax are always ' - 'coroutine\n' - 'functions, even if they do not contain "await" or "async" ' - 'keywords.\n' - '\n' - 'It is a "SyntaxError" to use "yield" expressions in "async ' - 'def"\n' - 'coroutines.\n' - '\n' - 'An example of a coroutine function:\n' - '\n' - ' async def func(param1, param2):\n' - ' do_stuff()\n' - ' await some_coroutine()\n' - '\n' - '\n' - 'The "async for" statement\n' - '-------------------------\n' - '\n' - ' async_for_stmt ::= "async" for_stmt\n' - '\n' - 'An *asynchronous iterable* is able to call asynchronous code ' - 'in its\n' - '*iter* implementation, and *asynchronous iterator* can call\n' - 'asynchronous code in its *next* method.\n' - '\n' - 'The "async for" statement allows convenient iteration over\n' - 'asynchronous iterators.\n' - '\n' - 'The following code:\n' - '\n' - ' async for TARGET in ITER:\n' - ' BLOCK\n' - ' else:\n' - ' BLOCK2\n' - '\n' - 'Is semantically equivalent to:\n' - '\n' - ' iter = (ITER)\n' - ' iter = await type(iter).__aiter__(iter)\n' - ' running = True\n' - ' while running:\n' - ' try:\n' - ' TARGET = await type(iter).__anext__(iter)\n' - ' except StopAsyncIteration:\n' - ' running = False\n' - ' else:\n' - ' BLOCK\n' - ' else:\n' - ' BLOCK2\n' - '\n' - 'See also "__aiter__()" and "__anext__()" for details.\n' - '\n' - 'It is a "SyntaxError" to use "async for" statement outside of ' - 'an\n' - '"async def" function.\n' - '\n' - '\n' - 'The "async with" statement\n' - '--------------------------\n' - '\n' - ' async_with_stmt ::= "async" with_stmt\n' - '\n' - 'An *asynchronous context manager* is a *context manager* that ' - 'is able\n' - 'to suspend execution in its *enter* and *exit* methods.\n' - '\n' - 'The following code:\n' - '\n' - ' async with EXPR as VAR:\n' - ' BLOCK\n' - '\n' - 'Is semantically equivalent to:\n' - '\n' - ' mgr = (EXPR)\n' - ' aexit = type(mgr).__aexit__\n' - ' aenter = type(mgr).__aenter__(mgr)\n' - ' exc = True\n' - '\n' - ' VAR = await aenter\n' - ' try:\n' - ' BLOCK\n' - ' except:\n' - ' if not await aexit(mgr, *sys.exc_info()):\n' - ' raise\n' - ' else:\n' - ' await aexit(mgr, None, None, None)\n' - '\n' - 'See also "__aenter__()" and "__aexit__()" for details.\n' - '\n' - 'It is a "SyntaxError" to use "async with" statement outside of ' - 'an\n' - '"async def" function.\n' - '\n' - 'See also: **PEP 492** - Coroutines with async and await ' - 'syntax\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] The exception is propagated to the invocation stack ' - 'unless\n' - ' there is a "finally" clause which happens to raise ' - 'another\n' - ' exception. That new exception causes the old one to be ' - 'lost.\n' - '\n' - '[2] Currently, control "flows off the end" except in the case ' - 'of\n' - ' an exception or the execution of a "return", "continue", ' - 'or\n' - ' "break" statement.\n' - '\n' - '[3] A string literal appearing as the first statement in the\n' - " function body is transformed into the function's " - '"__doc__"\n' - " attribute and therefore the function's *docstring*.\n" - '\n' - '[4] A string literal appearing as the first statement in the ' - 'class\n' - ' body is transformed into the namespace\'s "__doc__" item ' - 'and\n' - " therefore the class's *docstring*.\n", - 'context-managers': '\n' - 'With Statement Context Managers\n' - '*******************************\n' - '\n' - 'A *context manager* is an object that defines the ' - 'runtime context to\n' - 'be established when executing a "with" statement. The ' - 'context manager\n' - 'handles the entry into, and the exit from, the desired ' - 'runtime context\n' - 'for the execution of the block of code. Context ' - 'managers are normally\n' - 'invoked using the "with" statement (described in ' - 'section *The with\n' - 'statement*), but can also be used by directly invoking ' - 'their methods.\n' - '\n' - 'Typical uses of context managers include saving and ' - 'restoring various\n' - 'kinds of global state, locking and unlocking ' - 'resources, closing opened\n' - 'files, etc.\n' - '\n' - 'For more information on context managers, see *Context ' - 'Manager Types*.\n' - '\n' - 'object.__enter__(self)\n' - '\n' - ' Enter the runtime context related to this object. ' - 'The "with"\n' - " statement will bind this method's return value to " - 'the target(s)\n' - ' specified in the "as" clause of the statement, if ' - 'any.\n' - '\n' - 'object.__exit__(self, exc_type, exc_value, traceback)\n' - '\n' - ' Exit the runtime context related to this object. ' - 'The parameters\n' - ' describe the exception that caused the context to ' - 'be exited. If the\n' - ' context was exited without an exception, all three ' - 'arguments will\n' - ' be "None".\n' - '\n' - ' If an exception is supplied, and the method wishes ' - 'to suppress the\n' - ' exception (i.e., prevent it from being propagated), ' - 'it should\n' - ' return a true value. Otherwise, the exception will ' - 'be processed\n' - ' normally upon exit from this method.\n' - '\n' - ' Note that "__exit__()" methods should not reraise ' - 'the passed-in\n' - " exception; this is the caller's responsibility.\n" - '\n' - 'See also: **PEP 0343** - The "with" statement\n' - '\n' - ' The specification, background, and examples for ' - 'the Python "with"\n' - ' statement.\n', - 'continue': '\n' - 'The "continue" statement\n' - '************************\n' - '\n' - ' continue_stmt ::= "continue"\n' - '\n' - '"continue" may only occur syntactically nested in a "for" or ' - '"while"\n' - 'loop, but not nested in a function or class definition or ' - '"finally"\n' - 'clause within that loop. It continues with the next cycle of ' - 'the\n' - 'nearest enclosing loop.\n' - '\n' - 'When "continue" passes control out of a "try" statement with ' - 'a\n' - '"finally" clause, that "finally" clause is executed before ' - 'really\n' - 'starting the next loop cycle.\n', - 'conversions': '\n' - 'Arithmetic conversions\n' - '**********************\n' - '\n' - 'When a description of an arithmetic operator below uses the ' - 'phrase\n' - '"the numeric arguments are converted to a common type," ' - 'this means\n' - 'that the operator implementation for built-in types works ' - 'as follows:\n' - '\n' - '* If either argument is a complex number, the other is ' - 'converted to\n' - ' complex;\n' - '\n' - '* otherwise, if either argument is a floating point number, ' - 'the\n' - ' other is converted to floating point;\n' - '\n' - '* otherwise, both must be integers and no conversion is ' - 'necessary.\n' - '\n' - 'Some additional rules apply for certain operators (e.g., a ' - 'string as a\n' - "left argument to the '%' operator). Extensions must define " - 'their own\n' - 'conversion behavior.\n', - 'customization': '\n' - 'Basic customization\n' - '*******************\n' - '\n' - 'object.__new__(cls[, ...])\n' - '\n' - ' Called to create a new instance of class *cls*. ' - '"__new__()" is a\n' - ' static method (special-cased so you need not declare ' - 'it as such)\n' - ' that takes the class of which an instance was ' - 'requested as its\n' - ' first argument. The remaining arguments are those ' - 'passed to the\n' - ' object constructor expression (the call to the ' - 'class). The return\n' - ' value of "__new__()" should be the new object instance ' - '(usually an\n' - ' instance of *cls*).\n' - '\n' - ' Typical implementations create a new instance of the ' - 'class by\n' - ' invoking the superclass\'s "__new__()" method using\n' - ' "super(currentclass, cls).__new__(cls[, ...])" with ' - 'appropriate\n' - ' arguments and then modifying the newly-created ' - 'instance as\n' - ' necessary before returning it.\n' - '\n' - ' If "__new__()" returns an instance of *cls*, then the ' - 'new\n' - ' instance\'s "__init__()" method will be invoked like\n' - ' "__init__(self[, ...])", where *self* is the new ' - 'instance and the\n' - ' remaining arguments are the same as were passed to ' - '"__new__()".\n' - '\n' - ' If "__new__()" does not return an instance of *cls*, ' - 'then the new\n' - ' instance\'s "__init__()" method will not be invoked.\n' - '\n' - ' "__new__()" is intended mainly to allow subclasses of ' - 'immutable\n' - ' types (like int, str, or tuple) to customize instance ' - 'creation. It\n' - ' is also commonly overridden in custom metaclasses in ' - 'order to\n' - ' customize class creation.\n' - '\n' - 'object.__init__(self[, ...])\n' - '\n' - ' Called after the instance has been created (by ' - '"__new__()"), but\n' - ' before it is returned to the caller. The arguments ' - 'are those\n' - ' passed to the class constructor expression. If a base ' - 'class has an\n' - ' "__init__()" method, the derived class\'s "__init__()" ' - 'method, if\n' - ' any, must explicitly call it to ensure proper ' - 'initialization of the\n' - ' base class part of the instance; for example:\n' - ' "BaseClass.__init__(self, [args...])".\n' - '\n' - ' Because "__new__()" and "__init__()" work together in ' - 'constructing\n' - ' objects ("__new__()" to create it, and "__init__()" to ' - 'customise\n' - ' it), no non-"None" value may be returned by ' - '"__init__()"; doing so\n' - ' will cause a "TypeError" to be raised at runtime.\n' - '\n' - 'object.__del__(self)\n' - '\n' - ' Called when the instance is about to be destroyed. ' - 'This is also\n' - ' called a destructor. If a base class has a ' - '"__del__()" method, the\n' - ' derived class\'s "__del__()" method, if any, must ' - 'explicitly call it\n' - ' to ensure proper deletion of the base class part of ' - 'the instance.\n' - ' Note that it is possible (though not recommended!) for ' - 'the\n' - ' "__del__()" method to postpone destruction of the ' - 'instance by\n' - ' creating a new reference to it. It may then be called ' - 'at a later\n' - ' time when this new reference is deleted. It is not ' - 'guaranteed that\n' - ' "__del__()" methods are called for objects that still ' - 'exist when\n' - ' the interpreter exits.\n' - '\n' - ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' - 'the former\n' - ' decrements the reference count for "x" by one, and ' - 'the latter is\n' - ' only called when "x"\'s reference count reaches ' - 'zero. Some common\n' - ' situations that may prevent the reference count of ' - 'an object from\n' - ' going to zero include: circular references between ' - 'objects (e.g.,\n' - ' a doubly-linked list or a tree data structure with ' - 'parent and\n' - ' child pointers); a reference to the object on the ' - 'stack frame of\n' - ' a function that caught an exception (the traceback ' - 'stored in\n' - ' "sys.exc_info()[2]" keeps the stack frame alive); or ' - 'a reference\n' - ' to the object on the stack frame that raised an ' - 'unhandled\n' - ' exception in interactive mode (the traceback stored ' - 'in\n' - ' "sys.last_traceback" keeps the stack frame alive). ' - 'The first\n' - ' situation can only be remedied by explicitly ' - 'breaking the cycles;\n' - ' the second can be resolved by freeing the reference ' - 'to the\n' - ' traceback object when it is no longer useful, and ' - 'the third can\n' - ' be resolved by storing "None" in ' - '"sys.last_traceback". Circular\n' - ' references which are garbage are detected and ' - 'cleaned up when the\n' - " cyclic garbage collector is enabled (it's on by " - 'default). Refer\n' - ' to the documentation for the "gc" module for more ' - 'information\n' - ' about this topic.\n' - '\n' - ' Warning: Due to the precarious circumstances under ' - 'which\n' - ' "__del__()" methods are invoked, exceptions that ' - 'occur during\n' - ' their execution are ignored, and a warning is ' - 'printed to\n' - ' "sys.stderr" instead. Also, when "__del__()" is ' - 'invoked in\n' - ' response to a module being deleted (e.g., when ' - 'execution of the\n' - ' program is done), other globals referenced by the ' - '"__del__()"\n' - ' method may already have been deleted or in the ' - 'process of being\n' - ' torn down (e.g. the import machinery shutting ' - 'down). For this\n' - ' reason, "__del__()" methods should do the absolute ' - 'minimum needed\n' - ' to maintain external invariants. Starting with ' - 'version 1.5,\n' - ' Python guarantees that globals whose name begins ' - 'with a single\n' - ' underscore are deleted from their module before ' - 'other globals are\n' - ' deleted; if no other references to such globals ' - 'exist, this may\n' - ' help in assuring that imported modules are still ' - 'available at the\n' - ' time when the "__del__()" method is called.\n' - '\n' - 'object.__repr__(self)\n' - '\n' - ' Called by the "repr()" built-in function to compute ' - 'the "official"\n' - ' string representation of an object. If at all ' - 'possible, this\n' - ' should look like a valid Python expression that could ' - 'be used to\n' - ' recreate an object with the same value (given an ' - 'appropriate\n' - ' environment). If this is not possible, a string of ' - 'the form\n' - ' "<...some useful description...>" should be returned. ' - 'The return\n' - ' value must be a string object. If a class defines ' - '"__repr__()" but\n' - ' not "__str__()", then "__repr__()" is also used when ' - 'an "informal"\n' - ' string representation of instances of that class is ' - 'required.\n' - '\n' - ' This is typically used for debugging, so it is ' - 'important that the\n' - ' representation is information-rich and unambiguous.\n' - '\n' - 'object.__str__(self)\n' - '\n' - ' Called by "str(object)" and the built-in functions ' - '"format()" and\n' - ' "print()" to compute the "informal" or nicely ' - 'printable string\n' - ' representation of an object. The return value must be ' - 'a *string*\n' - ' object.\n' - '\n' - ' This method differs from "object.__repr__()" in that ' - 'there is no\n' - ' expectation that "__str__()" return a valid Python ' - 'expression: a\n' - ' more convenient or concise representation can be ' - 'used.\n' - '\n' - ' The default implementation defined by the built-in ' - 'type "object"\n' - ' calls "object.__repr__()".\n' - '\n' - 'object.__bytes__(self)\n' - '\n' - ' Called by "bytes()" to compute a byte-string ' - 'representation of an\n' - ' object. This should return a "bytes" object.\n' - '\n' - 'object.__format__(self, format_spec)\n' - '\n' - ' Called by the "format()" built-in function (and by ' - 'extension, the\n' - ' "str.format()" method of class "str") to produce a ' - '"formatted"\n' - ' string representation of an object. The "format_spec" ' - 'argument is a\n' - ' string that contains a description of the formatting ' - 'options\n' - ' desired. The interpretation of the "format_spec" ' - 'argument is up to\n' - ' the type implementing "__format__()", however most ' - 'classes will\n' - ' either delegate formatting to one of the built-in ' - 'types, or use a\n' - ' similar formatting option syntax.\n' - '\n' - ' See *Format Specification Mini-Language* for a ' - 'description of the\n' - ' standard formatting syntax.\n' - '\n' - ' The return value must be a string object.\n' - '\n' - ' Changed in version 3.4: The __format__ method of ' - '"object" itself\n' - ' raises a "TypeError" if passed any non-empty string.\n' - '\n' - 'object.__lt__(self, other)\n' - 'object.__le__(self, other)\n' - 'object.__eq__(self, other)\n' - 'object.__ne__(self, other)\n' - 'object.__gt__(self, other)\n' - 'object.__ge__(self, other)\n' - '\n' - ' These are the so-called "rich comparison" methods. ' - 'The\n' - ' correspondence between operator symbols and method ' - 'names is as\n' - ' follows: "xy" calls\n' - ' "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n' - '\n' - ' A rich comparison method may return the singleton ' - '"NotImplemented"\n' - ' if it does not implement the operation for a given ' - 'pair of\n' - ' arguments. By convention, "False" and "True" are ' - 'returned for a\n' - ' successful comparison. However, these methods can ' - 'return any value,\n' - ' so if the comparison operator is used in a Boolean ' - 'context (e.g.,\n' - ' in the condition of an "if" statement), Python will ' - 'call "bool()"\n' - ' on the value to determine if the result is true or ' - 'false.\n' - '\n' - ' By default, "__ne__()" delegates to "__eq__()" and ' - 'inverts the\n' - ' result unless it is "NotImplemented". There are no ' - 'other implied\n' - ' relationships among the comparison operators, for ' - 'example, the\n' - ' truth of "(x.__hash__".\n' - '\n' - ' If a class that does not override "__eq__()" wishes to ' - 'suppress\n' - ' hash support, it should include "__hash__ = None" in ' - 'the class\n' - ' definition. A class which defines its own "__hash__()" ' - 'that\n' - ' explicitly raises a "TypeError" would be incorrectly ' - 'identified as\n' - ' hashable by an "isinstance(obj, collections.Hashable)" ' - 'call.\n' - '\n' - ' Note: By default, the "__hash__()" values of str, ' - 'bytes and\n' - ' datetime objects are "salted" with an unpredictable ' - 'random value.\n' - ' Although they remain constant within an individual ' - 'Python\n' - ' process, they are not predictable between repeated ' - 'invocations of\n' - ' Python.This is intended to provide protection ' - 'against a denial-\n' - ' of-service caused by carefully-chosen inputs that ' - 'exploit the\n' - ' worst case performance of a dict insertion, O(n^2) ' - 'complexity.\n' - ' See ' - 'http://www.ocert.org/advisories/ocert-2011-003.html for\n' - ' details.Changing hash values affects the iteration ' - 'order of\n' - ' dicts, sets and other mappings. Python has never ' - 'made guarantees\n' - ' about this ordering (and it typically varies between ' - '32-bit and\n' - ' 64-bit builds).See also "PYTHONHASHSEED".\n' - '\n' - ' Changed in version 3.3: Hash randomization is enabled ' - 'by default.\n' - '\n' - 'object.__bool__(self)\n' - '\n' - ' Called to implement truth value testing and the ' - 'built-in operation\n' - ' "bool()"; should return "False" or "True". When this ' - 'method is not\n' - ' defined, "__len__()" is called, if it is defined, and ' - 'the object is\n' - ' considered true if its result is nonzero. If a class ' - 'defines\n' - ' neither "__len__()" nor "__bool__()", all its ' - 'instances are\n' - ' considered true.\n', - 'debugger': '\n' - '"pdb" --- The Python Debugger\n' - '*****************************\n' - '\n' - '**Source code:** Lib/pdb.py\n' - '\n' - '======================================================================\n' - '\n' - 'The module "pdb" defines an interactive source code debugger ' - 'for\n' - 'Python programs. It supports setting (conditional) ' - 'breakpoints and\n' - 'single stepping at the source line level, inspection of stack ' - 'frames,\n' - 'source code listing, and evaluation of arbitrary Python code ' - 'in the\n' - 'context of any stack frame. It also supports post-mortem ' - 'debugging\n' - 'and can be called under program control.\n' - '\n' - 'The debugger is extensible -- it is actually defined as the ' - 'class\n' - '"Pdb". This is currently undocumented but easily understood by ' - 'reading\n' - 'the source. The extension interface uses the modules "bdb" ' - 'and "cmd".\n' - '\n' - 'The debugger\'s prompt is "(Pdb)". Typical usage to run a ' - 'program under\n' - 'control of the debugger is:\n' - '\n' - ' >>> import pdb\n' - ' >>> import mymodule\n' - " >>> pdb.run('mymodule.test()')\n" - ' > (0)?()\n' - ' (Pdb) continue\n' - ' > (1)?()\n' - ' (Pdb) continue\n' - " NameError: 'spam'\n" - ' > (1)?()\n' - ' (Pdb)\n' - '\n' - 'Changed in version 3.3: Tab-completion via the "readline" ' - 'module is\n' - 'available for commands and command arguments, e.g. the current ' - 'global\n' - 'and local names are offered as arguments of the "p" command.\n' - '\n' - '"pdb.py" can also be invoked as a script to debug other ' - 'scripts. For\n' - 'example:\n' - '\n' - ' python3 -m pdb myscript.py\n' - '\n' - 'When invoked as a script, pdb will automatically enter ' - 'post-mortem\n' - 'debugging if the program being debugged exits abnormally. ' - 'After post-\n' - 'mortem debugging (or after normal exit of the program), pdb ' - 'will\n' - "restart the program. Automatic restarting preserves pdb's " - 'state (such\n' - 'as breakpoints) and in most cases is more useful than quitting ' - 'the\n' - "debugger upon program's exit.\n" - '\n' - 'New in version 3.2: "pdb.py" now accepts a "-c" option that ' - 'executes\n' - 'commands as if given in a ".pdbrc" file, see *Debugger ' - 'Commands*.\n' - '\n' - 'The typical usage to break into the debugger from a running ' - 'program is\n' - 'to insert\n' - '\n' - ' import pdb; pdb.set_trace()\n' - '\n' - 'at the location you want to break into the debugger. You can ' - 'then\n' - 'step through the code following this statement, and continue ' - 'running\n' - 'without the debugger using the "continue" command.\n' - '\n' - 'The typical usage to inspect a crashed program is:\n' - '\n' - ' >>> import pdb\n' - ' >>> import mymodule\n' - ' >>> mymodule.test()\n' - ' Traceback (most recent call last):\n' - ' File "", line 1, in ?\n' - ' File "./mymodule.py", line 4, in test\n' - ' test2()\n' - ' File "./mymodule.py", line 3, in test2\n' - ' print(spam)\n' - ' NameError: spam\n' - ' >>> pdb.pm()\n' - ' > ./mymodule.py(3)test2()\n' - ' -> print(spam)\n' - ' (Pdb)\n' - '\n' - 'The module defines the following functions; each enters the ' - 'debugger\n' - 'in a slightly different way:\n' - '\n' - 'pdb.run(statement, globals=None, locals=None)\n' - '\n' - ' Execute the *statement* (given as a string or a code ' - 'object) under\n' - ' debugger control. The debugger prompt appears before any ' - 'code is\n' - ' executed; you can set breakpoints and type "continue", or ' - 'you can\n' - ' step through the statement using "step" or "next" (all ' - 'these\n' - ' commands are explained below). The optional *globals* and ' - '*locals*\n' - ' arguments specify the environment in which the code is ' - 'executed; by\n' - ' default the dictionary of the module "__main__" is used. ' - '(See the\n' - ' explanation of the built-in "exec()" or "eval()" ' - 'functions.)\n' - '\n' - 'pdb.runeval(expression, globals=None, locals=None)\n' - '\n' - ' Evaluate the *expression* (given as a string or a code ' - 'object)\n' - ' under debugger control. When "runeval()" returns, it ' - 'returns the\n' - ' value of the expression. Otherwise this function is ' - 'similar to\n' - ' "run()".\n' - '\n' - 'pdb.runcall(function, *args, **kwds)\n' - '\n' - ' Call the *function* (a function or method object, not a ' - 'string)\n' - ' with the given arguments. When "runcall()" returns, it ' - 'returns\n' - ' whatever the function call returned. The debugger prompt ' - 'appears\n' - ' as soon as the function is entered.\n' - '\n' - 'pdb.set_trace()\n' - '\n' - ' Enter the debugger at the calling stack frame. This is ' - 'useful to\n' - ' hard-code a breakpoint at a given point in a program, even ' - 'if the\n' - ' code is not otherwise being debugged (e.g. when an ' - 'assertion\n' - ' fails).\n' - '\n' - 'pdb.post_mortem(traceback=None)\n' - '\n' - ' Enter post-mortem debugging of the given *traceback* ' - 'object. If no\n' - ' *traceback* is given, it uses the one of the exception that ' - 'is\n' - ' currently being handled (an exception must be being handled ' - 'if the\n' - ' default is to be used).\n' - '\n' - 'pdb.pm()\n' - '\n' - ' Enter post-mortem debugging of the traceback found in\n' - ' "sys.last_traceback".\n' - '\n' - 'The "run*" functions and "set_trace()" are aliases for ' - 'instantiating\n' - 'the "Pdb" class and calling the method of the same name. If ' - 'you want\n' - 'to access further features, you have to do this yourself:\n' - '\n' - "class class pdb.Pdb(completekey='tab', stdin=None, " - 'stdout=None, skip=None, nosigint=False)\n' - '\n' - ' "Pdb" is the debugger class.\n' - '\n' - ' The *completekey*, *stdin* and *stdout* arguments are ' - 'passed to the\n' - ' underlying "cmd.Cmd" class; see the description there.\n' - '\n' - ' The *skip* argument, if given, must be an iterable of ' - 'glob-style\n' - ' module name patterns. The debugger will not step into ' - 'frames that\n' - ' originate in a module that matches one of these patterns. ' - '[1]\n' - '\n' - ' By default, Pdb sets a handler for the SIGINT signal (which ' - 'is sent\n' - ' when the user presses Ctrl-C on the console) when you give ' - 'a\n' - ' "continue" command. This allows you to break into the ' - 'debugger\n' - ' again by pressing Ctrl-C. If you want Pdb not to touch the ' - 'SIGINT\n' - ' handler, set *nosigint* tot true.\n' - '\n' - ' Example call to enable tracing with *skip*:\n' - '\n' - " import pdb; pdb.Pdb(skip=['django.*']).set_trace()\n" - '\n' - ' New in version 3.1: The *skip* argument.\n' - '\n' - ' New in version 3.2: The *nosigint* argument. Previously, a ' - 'SIGINT\n' - ' handler was never set by Pdb.\n' - '\n' - ' run(statement, globals=None, locals=None)\n' - ' runeval(expression, globals=None, locals=None)\n' - ' runcall(function, *args, **kwds)\n' - ' set_trace()\n' - '\n' - ' See the documentation for the functions explained ' - 'above.\n' - '\n' - '\n' - 'Debugger Commands\n' - '=================\n' - '\n' - 'The commands recognized by the debugger are listed below. ' - 'Most\n' - 'commands can be abbreviated to one or two letters as ' - 'indicated; e.g.\n' - '"h(elp)" means that either "h" or "help" can be used to enter ' - 'the help\n' - 'command (but not "he" or "hel", nor "H" or "Help" or "HELP").\n' - 'Arguments to commands must be separated by whitespace (spaces ' - 'or\n' - 'tabs). Optional arguments are enclosed in square brackets ' - '("[]") in\n' - 'the command syntax; the square brackets must not be typed.\n' - 'Alternatives in the command syntax are separated by a vertical ' - 'bar\n' - '("|").\n' - '\n' - 'Entering a blank line repeats the last command entered. ' - 'Exception: if\n' - 'the last command was a "list" command, the next 11 lines are ' - 'listed.\n' - '\n' - "Commands that the debugger doesn't recognize are assumed to be " - 'Python\n' - 'statements and are executed in the context of the program ' - 'being\n' - 'debugged. Python statements can also be prefixed with an ' - 'exclamation\n' - 'point ("!"). This is a powerful way to inspect the program ' - 'being\n' - 'debugged; it is even possible to change a variable or call a ' - 'function.\n' - 'When an exception occurs in such a statement, the exception ' - 'name is\n' - "printed but the debugger's state is not changed.\n" - '\n' - 'The debugger supports *aliases*. Aliases can have parameters ' - 'which\n' - 'allows one a certain level of adaptability to the context ' - 'under\n' - 'examination.\n' - '\n' - 'Multiple commands may be entered on a single line, separated ' - 'by ";;".\n' - '(A single ";" is not used as it is the separator for multiple ' - 'commands\n' - 'in a line that is passed to the Python parser.) No ' - 'intelligence is\n' - 'applied to separating the commands; the input is split at the ' - 'first\n' - '";;" pair, even if it is in the middle of a quoted string.\n' - '\n' - 'If a file ".pdbrc" exists in the user\'s home directory or in ' - 'the\n' - 'current directory, it is read in and executed as if it had ' - 'been typed\n' - 'at the debugger prompt. This is particularly useful for ' - 'aliases. If\n' - 'both files exist, the one in the home directory is read first ' - 'and\n' - 'aliases defined there can be overridden by the local file.\n' - '\n' - 'Changed in version 3.2: ".pdbrc" can now contain commands ' - 'that\n' - 'continue debugging, such as "continue" or "next". Previously, ' - 'these\n' - 'commands had no effect.\n' - '\n' - 'h(elp) [command]\n' - '\n' - ' Without argument, print the list of available commands. ' - 'With a\n' - ' *command* as argument, print help about that command. ' - '"help pdb"\n' - ' displays the full documentation (the docstring of the ' - '"pdb"\n' - ' module). Since the *command* argument must be an ' - 'identifier, "help\n' - ' exec" must be entered to get help on the "!" command.\n' - '\n' - 'w(here)\n' - '\n' - ' Print a stack trace, with the most recent frame at the ' - 'bottom. An\n' - ' arrow indicates the current frame, which determines the ' - 'context of\n' - ' most commands.\n' - '\n' - 'd(own) [count]\n' - '\n' - ' Move the current frame *count* (default one) levels down in ' - 'the\n' - ' stack trace (to a newer frame).\n' - '\n' - 'u(p) [count]\n' - '\n' - ' Move the current frame *count* (default one) levels up in ' - 'the stack\n' - ' trace (to an older frame).\n' - '\n' - 'b(reak) [([filename:]lineno | function) [, condition]]\n' - '\n' - ' With a *lineno* argument, set a break there in the current ' - 'file.\n' - ' With a *function* argument, set a break at the first ' - 'executable\n' - ' statement within that function. The line number may be ' - 'prefixed\n' - ' with a filename and a colon, to specify a breakpoint in ' - 'another\n' - " file (probably one that hasn't been loaded yet). The file " - 'is\n' - ' searched on "sys.path". Note that each breakpoint is ' - 'assigned a\n' - ' number to which all the other breakpoint commands refer.\n' - '\n' - ' If a second argument is present, it is an expression which ' - 'must\n' - ' evaluate to true before the breakpoint is honored.\n' - '\n' - ' Without argument, list all breaks, including for each ' - 'breakpoint,\n' - ' the number of times that breakpoint has been hit, the ' - 'current\n' - ' ignore count, and the associated condition if any.\n' - '\n' - 'tbreak [([filename:]lineno | function) [, condition]]\n' - '\n' - ' Temporary breakpoint, which is removed automatically when ' - 'it is\n' - ' first hit. The arguments are the same as for "break".\n' - '\n' - 'cl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n' - '\n' - ' With a *filename:lineno* argument, clear all the ' - 'breakpoints at\n' - ' this line. With a space separated list of breakpoint ' - 'numbers, clear\n' - ' those breakpoints. Without argument, clear all breaks (but ' - 'first\n' - ' ask confirmation).\n' - '\n' - 'disable [bpnumber [bpnumber ...]]\n' - '\n' - ' Disable the breakpoints given as a space separated list of\n' - ' breakpoint numbers. Disabling a breakpoint means it cannot ' - 'cause\n' - ' the program to stop execution, but unlike clearing a ' - 'breakpoint, it\n' - ' remains in the list of breakpoints and can be ' - '(re-)enabled.\n' - '\n' - 'enable [bpnumber [bpnumber ...]]\n' - '\n' - ' Enable the breakpoints specified.\n' - '\n' - 'ignore bpnumber [count]\n' - '\n' - ' Set the ignore count for the given breakpoint number. If ' - 'count is\n' - ' omitted, the ignore count is set to 0. A breakpoint ' - 'becomes active\n' - ' when the ignore count is zero. When non-zero, the count ' - 'is\n' - ' decremented each time the breakpoint is reached and the ' - 'breakpoint\n' - ' is not disabled and any associated condition evaluates to ' - 'true.\n' - '\n' - 'condition bpnumber [condition]\n' - '\n' - ' Set a new *condition* for the breakpoint, an expression ' - 'which must\n' - ' evaluate to true before the breakpoint is honored. If ' - '*condition*\n' - ' is absent, any existing condition is removed; i.e., the ' - 'breakpoint\n' - ' is made unconditional.\n' - '\n' - 'commands [bpnumber]\n' - '\n' - ' Specify a list of commands for breakpoint number ' - '*bpnumber*. The\n' - ' commands themselves appear on the following lines. Type a ' - 'line\n' - ' containing just "end" to terminate the commands. An ' - 'example:\n' - '\n' - ' (Pdb) commands 1\n' - ' (com) p some_variable\n' - ' (com) end\n' - ' (Pdb)\n' - '\n' - ' To remove all commands from a breakpoint, type commands and ' - 'follow\n' - ' it immediately with "end"; that is, give no commands.\n' - '\n' - ' With no *bpnumber* argument, commands refers to the last ' - 'breakpoint\n' - ' set.\n' - '\n' - ' You can use breakpoint commands to start your program up ' - 'again.\n' - ' Simply use the continue command, or step, or any other ' - 'command that\n' - ' resumes execution.\n' - '\n' - ' Specifying any command resuming execution (currently ' - 'continue,\n' - ' step, next, return, jump, quit and their abbreviations) ' - 'terminates\n' - ' the command list (as if that command was immediately ' - 'followed by\n' - ' end). This is because any time you resume execution (even ' - 'with a\n' - ' simple next or step), you may encounter another ' - 'breakpoint--which\n' - ' could have its own command list, leading to ambiguities ' - 'about which\n' - ' list to execute.\n' - '\n' - " If you use the 'silent' command in the command list, the " - 'usual\n' - ' message about stopping at a breakpoint is not printed. ' - 'This may be\n' - ' desirable for breakpoints that are to print a specific ' - 'message and\n' - ' then continue. If none of the other commands print ' - 'anything, you\n' - ' see no sign that the breakpoint was reached.\n' - '\n' - 's(tep)\n' - '\n' - ' Execute the current line, stop at the first possible ' - 'occasion\n' - ' (either in a function that is called or on the next line in ' - 'the\n' - ' current function).\n' - '\n' - 'n(ext)\n' - '\n' - ' Continue execution until the next line in the current ' - 'function is\n' - ' reached or it returns. (The difference between "next" and ' - '"step"\n' - ' is that "step" stops inside a called function, while ' - '"next"\n' - ' executes called functions at (nearly) full speed, only ' - 'stopping at\n' - ' the next line in the current function.)\n' - '\n' - 'unt(il) [lineno]\n' - '\n' - ' Without argument, continue execution until the line with a ' - 'number\n' - ' greater than the current one is reached.\n' - '\n' - ' With a line number, continue execution until a line with a ' - 'number\n' - ' greater or equal to that is reached. In both cases, also ' - 'stop when\n' - ' the current frame returns.\n' - '\n' - ' Changed in version 3.2: Allow giving an explicit line ' - 'number.\n' - '\n' - 'r(eturn)\n' - '\n' - ' Continue execution until the current function returns.\n' - '\n' - 'c(ont(inue))\n' - '\n' - ' Continue execution, only stop when a breakpoint is ' - 'encountered.\n' - '\n' - 'j(ump) lineno\n' - '\n' - ' Set the next line that will be executed. Only available in ' - 'the\n' - ' bottom-most frame. This lets you jump back and execute ' - 'code again,\n' - " or jump forward to skip code that you don't want to run.\n" - '\n' - ' It should be noted that not all jumps are allowed -- for ' - 'instance\n' - ' it is not possible to jump into the middle of a "for" loop ' - 'or out\n' - ' of a "finally" clause.\n' - '\n' - 'l(ist) [first[, last]]\n' - '\n' - ' List source code for the current file. Without arguments, ' - 'list 11\n' - ' lines around the current line or continue the previous ' - 'listing.\n' - ' With "." as argument, list 11 lines around the current ' - 'line. With\n' - ' one argument, list 11 lines around at that line. With two\n' - ' arguments, list the given range; if the second argument is ' - 'less\n' - ' than the first, it is interpreted as a count.\n' - '\n' - ' The current line in the current frame is indicated by ' - '"->". If an\n' - ' exception is being debugged, the line where the exception ' - 'was\n' - ' originally raised or propagated is indicated by ">>", if it ' - 'differs\n' - ' from the current line.\n' - '\n' - ' New in version 3.2: The ">>" marker.\n' - '\n' - 'll | longlist\n' - '\n' - ' List all source code for the current function or frame.\n' - ' Interesting lines are marked as for "list".\n' - '\n' - ' New in version 3.2.\n' - '\n' - 'a(rgs)\n' - '\n' - ' Print the argument list of the current function.\n' - '\n' - 'p expression\n' - '\n' - ' Evaluate the *expression* in the current context and print ' - 'its\n' - ' value.\n' - '\n' - ' Note: "print()" can also be used, but is not a debugger ' - 'command\n' - ' --- this executes the Python "print()" function.\n' - '\n' - 'pp expression\n' - '\n' - ' Like the "p" command, except the value of the expression is ' - 'pretty-\n' - ' printed using the "pprint" module.\n' - '\n' - 'whatis expression\n' - '\n' - ' Print the type of the *expression*.\n' - '\n' - 'source expression\n' - '\n' - ' Try to get source code for the given object and display ' - 'it.\n' - '\n' - ' New in version 3.2.\n' - '\n' - 'display [expression]\n' - '\n' - ' Display the value of the expression if it changed, each ' - 'time\n' - ' execution stops in the current frame.\n' - '\n' - ' Without expression, list all display expressions for the ' - 'current\n' - ' frame.\n' - '\n' - ' New in version 3.2.\n' - '\n' - 'undisplay [expression]\n' - '\n' - ' Do not display the expression any more in the current ' - 'frame.\n' - ' Without expression, clear all display expressions for the ' - 'current\n' - ' frame.\n' - '\n' - ' New in version 3.2.\n' - '\n' - 'interact\n' - '\n' - ' Start an interative interpreter (using the "code" module) ' - 'whose\n' - ' global namespace contains all the (global and local) names ' - 'found in\n' - ' the current scope.\n' - '\n' - ' New in version 3.2.\n' - '\n' - 'alias [name [command]]\n' - '\n' - ' Create an alias called *name* that executes *command*. The ' - 'command\n' - ' must *not* be enclosed in quotes. Replaceable parameters ' - 'can be\n' - ' indicated by "%1", "%2", and so on, while "%*" is replaced ' - 'by all\n' - ' the parameters. If no command is given, the current alias ' - 'for\n' - ' *name* is shown. If no arguments are given, all aliases are ' - 'listed.\n' - '\n' - ' Aliases may be nested and can contain anything that can be ' - 'legally\n' - ' typed at the pdb prompt. Note that internal pdb commands ' - '*can* be\n' - ' overridden by aliases. Such a command is then hidden until ' - 'the\n' - ' alias is removed. Aliasing is recursively applied to the ' - 'first\n' - ' word of the command line; all other words in the line are ' - 'left\n' - ' alone.\n' - '\n' - ' As an example, here are two useful aliases (especially when ' - 'placed\n' - ' in the ".pdbrc" file):\n' - '\n' - ' # Print instance variables (usage "pi classInst")\n' - ' alias pi for k in %1.__dict__.keys(): ' - 'print("%1.",k,"=",%1.__dict__[k])\n' - ' # Print instance variables in self\n' - ' alias ps pi self\n' - '\n' - 'unalias name\n' - '\n' - ' Delete the specified alias.\n' - '\n' - '! statement\n' - '\n' - ' Execute the (one-line) *statement* in the context of the ' - 'current\n' - ' stack frame. The exclamation point can be omitted unless ' - 'the first\n' - ' word of the statement resembles a debugger command. To set ' - 'a\n' - ' global variable, you can prefix the assignment command with ' - 'a\n' - ' "global" statement on the same line, e.g.:\n' - '\n' - " (Pdb) global list_options; list_options = ['-l']\n" - ' (Pdb)\n' - '\n' - 'run [args ...]\n' - 'restart [args ...]\n' - '\n' - ' Restart the debugged Python program. If an argument is ' - 'supplied,\n' - ' it is split with "shlex" and the result is used as the new\n' - ' "sys.argv". History, breakpoints, actions and debugger ' - 'options are\n' - ' preserved. "restart" is an alias for "run".\n' - '\n' - 'q(uit)\n' - '\n' - ' Quit from the debugger. The program being executed is ' - 'aborted.\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] Whether a frame is considered to originate in a certain ' - 'module\n' - ' is determined by the "__name__" in the frame globals.\n', - 'del': '\n' - 'The "del" statement\n' - '*******************\n' - '\n' - ' del_stmt ::= "del" target_list\n' - '\n' - 'Deletion is recursively defined very similar to the way assignment ' - 'is\n' - 'defined. Rather than spelling it out in full details, here are ' - 'some\n' - 'hints.\n' - '\n' - 'Deletion of a target list recursively deletes each target, from ' - 'left\n' - 'to right.\n' - '\n' - 'Deletion of a name removes the binding of that name from the local ' - 'or\n' - 'global namespace, depending on whether the name occurs in a ' - '"global"\n' - 'statement in the same code block. If the name is unbound, a\n' - '"NameError" exception will be raised.\n' - '\n' - 'Deletion of attribute references, subscriptions and slicings is ' - 'passed\n' - 'to the primary object involved; deletion of a slicing is in ' - 'general\n' - 'equivalent to assignment of an empty slice of the right type (but ' - 'even\n' - 'this is determined by the sliced object).\n' - '\n' - 'Changed in version 3.2: Previously it was illegal to delete a name\n' - 'from the local namespace if it occurs as a free variable in a ' - 'nested\n' - 'block.\n', - 'dict': '\n' - 'Dictionary displays\n' - '*******************\n' - '\n' - 'A dictionary display is a possibly empty series of key/datum ' - 'pairs\n' - 'enclosed in curly braces:\n' - '\n' - ' dict_display ::= "{" [key_datum_list | ' - 'dict_comprehension] "}"\n' - ' key_datum_list ::= key_datum ("," key_datum)* [","]\n' - ' key_datum ::= expression ":" expression\n' - ' dict_comprehension ::= expression ":" expression comp_for\n' - '\n' - 'A dictionary display yields a new dictionary object.\n' - '\n' - 'If a comma-separated sequence of key/datum pairs is given, they ' - 'are\n' - 'evaluated from left to right to define the entries of the ' - 'dictionary:\n' - 'each key object is used as a key into the dictionary to store the\n' - 'corresponding datum. This means that you can specify the same ' - 'key\n' - "multiple times in the key/datum list, and the final dictionary's " - 'value\n' - 'for that key will be the last one given.\n' - '\n' - 'A dict comprehension, in contrast to list and set comprehensions,\n' - 'needs two expressions separated with a colon followed by the ' - 'usual\n' - '"for" and "if" clauses. When the comprehension is run, the ' - 'resulting\n' - 'key and value elements are inserted in the new dictionary in the ' - 'order\n' - 'they are produced.\n' - '\n' - 'Restrictions on the types of the key values are listed earlier in\n' - 'section *The standard type hierarchy*. (To summarize, the key ' - 'type\n' - 'should be *hashable*, which excludes all mutable objects.) ' - 'Clashes\n' - 'between duplicate keys are not detected; the last datum ' - '(textually\n' - 'rightmost in the display) stored for a given key value prevails.\n', - 'dynamic-features': '\n' - 'Interaction with dynamic features\n' - '*********************************\n' - '\n' - 'Name resolution of free variables occurs at runtime, ' - 'not at compile\n' - 'time. This means that the following code will print ' - '42:\n' - '\n' - ' i = 10\n' - ' def f():\n' - ' print(i)\n' - ' i = 42\n' - ' f()\n' - '\n' - 'There are several cases where Python statements are ' - 'illegal when used\n' - 'in conjunction with nested scopes that contain free ' - 'variables.\n' - '\n' - 'If a variable is referenced in an enclosing scope, it ' - 'is illegal to\n' - 'delete the name. An error will be reported at compile ' - 'time.\n' - '\n' - 'The "eval()" and "exec()" functions do not have access ' - 'to the full\n' - 'environment for resolving names. Names may be ' - 'resolved in the local\n' - 'and global namespaces of the caller. Free variables ' - 'are not resolved\n' - 'in the nearest enclosing namespace, but in the global ' - 'namespace. [1]\n' - 'The "exec()" and "eval()" functions have optional ' - 'arguments to\n' - 'override the global and local namespace. If only one ' - 'namespace is\n' - 'specified, it is used for both.\n', - 'else': '\n' - 'The "if" statement\n' - '******************\n' - '\n' - 'The "if" statement is used for conditional execution:\n' - '\n' - ' if_stmt ::= "if" expression ":" suite\n' - ' ( "elif" expression ":" suite )*\n' - ' ["else" ":" suite]\n' - '\n' - 'It selects exactly one of the suites by evaluating the expressions ' - 'one\n' - 'by one until one is found to be true (see section *Boolean ' - 'operations*\n' - 'for the definition of true and false); then that suite is ' - 'executed\n' - '(and no other part of the "if" statement is executed or ' - 'evaluated).\n' - 'If all expressions are false, the suite of the "else" clause, if\n' - 'present, is executed.\n', - 'exceptions': '\n' - 'Exceptions\n' - '**********\n' - '\n' - 'Exceptions are a means of breaking out of the normal flow of ' - 'control\n' - 'of a code block in order to handle errors or other ' - 'exceptional\n' - 'conditions. An exception is *raised* at the point where the ' - 'error is\n' - 'detected; it may be *handled* by the surrounding code block ' - 'or by any\n' - 'code block that directly or indirectly invoked the code ' - 'block where\n' - 'the error occurred.\n' - '\n' - 'The Python interpreter raises an exception when it detects a ' - 'run-time\n' - 'error (such as division by zero). A Python program can ' - 'also\n' - 'explicitly raise an exception with the "raise" statement. ' - 'Exception\n' - 'handlers are specified with the "try" ... "except" ' - 'statement. The\n' - '"finally" clause of such a statement can be used to specify ' - 'cleanup\n' - 'code which does not handle the exception, but is executed ' - 'whether an\n' - 'exception occurred or not in the preceding code.\n' - '\n' - 'Python uses the "termination" model of error handling: an ' - 'exception\n' - 'handler can find out what happened and continue execution at ' - 'an outer\n' - 'level, but it cannot repair the cause of the error and retry ' - 'the\n' - 'failing operation (except by re-entering the offending piece ' - 'of code\n' - 'from the top).\n' - '\n' - 'When an exception is not handled at all, the interpreter ' - 'terminates\n' - 'execution of the program, or returns to its interactive main ' - 'loop. In\n' - 'either case, it prints a stack backtrace, except when the ' - 'exception is\n' - '"SystemExit".\n' - '\n' - 'Exceptions are identified by class instances. The "except" ' - 'clause is\n' - 'selected depending on the class of the instance: it must ' - 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' - '\n' - 'Note: Exception messages are not part of the Python API. ' - 'Their\n' - ' contents may change from one version of Python to the next ' - 'without\n' - ' warning and should not be relied on by code which will run ' - 'under\n' - ' multiple versions of the interpreter.\n' - '\n' - 'See also the description of the "try" statement in section ' - '*The try\n' - 'statement* and "raise" statement in section *The raise ' - 'statement*.\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] This limitation occurs because the code that is executed ' - 'by\n' - ' these operations is not available at the time the module ' - 'is\n' - ' compiled.\n', - 'execmodel': '\n' - 'Execution model\n' - '***************\n' - '\n' - '\n' - 'Structure of a programm\n' - '=======================\n' - '\n' - 'A Python program is constructed from code blocks. A *block* ' - 'is a piece\n' - 'of Python program text that is executed as a unit. The ' - 'following are\n' - 'blocks: a module, a function body, and a class definition. ' - 'Each\n' - 'command typed interactively is a block. A script file (a ' - 'file given\n' - 'as standard input to the interpreter or specified as a ' - 'command line\n' - 'argument to the interpreter) is a code block. A script ' - 'command (a\n' - 'command specified on the interpreter command line with the ' - "'**-c**'\n" - 'option) is a code block. The string argument passed to the ' - 'built-in\n' - 'functions "eval()" and "exec()" is a code block.\n' - '\n' - 'A code block is executed in an *execution frame*. A frame ' - 'contains\n' - 'some administrative information (used for debugging) and ' - 'determines\n' - "where and how execution continues after the code block's " - 'execution has\n' - 'completed.\n' - '\n' - '\n' - 'Naming and binding\n' - '==================\n' - '\n' - '\n' - 'Binding of names\n' - '----------------\n' - '\n' - '*Names* refer to objects. Names are introduced by name ' - 'binding\n' - 'operations.\n' - '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these ' - 'bind the\n' - 'class or function name in the defining block), and targets ' - 'that are\n' - 'identifiers if occurring in an assignment, "for" loop header, ' - 'or after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in ' - 'the\n' - 'imported module, except those beginning with an underscore. ' - 'This form\n' - 'may only be used at the module level.\n' - '\n' - 'A target occurring in a "del" statement is also considered ' - 'bound for\n' - 'this purpose (though the actual semantics are to unbind the ' - 'name).\n' - '\n' - 'Each assignment or import statement occurs within a block ' - 'defined by a\n' - 'class or function definition or at the module level (the ' - 'top-level\n' - 'code block).\n' - '\n' - 'If a name is bound in a block, it is a local variable of that ' - 'block,\n' - 'unless declared as "nonlocal" or "global". If a name is ' - 'bound at the\n' - 'module level, it is a global variable. (The variables of the ' - 'module\n' - 'code block are local and global.) If a variable is used in a ' - 'code\n' - 'block but not defined there, it is a *free variable*.\n' - '\n' - 'Each occurrence of a name in the program text refers to the ' - '*binding*\n' - 'of that name established by the following name resolution ' - 'rules.\n' - '\n' - '\n' - 'Resolution of names\n' - '-------------------\n' - '\n' - 'A *scope* defines the visibility of a name within a block. ' - 'If a local\n' - 'variable is defined in a block, its scope includes that ' - 'block. If the\n' - 'definition occurs in a function block, the scope extends to ' - 'any blocks\n' - 'contained within the defining one, unless a contained block ' - 'introduces\n' - 'a different binding for the name.\n' - '\n' - 'When a name is used in a code block, it is resolved using the ' - 'nearest\n' - 'enclosing scope. The set of all such scopes visible to a ' - 'code block\n' - "is called the block's *environment*.\n" - '\n' - 'When a name is not found at all, a "NameError" exception is ' - 'raised. If\n' - 'the current scope is a function scope, and the name refers to ' - 'a local\n' - 'variable that has not yet been bound to a value at the point ' - 'where the\n' - 'name is used, an "UnboundLocalError" exception is raised.\n' - '"UnboundLocalError" is a subclass of "NameError".\n' - '\n' - 'If a name binding operation occurs anywhere within a code ' - 'block, all\n' - 'uses of the name within the block are treated as references ' - 'to the\n' - 'current block. This can lead to errors when a name is used ' - 'within a\n' - 'block before it is bound. This rule is subtle. Python ' - 'lacks\n' - 'declarations and allows name binding operations to occur ' - 'anywhere\n' - 'within a code block. The local variables of a code block can ' - 'be\n' - 'determined by scanning the entire text of the block for name ' - 'binding\n' - 'operations.\n' - '\n' - 'If the "global" statement occurs within a block, all uses of ' - 'the name\n' - 'specified in the statement refer to the binding of that name ' - 'in the\n' - 'top-level namespace. Names are resolved in the top-level ' - 'namespace by\n' - 'searching the global namespace, i.e. the namespace of the ' - 'module\n' - 'containing the code block, and the builtins namespace, the ' - 'namespace\n' - 'of the module "builtins". The global namespace is searched ' - 'first. If\n' - 'the name is not found there, the builtins namespace is ' - 'searched. The\n' - '"global" statement must precede all uses of the name.\n' - '\n' - 'The "global" statement has the same scope as a name binding ' - 'operation\n' - 'in the same block. If the nearest enclosing scope for a free ' - 'variable\n' - 'contains a global statement, the free variable is treated as ' - 'a global.\n' - '\n' - 'The "nonlocal" statement causes corresponding names to refer ' - 'to\n' - 'previously bound variables in the nearest enclosing function ' - 'scope.\n' - '"SyntaxError" is raised at compile time if the given name ' - 'does not\n' - 'exist in any enclosing function scope.\n' - '\n' - 'The namespace for a module is automatically created the first ' - 'time a\n' - 'module is imported. The main module for a script is always ' - 'called\n' - '"__main__".\n' - '\n' - 'Class definition blocks and arguments to "exec()" and ' - '"eval()" are\n' - 'special in the context of name resolution. A class definition ' - 'is an\n' - 'executable statement that may use and define names. These ' - 'references\n' - 'follow the normal rules for name resolution with an exception ' - 'that\n' - 'unbound local variables are looked up in the global ' - 'namespace. The\n' - 'namespace of the class definition becomes the attribute ' - 'dictionary of\n' - 'the class. The scope of names defined in a class block is ' - 'limited to\n' - 'the class block; it does not extend to the code blocks of ' - 'methods --\n' - 'this includes comprehensions and generator expressions since ' - 'they are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' - '\n' - ' class A:\n' - ' a = 42\n' - ' b = list(a + i for i in range(10))\n' - '\n' - '\n' - 'Builtins and restricted execution\n' - '---------------------------------\n' - '\n' - 'The builtins namespace associated with the execution of a ' - 'code block\n' - 'is actually found by looking up the name "__builtins__" in ' - 'its global\n' - 'namespace; this should be a dictionary or a module (in the ' - 'latter case\n' - "the module's dictionary is used). By default, when in the " - '"__main__"\n' - 'module, "__builtins__" is the built-in module "builtins"; ' - 'when in any\n' - 'other module, "__builtins__" is an alias for the dictionary ' - 'of the\n' - '"builtins" module itself. "__builtins__" can be set to a ' - 'user-created\n' - 'dictionary to create a weak form of restricted execution.\n' - '\n' - '**CPython implementation detail:** Users should not touch\n' - '"__builtins__"; it is strictly an implementation detail. ' - 'Users\n' - 'wanting to override values in the builtins namespace should ' - '"import"\n' - 'the "builtins" module and modify its attributes ' - 'appropriately.\n' - '\n' - '\n' - 'Interaction with dynamic features\n' - '---------------------------------\n' - '\n' - 'Name resolution of free variables occurs at runtime, not at ' - 'compile\n' - 'time. This means that the following code will print 42:\n' - '\n' - ' i = 10\n' - ' def f():\n' - ' print(i)\n' - ' i = 42\n' - ' f()\n' - '\n' - 'There are several cases where Python statements are illegal ' - 'when used\n' - 'in conjunction with nested scopes that contain free ' - 'variables.\n' - '\n' - 'If a variable is referenced in an enclosing scope, it is ' - 'illegal to\n' - 'delete the name. An error will be reported at compile time.\n' - '\n' - 'The "eval()" and "exec()" functions do not have access to the ' - 'full\n' - 'environment for resolving names. Names may be resolved in ' - 'the local\n' - 'and global namespaces of the caller. Free variables are not ' - 'resolved\n' - 'in the nearest enclosing namespace, but in the global ' - 'namespace. [1]\n' - 'The "exec()" and "eval()" functions have optional arguments ' - 'to\n' - 'override the global and local namespace. If only one ' - 'namespace is\n' - 'specified, it is used for both.\n' - '\n' - '\n' - 'Exceptions\n' - '==========\n' - '\n' - 'Exceptions are a means of breaking out of the normal flow of ' - 'control\n' - 'of a code block in order to handle errors or other ' - 'exceptional\n' - 'conditions. An exception is *raised* at the point where the ' - 'error is\n' - 'detected; it may be *handled* by the surrounding code block ' - 'or by any\n' - 'code block that directly or indirectly invoked the code block ' - 'where\n' - 'the error occurred.\n' - '\n' - 'The Python interpreter raises an exception when it detects a ' - 'run-time\n' - 'error (such as division by zero). A Python program can also\n' - 'explicitly raise an exception with the "raise" statement. ' - 'Exception\n' - 'handlers are specified with the "try" ... "except" ' - 'statement. The\n' - '"finally" clause of such a statement can be used to specify ' - 'cleanup\n' - 'code which does not handle the exception, but is executed ' - 'whether an\n' - 'exception occurred or not in the preceding code.\n' - '\n' - 'Python uses the "termination" model of error handling: an ' - 'exception\n' - 'handler can find out what happened and continue execution at ' - 'an outer\n' - 'level, but it cannot repair the cause of the error and retry ' - 'the\n' - 'failing operation (except by re-entering the offending piece ' - 'of code\n' - 'from the top).\n' - '\n' - 'When an exception is not handled at all, the interpreter ' - 'terminates\n' - 'execution of the program, or returns to its interactive main ' - 'loop. In\n' - 'either case, it prints a stack backtrace, except when the ' - 'exception is\n' - '"SystemExit".\n' - '\n' - 'Exceptions are identified by class instances. The "except" ' - 'clause is\n' - 'selected depending on the class of the instance: it must ' - 'reference the\n' - 'class of the instance or a base class thereof. The instance ' - 'can be\n' - 'received by the handler and can carry additional information ' - 'about the\n' - 'exceptional condition.\n' - '\n' - 'Note: Exception messages are not part of the Python API. ' - 'Their\n' - ' contents may change from one version of Python to the next ' - 'without\n' - ' warning and should not be relied on by code which will run ' - 'under\n' - ' multiple versions of the interpreter.\n' - '\n' - 'See also the description of the "try" statement in section ' - '*The try\n' - 'statement* and "raise" statement in section *The raise ' - 'statement*.\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] This limitation occurs because the code that is executed ' - 'by\n' - ' these operations is not available at the time the module ' - 'is\n' - ' compiled.\n', - 'exprlists': '\n' - 'Expression lists\n' - '****************\n' - '\n' - ' expression_list ::= expression ( "," expression )* [","]\n' - '\n' - 'An expression list containing at least one comma yields a ' - 'tuple. The\n' - 'length of the tuple is the number of expressions in the ' - 'list. The\n' - 'expressions are evaluated from left to right.\n' - '\n' - 'The trailing comma is required only to create a single tuple ' - '(a.k.a. a\n' - '*singleton*); it is optional in all other cases. A single ' - 'expression\n' - "without a trailing comma doesn't create a tuple, but rather " - 'yields the\n' - 'value of that expression. (To create an empty tuple, use an ' - 'empty pair\n' - 'of parentheses: "()".)\n', - 'floating': '\n' - 'Floating point literals\n' - '***********************\n' - '\n' - 'Floating point literals are described by the following ' - 'lexical\n' - 'definitions:\n' - '\n' - ' floatnumber ::= pointfloat | exponentfloat\n' - ' pointfloat ::= [intpart] fraction | intpart "."\n' - ' exponentfloat ::= (intpart | pointfloat) exponent\n' - ' intpart ::= digit+\n' - ' fraction ::= "." digit+\n' - ' exponent ::= ("e" | "E") ["+" | "-"] digit+\n' - '\n' - 'Note that the integer and exponent parts are always ' - 'interpreted using\n' - 'radix 10. For example, "077e010" is legal, and denotes the ' - 'same number\n' - 'as "77e10". The allowed range of floating point literals is\n' - 'implementation-dependent. Some examples of floating point ' - 'literals:\n' - '\n' - ' 3.14 10. .001 1e100 3.14e-10 0e0\n' - '\n' - 'Note that numeric literals do not include a sign; a phrase ' - 'like "-1"\n' - 'is actually an expression composed of the unary operator "-" ' - 'and the\n' - 'literal "1".\n', - 'for': '\n' - 'The "for" statement\n' - '*******************\n' - '\n' - 'The "for" statement is used to iterate over the elements of a ' - 'sequence\n' - '(such as a string, tuple or list) or other iterable object:\n' - '\n' - ' for_stmt ::= "for" target_list "in" expression_list ":" suite\n' - ' ["else" ":" suite]\n' - '\n' - 'The expression list is evaluated once; it should yield an iterable\n' - 'object. An iterator is created for the result of the\n' - '"expression_list". The suite is then executed once for each item\n' - 'provided by the iterator, in the order returned by the iterator. ' - 'Each\n' - 'item in turn is assigned to the target list using the standard ' - 'rules\n' - 'for assignments (see *Assignment statements*), and then the suite ' - 'is\n' - 'executed. When the items are exhausted (which is immediately when ' - 'the\n' - 'sequence is empty or an iterator raises a "StopIteration" ' - 'exception),\n' - 'the suite in the "else" clause, if present, is executed, and the ' - 'loop\n' - 'terminates.\n' - '\n' - 'A "break" statement executed in the first suite terminates the ' - 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' - 'statement\n' - 'executed in the first suite skips the rest of the suite and ' - 'continues\n' - 'with the next item, or with the "else" clause if there is no next\n' - 'item.\n' - '\n' - 'The for-loop makes assignments to the variables(s) in the target ' - 'list.\n' - 'This overwrites all previous assignments to those variables ' - 'including\n' - 'those made in the suite of the for-loop:\n' - '\n' - ' for i in range(10):\n' - ' print(i)\n' - ' i = 5 # this will not affect the for-loop\n' - ' # because i will be overwritten with the ' - 'next\n' - ' # index in the range\n' - '\n' - 'Names in the target list are not deleted when the loop is ' - 'finished,\n' - 'but if the sequence is empty, they will not have been assigned to ' - 'at\n' - 'all by the loop. Hint: the built-in function "range()" returns an\n' - "iterator of integers suitable to emulate the effect of Pascal's " - '"for i\n' - ':= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, ' - '2]".\n' - '\n' - 'Note: There is a subtlety when the sequence is being modified by ' - 'the\n' - ' loop (this can only occur for mutable sequences, i.e. lists). ' - 'An\n' - ' internal counter is used to keep track of which item is used ' - 'next,\n' - ' and this is incremented on each iteration. When this counter ' - 'has\n' - ' reached the length of the sequence the loop terminates. This ' - 'means\n' - ' that if the suite deletes the current (or a previous) item from ' - 'the\n' - ' sequence, the next item will be skipped (since it gets the index ' - 'of\n' - ' the current item which has already been treated). Likewise, if ' - 'the\n' - ' suite inserts an item in the sequence before the current item, ' - 'the\n' - ' current item will be treated again the next time through the ' - 'loop.\n' - ' This can lead to nasty bugs that can be avoided by making a\n' - ' temporary copy using a slice of the whole sequence, e.g.,\n' - '\n' - ' for x in a[:]:\n' - ' if x < 0: a.remove(x)\n', - 'formatstrings': '\n' - 'Format String Syntax\n' - '********************\n' - '\n' - 'The "str.format()" method and the "Formatter" class share ' - 'the same\n' - 'syntax for format strings (although in the case of ' - '"Formatter",\n' - 'subclasses can define their own format string syntax).\n' - '\n' - 'Format strings contain "replacement fields" surrounded by ' - 'curly braces\n' - '"{}". Anything that is not contained in braces is ' - 'considered literal\n' - 'text, which is copied unchanged to the output. If you ' - 'need to include\n' - 'a brace character in the literal text, it can be escaped ' - 'by doubling:\n' - '"{{" and "}}".\n' - '\n' - 'The grammar for a replacement field is as follows:\n' - '\n' - ' replacement_field ::= "{" [field_name] ["!" ' - 'conversion] [":" format_spec] "}"\n' - ' field_name ::= arg_name ("." attribute_name ' - '| "[" element_index "]")*\n' - ' arg_name ::= [identifier | integer]\n' - ' attribute_name ::= identifier\n' - ' element_index ::= integer | index_string\n' - ' index_string ::= +\n' - ' conversion ::= "r" | "s" | "a"\n' - ' format_spec ::= \n' - '\n' - 'In less formal terms, the replacement field can start ' - 'with a\n' - '*field_name* that specifies the object whose value is to ' - 'be formatted\n' - 'and inserted into the output instead of the replacement ' - 'field. The\n' - '*field_name* is optionally followed by a *conversion* ' - 'field, which is\n' - 'preceded by an exclamation point "\'!\'", and a ' - '*format_spec*, which is\n' - 'preceded by a colon "\':\'". These specify a non-default ' - 'format for the\n' - 'replacement value.\n' - '\n' - 'See also the *Format Specification Mini-Language* ' - 'section.\n' - '\n' - 'The *field_name* itself begins with an *arg_name* that is ' - 'either a\n' - "number or a keyword. If it's a number, it refers to a " - 'positional\n' - "argument, and if it's a keyword, it refers to a named " - 'keyword\n' - 'argument. If the numerical arg_names in a format string ' - 'are 0, 1, 2,\n' - '... in sequence, they can all be omitted (not just some) ' - 'and the\n' - 'numbers 0, 1, 2, ... will be automatically inserted in ' - 'that order.\n' - 'Because *arg_name* is not quote-delimited, it is not ' - 'possible to\n' - 'specify arbitrary dictionary keys (e.g., the strings ' - '"\'10\'" or\n' - '"\':-]\'") within a format string. The *arg_name* can be ' - 'followed by any\n' - 'number of index or attribute expressions. An expression ' - 'of the form\n' - '"\'.name\'" selects the named attribute using ' - '"getattr()", while an\n' - 'expression of the form "\'[index]\'" does an index lookup ' - 'using\n' - '"__getitem__()".\n' - '\n' - 'Changed in version 3.1: The positional argument ' - 'specifiers can be\n' - 'omitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n' - '\n' - 'Some simple format string examples:\n' - '\n' - ' "First, thou shalt count to {0}" # References first ' - 'positional argument\n' - ' "Bring me a {}" # Implicitly ' - 'references the first positional argument\n' - ' "From {} to {}" # Same as "From {0} ' - 'to {1}"\n' - ' "My quest is {name}" # References keyword ' - "argument 'name'\n" - ' "Weight in tons {0.weight}" # \'weight\' ' - 'attribute of first positional arg\n' - ' "Units destroyed: {players[0]}" # First element of ' - "keyword argument 'players'.\n" - '\n' - 'The *conversion* field causes a type coercion before ' - 'formatting.\n' - 'Normally, the job of formatting a value is done by the ' - '"__format__()"\n' - 'method of the value itself. However, in some cases it is ' - 'desirable to\n' - 'force a type to be formatted as a string, overriding its ' - 'own\n' - 'definition of formatting. By converting the value to a ' - 'string before\n' - 'calling "__format__()", the normal formatting logic is ' - 'bypassed.\n' - '\n' - 'Three conversion flags are currently supported: "\'!s\'" ' - 'which calls\n' - '"str()" on the value, "\'!r\'" which calls "repr()" and ' - '"\'!a\'" which\n' - 'calls "ascii()".\n' - '\n' - 'Some examples:\n' - '\n' - ' "Harold\'s a clever {0!s}" # Calls str() on the ' - 'argument first\n' - ' "Bring out the holy {name!r}" # Calls repr() on the ' - 'argument first\n' - ' "More {!a}" # Calls ascii() on ' - 'the argument first\n' - '\n' - 'The *format_spec* field contains a specification of how ' - 'the value\n' - 'should be presented, including such details as field ' - 'width, alignment,\n' - 'padding, decimal precision and so on. Each value type ' - 'can define its\n' - 'own "formatting mini-language" or interpretation of the ' - '*format_spec*.\n' - '\n' - 'Most built-in types support a common formatting ' - 'mini-language, which\n' - 'is described in the next section.\n' - '\n' - 'A *format_spec* field can also include nested replacement ' - 'fields\n' - 'within it. These nested replacement fields can contain ' - 'only a field\n' - 'name; conversion flags and format specifications are not ' - 'allowed. The\n' - 'replacement fields within the format_spec are substituted ' - 'before the\n' - '*format_spec* string is interpreted. This allows the ' - 'formatting of a\n' - 'value to be dynamically specified.\n' - '\n' - 'See the *Format examples* section for some examples.\n' - '\n' - '\n' - 'Format Specification Mini-Language\n' - '==================================\n' - '\n' - '"Format specifications" are used within replacement ' - 'fields contained\n' - 'within a format string to define how individual values ' - 'are presented\n' - '(see *Format String Syntax*). They can also be passed ' - 'directly to the\n' - 'built-in "format()" function. Each formattable type may ' - 'define how\n' - 'the format specification is to be interpreted.\n' - '\n' - 'Most built-in types implement the following options for ' - 'format\n' - 'specifications, although some of the formatting options ' - 'are only\n' - 'supported by the numeric types.\n' - '\n' - 'A general convention is that an empty format string ' - '("""") produces\n' - 'the same result as if you had called "str()" on the ' - 'value. A non-empty\n' - 'format string typically modifies the result.\n' - '\n' - 'The general form of a *standard format specifier* is:\n' - '\n' - ' format_spec ::= ' - '[[fill]align][sign][#][0][width][,][.precision][type]\n' - ' fill ::= \n' - ' align ::= "<" | ">" | "=" | "^"\n' - ' sign ::= "+" | "-" | " "\n' - ' width ::= integer\n' - ' precision ::= integer\n' - ' type ::= "b" | "c" | "d" | "e" | "E" | "f" | ' - '"F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n' - '\n' - 'If a valid *align* value is specified, it can be preceded ' - 'by a *fill*\n' - 'character that can be any character and defaults to a ' - 'space if\n' - 'omitted. Note that it is not possible to use "{" and "}" ' - 'as *fill*\n' - 'char while using the "str.format()" method; this ' - 'limitation however\n' - 'doesn\'t affect the "format()" function.\n' - '\n' - 'The meaning of the various alignment options is as ' - 'follows:\n' - '\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | Option | ' - 'Meaning ' - '|\n' - ' ' - '+===========+============================================================+\n' - ' | "\'<\'" | Forces the field to be left-aligned ' - 'within the available |\n' - ' | | space (this is the default for most ' - 'objects). |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'>\'" | Forces the field to be right-aligned ' - 'within the available |\n' - ' | | space (this is the default for ' - 'numbers). |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'=\'" | Forces the padding to be placed after ' - 'the sign (if any) |\n' - ' | | but before the digits. This is used for ' - 'printing fields |\n' - " | | in the form '+000000120'. This alignment " - 'option is only |\n' - ' | | valid for numeric ' - 'types. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'^\'" | Forces the field to be centered within ' - 'the available |\n' - ' | | ' - 'space. ' - '|\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - '\n' - 'Note that unless a minimum field width is defined, the ' - 'field width\n' - 'will always be the same size as the data to fill it, so ' - 'that the\n' - 'alignment option has no meaning in this case.\n' - '\n' - 'The *sign* option is only valid for number types, and can ' - 'be one of\n' - 'the following:\n' - '\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | Option | ' - 'Meaning ' - '|\n' - ' ' - '+===========+============================================================+\n' - ' | "\'+\'" | indicates that a sign should be used ' - 'for both positive as |\n' - ' | | well as negative ' - 'numbers. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'-\'" | indicates that a sign should be used ' - 'only for negative |\n' - ' | | numbers (this is the default ' - 'behavior). |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | space | indicates that a leading space should be ' - 'used on positive |\n' - ' | | numbers, and a minus sign on negative ' - 'numbers. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - '\n' - 'The "\'#\'" option causes the "alternate form" to be used ' - 'for the\n' - 'conversion. The alternate form is defined differently ' - 'for different\n' - 'types. This option is only valid for integer, float, ' - 'complex and\n' - 'Decimal types. For integers, when binary, octal, or ' - 'hexadecimal output\n' - 'is used, this option adds the prefix respective "\'0b\'", ' - '"\'0o\'", or\n' - '"\'0x\'" to the output value. For floats, complex and ' - 'Decimal the\n' - 'alternate form causes the result of the conversion to ' - 'always contain a\n' - 'decimal-point character, even if no digits follow it. ' - 'Normally, a\n' - 'decimal-point character appears in the result of these ' - 'conversions\n' - 'only if a digit follows it. In addition, for "\'g\'" and ' - '"\'G\'"\n' - 'conversions, trailing zeros are not removed from the ' - 'result.\n' - '\n' - 'The "\',\'" option signals the use of a comma for a ' - 'thousands separator.\n' - 'For a locale aware separator, use the "\'n\'" integer ' - 'presentation type\n' - 'instead.\n' - '\n' - 'Changed in version 3.1: Added the "\',\'" option (see ' - 'also **PEP 378**).\n' - '\n' - '*width* is a decimal integer defining the minimum field ' - 'width. If not\n' - 'specified, then the field width will be determined by the ' - 'content.\n' - '\n' - 'Preceding the *width* field by a zero ("\'0\'") character ' - 'enables sign-\n' - 'aware zero-padding for numeric types. This is equivalent ' - 'to a *fill*\n' - 'character of "\'0\'" with an *alignment* type of ' - '"\'=\'".\n' - '\n' - 'The *precision* is a decimal number indicating how many ' - 'digits should\n' - 'be displayed after the decimal point for a floating point ' - 'value\n' - 'formatted with "\'f\'" and "\'F\'", or before and after ' - 'the decimal point\n' - 'for a floating point value formatted with "\'g\'" or ' - '"\'G\'". For non-\n' - 'number types the field indicates the maximum field size - ' - 'in other\n' - 'words, how many characters will be used from the field ' - 'content. The\n' - '*precision* is not allowed for integer values.\n' - '\n' - 'Finally, the *type* determines how the data should be ' - 'presented.\n' - '\n' - 'The available string presentation types are:\n' - '\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | Type | ' - 'Meaning ' - '|\n' - ' ' - '+===========+============================================================+\n' - ' | "\'s\'" | String format. This is the default ' - 'type for strings and |\n' - ' | | may be ' - 'omitted. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | None | The same as ' - '"\'s\'". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - '\n' - 'The available integer presentation types are:\n' - '\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | Type | ' - 'Meaning ' - '|\n' - ' ' - '+===========+============================================================+\n' - ' | "\'b\'" | Binary format. Outputs the number in ' - 'base 2. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'c\'" | Character. Converts the integer to the ' - 'corresponding |\n' - ' | | unicode character before ' - 'printing. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'d\'" | Decimal Integer. Outputs the number in ' - 'base 10. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'o\'" | Octal format. Outputs the number in ' - 'base 8. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'x\'" | Hex format. Outputs the number in base ' - '16, using lower- |\n' - ' | | case letters for the digits above ' - '9. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'X\'" | Hex format. Outputs the number in base ' - '16, using upper- |\n' - ' | | case letters for the digits above ' - '9. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'n\'" | Number. This is the same as "\'d\'", ' - 'except that it uses the |\n' - ' | | current locale setting to insert the ' - 'appropriate number |\n' - ' | | separator ' - 'characters. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | None | The same as ' - '"\'d\'". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - '\n' - 'In addition to the above presentation types, integers can ' - 'be formatted\n' - 'with the floating point presentation types listed below ' - '(except "\'n\'"\n' - 'and None). When doing so, "float()" is used to convert ' - 'the integer to\n' - 'a floating point number before formatting.\n' - '\n' - 'The available presentation types for floating point and ' - 'decimal values\n' - 'are:\n' - '\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | Type | ' - 'Meaning ' - '|\n' - ' ' - '+===========+============================================================+\n' - ' | "\'e\'" | Exponent notation. Prints the number ' - 'in scientific |\n' - " | | notation using the letter 'e' to " - 'indicate the exponent. |\n' - ' | | The default precision is ' - '"6". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'E\'" | Exponent notation. Same as "\'e\'" ' - 'except it uses an upper |\n' - " | | case 'E' as the separator " - 'character. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'f\'" | Fixed point. Displays the number as a ' - 'fixed-point number. |\n' - ' | | The default precision is ' - '"6". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'F\'" | Fixed point. Same as "\'f\'", but ' - 'converts "nan" to "NAN" |\n' - ' | | and "inf" to ' - '"INF". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'g\'" | General format. For a given precision ' - '"p >= 1", this |\n' - ' | | rounds the number to "p" significant ' - 'digits and then |\n' - ' | | formats the result in either fixed-point ' - 'format or in |\n' - ' | | scientific notation, depending on its ' - 'magnitude. The |\n' - ' | | precise rules are as follows: suppose ' - 'that the result |\n' - ' | | formatted with presentation type "\'e\'" ' - 'and precision "p-1" |\n' - ' | | would have exponent "exp". Then if "-4 ' - '<= exp < p", the |\n' - ' | | number is formatted with presentation ' - 'type "\'f\'" and |\n' - ' | | precision "p-1-exp". Otherwise, the ' - 'number is formatted |\n' - ' | | with presentation type "\'e\'" and ' - 'precision "p-1". In both |\n' - ' | | cases insignificant trailing zeros are ' - 'removed from the |\n' - ' | | significand, and the decimal point is ' - 'also removed if |\n' - ' | | there are no remaining digits following ' - 'it. Positive and |\n' - ' | | negative infinity, positive and negative ' - 'zero, and nans, |\n' - ' | | are formatted as "inf", "-inf", "0", ' - '"-0" and "nan" |\n' - ' | | respectively, regardless of the ' - 'precision. A precision of |\n' - ' | | "0" is treated as equivalent to a ' - 'precision of "1". The |\n' - ' | | default precision is ' - '"6". |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'G\'" | General format. Same as "\'g\'" except ' - 'switches to "\'E\'" if |\n' - ' | | the number gets too large. The ' - 'representations of infinity |\n' - ' | | and NaN are uppercased, ' - 'too. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'n\'" | Number. This is the same as "\'g\'", ' - 'except that it uses the |\n' - ' | | current locale setting to insert the ' - 'appropriate number |\n' - ' | | separator ' - 'characters. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | "\'%\'" | Percentage. Multiplies the number by ' - '100 and displays in |\n' - ' | | fixed ("\'f\'") format, followed by a ' - 'percent sign. |\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - ' | None | Similar to "\'g\'", except that ' - 'fixed-point notation, when |\n' - ' | | used, has at least one digit past the ' - 'decimal point. The |\n' - ' | | default precision is as high as needed ' - 'to represent the |\n' - ' | | particular value. The overall effect is ' - 'to match the |\n' - ' | | output of "str()" as altered by the ' - 'other format |\n' - ' | | ' - 'modifiers. ' - '|\n' - ' ' - '+-----------+------------------------------------------------------------+\n' - '\n' - '\n' - 'Format examples\n' - '===============\n' - '\n' - 'This section contains examples of the new format syntax ' - 'and comparison\n' - 'with the old "%"-formatting.\n' - '\n' - 'In most of the cases the syntax is similar to the old ' - '"%"-formatting,\n' - 'with the addition of the "{}" and with ":" used instead ' - 'of "%". For\n' - 'example, "\'%03.2f\'" can be translated to ' - '"\'{:03.2f}\'".\n' - '\n' - 'The new format syntax also supports new and different ' - 'options, shown\n' - 'in the follow examples.\n' - '\n' - 'Accessing arguments by position:\n' - '\n' - " >>> '{0}, {1}, {2}'.format('a', 'b', 'c')\n" - " 'a, b, c'\n" - " >>> '{}, {}, {}'.format('a', 'b', 'c') # 3.1+ only\n" - " 'a, b, c'\n" - " >>> '{2}, {1}, {0}'.format('a', 'b', 'c')\n" - " 'c, b, a'\n" - " >>> '{2}, {1}, {0}'.format(*'abc') # unpacking " - 'argument sequence\n' - " 'c, b, a'\n" - " >>> '{0}{1}{0}'.format('abra', 'cad') # arguments' " - 'indices can be repeated\n' - " 'abracadabra'\n" - '\n' - 'Accessing arguments by name:\n' - '\n' - " >>> 'Coordinates: {latitude}, " - "{longitude}'.format(latitude='37.24N', " - "longitude='-115.81W')\n" - " 'Coordinates: 37.24N, -115.81W'\n" - " >>> coord = {'latitude': '37.24N', 'longitude': " - "'-115.81W'}\n" - " >>> 'Coordinates: {latitude}, " - "{longitude}'.format(**coord)\n" - " 'Coordinates: 37.24N, -115.81W'\n" - '\n' - "Accessing arguments' attributes:\n" - '\n' - ' >>> c = 3-5j\n' - " >>> ('The complex number {0} is formed from the real " - "part {0.real} '\n" - " ... 'and the imaginary part {0.imag}.').format(c)\n" - " 'The complex number (3-5j) is formed from the real " - "part 3.0 and the imaginary part -5.0.'\n" - ' >>> class Point:\n' - ' ... def __init__(self, x, y):\n' - ' ... self.x, self.y = x, y\n' - ' ... def __str__(self):\n' - " ... return 'Point({self.x}, " - "{self.y})'.format(self=self)\n" - ' ...\n' - ' >>> str(Point(4, 2))\n' - " 'Point(4, 2)'\n" - '\n' - "Accessing arguments' items:\n" - '\n' - ' >>> coord = (3, 5)\n' - " >>> 'X: {0[0]}; Y: {0[1]}'.format(coord)\n" - " 'X: 3; Y: 5'\n" - '\n' - 'Replacing "%s" and "%r":\n' - '\n' - ' >>> "repr() shows quotes: {!r}; str() doesn\'t: ' - '{!s}".format(\'test1\', \'test2\')\n' - ' "repr() shows quotes: \'test1\'; str() doesn\'t: ' - 'test2"\n' - '\n' - 'Aligning the text and specifying a width:\n' - '\n' - " >>> '{:<30}'.format('left aligned')\n" - " 'left aligned '\n" - " >>> '{:>30}'.format('right aligned')\n" - " ' right aligned'\n" - " >>> '{:^30}'.format('centered')\n" - " ' centered '\n" - " >>> '{:*^30}'.format('centered') # use '*' as a fill " - 'char\n' - " '***********centered***********'\n" - '\n' - 'Replacing "%+f", "%-f", and "% f" and specifying a sign:\n' - '\n' - " >>> '{:+f}; {:+f}'.format(3.14, -3.14) # show it " - 'always\n' - " '+3.140000; -3.140000'\n" - " >>> '{: f}; {: f}'.format(3.14, -3.14) # show a space " - 'for positive numbers\n' - " ' 3.140000; -3.140000'\n" - " >>> '{:-f}; {:-f}'.format(3.14, -3.14) # show only " - "the minus -- same as '{:f}; {:f}'\n" - " '3.140000; -3.140000'\n" - '\n' - 'Replacing "%x" and "%o" and converting the value to ' - 'different bases:\n' - '\n' - ' >>> # format also supports binary numbers\n' - ' >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: ' - '{0:b}".format(42)\n' - " 'int: 42; hex: 2a; oct: 52; bin: 101010'\n" - ' >>> # with 0x, 0o, or 0b as prefix:\n' - ' >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: ' - '{0:#b}".format(42)\n' - " 'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'\n" - '\n' - 'Using the comma as a thousands separator:\n' - '\n' - " >>> '{:,}'.format(1234567890)\n" - " '1,234,567,890'\n" - '\n' - 'Expressing a percentage:\n' - '\n' - ' >>> points = 19\n' - ' >>> total = 22\n' - " >>> 'Correct answers: {:.2%}'.format(points/total)\n" - " 'Correct answers: 86.36%'\n" - '\n' - 'Using type-specific formatting:\n' - '\n' - ' >>> import datetime\n' - ' >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n' - " >>> '{:%Y-%m-%d %H:%M:%S}'.format(d)\n" - " '2010-07-04 12:15:58'\n" - '\n' - 'Nesting arguments and more complex examples:\n' - '\n' - " >>> for align, text in zip('<^>', ['left', 'center', " - "'right']):\n" - " ... '{0:{fill}{align}16}'.format(text, fill=align, " - 'align=align)\n' - ' ...\n' - " 'left<<<<<<<<<<<<'\n" - " '^^^^^center^^^^^'\n" - " '>>>>>>>>>>>right'\n" - ' >>>\n' - ' >>> octets = [192, 168, 0, 1]\n' - " >>> '{:02X}{:02X}{:02X}{:02X}'.format(*octets)\n" - " 'C0A80001'\n" - ' >>> int(_, 16)\n' - ' 3232235521\n' - ' >>>\n' - ' >>> width = 5\n' - ' >>> for num in range(5,12): #doctest: ' - '+NORMALIZE_WHITESPACE\n' - " ... for base in 'dXob':\n" - " ... print('{0:{width}{base}}'.format(num, " - "base=base, width=width), end=' ')\n" - ' ... print()\n' - ' ...\n' - ' 5 5 5 101\n' - ' 6 6 6 110\n' - ' 7 7 7 111\n' - ' 8 8 10 1000\n' - ' 9 9 11 1001\n' - ' 10 A 12 1010\n' - ' 11 B 13 1011\n', - 'function': '\n' - 'Function definitions\n' - '********************\n' - '\n' - 'A function definition defines a user-defined function object ' - '(see\n' - 'section *The standard type hierarchy*):\n' - '\n' - ' funcdef ::= [decorators] "def" funcname "(" ' - '[parameter_list] ")" ["->" expression] ":" suite\n' - ' decorators ::= decorator+\n' - ' decorator ::= "@" dotted_name ["(" [parameter_list ' - '[","]] ")"] NEWLINE\n' - ' dotted_name ::= identifier ("." identifier)*\n' - ' parameter_list ::= (defparameter ",")*\n' - ' | "*" [parameter] ("," defparameter)* ' - '["," "**" parameter]\n' - ' | "**" parameter\n' - ' | defparameter [","] )\n' - ' parameter ::= identifier [":" expression]\n' - ' defparameter ::= parameter ["=" expression]\n' - ' funcname ::= identifier\n' - '\n' - 'A function definition is an executable statement. Its ' - 'execution binds\n' - 'the function name in the current local namespace to a function ' - 'object\n' - '(a wrapper around the executable code for the function). ' - 'This\n' - 'function object contains a reference to the current global ' - 'namespace\n' - 'as the global namespace to be used when the function is ' - 'called.\n' - '\n' - 'The function definition does not execute the function body; ' - 'this gets\n' - 'executed only when the function is called. [3]\n' - '\n' - 'A function definition may be wrapped by one or more ' - '*decorator*\n' - 'expressions. Decorator expressions are evaluated when the ' - 'function is\n' - 'defined, in the scope that contains the function definition. ' - 'The\n' - 'result must be a callable, which is invoked with the function ' - 'object\n' - 'as the only argument. The returned value is bound to the ' - 'function name\n' - 'instead of the function object. Multiple decorators are ' - 'applied in\n' - 'nested fashion. For example, the following code\n' - '\n' - ' @f1(arg)\n' - ' @f2\n' - ' def func(): pass\n' - '\n' - 'is equivalent to\n' - '\n' - ' def func(): pass\n' - ' func = f1(arg)(f2(func))\n' - '\n' - 'When one or more *parameters* have the form *parameter* "="\n' - '*expression*, the function is said to have "default parameter ' - 'values."\n' - 'For a parameter with a default value, the corresponding ' - '*argument* may\n' - "be omitted from a call, in which case the parameter's default " - 'value is\n' - 'substituted. If a parameter has a default value, all ' - 'following\n' - 'parameters up until the ""*"" must also have a default value ' - '--- this\n' - 'is a syntactic restriction that is not expressed by the ' - 'grammar.\n' - '\n' - '**Default parameter values are evaluated from left to right ' - 'when the\n' - 'function definition is executed.** This means that the ' - 'expression is\n' - 'evaluated once, when the function is defined, and that the ' - 'same "pre-\n' - 'computed" value is used for each call. This is especially ' - 'important\n' - 'to understand when a default parameter is a mutable object, ' - 'such as a\n' - 'list or a dictionary: if the function modifies the object ' - '(e.g. by\n' - 'appending an item to a list), the default value is in effect ' - 'modified.\n' - 'This is generally not what was intended. A way around this is ' - 'to use\n' - '"None" as the default, and explicitly test for it in the body ' - 'of the\n' - 'function, e.g.:\n' - '\n' - ' def whats_on_the_telly(penguin=None):\n' - ' if penguin is None:\n' - ' penguin = []\n' - ' penguin.append("property of the zoo")\n' - ' return penguin\n' - '\n' - 'Function call semantics are described in more detail in ' - 'section\n' - '*Calls*. A function call always assigns values to all ' - 'parameters\n' - 'mentioned in the parameter list, either from position ' - 'arguments, from\n' - 'keyword arguments, or from default values. If the form\n' - '""*identifier"" is present, it is initialized to a tuple ' - 'receiving any\n' - 'excess positional parameters, defaulting to the empty tuple. ' - 'If the\n' - 'form ""**identifier"" is present, it is initialized to a new\n' - 'dictionary receiving any excess keyword arguments, defaulting ' - 'to a new\n' - 'empty dictionary. Parameters after ""*"" or ""*identifier"" ' - 'are\n' - 'keyword-only parameters and may only be passed used keyword ' - 'arguments.\n' - '\n' - 'Parameters may have annotations of the form "": expression"" ' - 'following\n' - 'the parameter name. Any parameter may have an annotation even ' - 'those\n' - 'of the form "*identifier" or "**identifier". Functions may ' - 'have\n' - '"return" annotation of the form ""-> expression"" after the ' - 'parameter\n' - 'list. These annotations can be any valid Python expression ' - 'and are\n' - 'evaluated when the function definition is executed. ' - 'Annotations may\n' - 'be evaluated in a different order than they appear in the ' - 'source code.\n' - 'The presence of annotations does not change the semantics of ' - 'a\n' - 'function. The annotation values are available as values of a\n' - "dictionary keyed by the parameters' names in the " - '"__annotations__"\n' - 'attribute of the function object.\n' - '\n' - 'It is also possible to create anonymous functions (functions ' - 'not bound\n' - 'to a name), for immediate use in expressions. This uses ' - 'lambda\n' - 'expressions, described in section *Lambdas*. Note that the ' - 'lambda\n' - 'expression is merely a shorthand for a simplified function ' - 'definition;\n' - 'a function defined in a ""def"" statement can be passed around ' - 'or\n' - 'assigned to another name just like a function defined by a ' - 'lambda\n' - 'expression. The ""def"" form is actually more powerful since ' - 'it\n' - 'allows the execution of multiple statements and annotations.\n' - '\n' - "**Programmer's note:** Functions are first-class objects. A " - '""def""\n' - 'statement executed inside a function definition defines a ' - 'local\n' - 'function that can be returned or passed around. Free ' - 'variables used\n' - 'in the nested function can access the local variables of the ' - 'function\n' - 'containing the def. See section *Naming and binding* for ' - 'details.\n' - '\n' - 'See also: **PEP 3107** - Function Annotations\n' - '\n' - ' The original specification for function annotations.\n', - 'global': '\n' - 'The "global" statement\n' - '**********************\n' - '\n' - ' global_stmt ::= "global" identifier ("," identifier)*\n' - '\n' - 'The "global" statement is a declaration which holds for the ' - 'entire\n' - 'current code block. It means that the listed identifiers are to ' - 'be\n' - 'interpreted as globals. It would be impossible to assign to a ' - 'global\n' - 'variable without "global", although free variables may refer to\n' - 'globals without being declared global.\n' - '\n' - 'Names listed in a "global" statement must not be used in the ' - 'same code\n' - 'block textually preceding that "global" statement.\n' - '\n' - 'Names listed in a "global" statement must not be defined as ' - 'formal\n' - 'parameters or in a "for" loop control target, "class" ' - 'definition,\n' - 'function definition, or "import" statement.\n' - '\n' - '**CPython implementation detail:** The current implementation ' - 'does not\n' - 'enforce the two restrictions, but programs should not abuse ' - 'this\n' - 'freedom, as future implementations may enforce them or silently ' - 'change\n' - 'the meaning of the program.\n' - '\n' - '**Programmer\'s note:** the "global" is a directive to the ' - 'parser. It\n' - 'applies only to code parsed at the same time as the "global"\n' - 'statement. In particular, a "global" statement contained in a ' - 'string\n' - 'or code object supplied to the built-in "exec()" function does ' - 'not\n' - 'affect the code block *containing* the function call, and code\n' - 'contained in such a string is unaffected by "global" statements ' - 'in the\n' - 'code containing the function call. The same applies to the ' - '"eval()"\n' - 'and "compile()" functions.\n', - 'id-classes': '\n' - 'Reserved classes of identifiers\n' - '*******************************\n' - '\n' - 'Certain classes of identifiers (besides keywords) have ' - 'special\n' - 'meanings. These classes are identified by the patterns of ' - 'leading and\n' - 'trailing underscore characters:\n' - '\n' - '"_*"\n' - ' Not imported by "from module import *". The special ' - 'identifier "_"\n' - ' is used in the interactive interpreter to store the ' - 'result of the\n' - ' last evaluation; it is stored in the "builtins" module. ' - 'When not\n' - ' in interactive mode, "_" has no special meaning and is ' - 'not defined.\n' - ' See section *The import statement*.\n' - '\n' - ' Note: The name "_" is often used in conjunction with\n' - ' internationalization; refer to the documentation for ' - 'the\n' - ' "gettext" module for more information on this ' - 'convention.\n' - '\n' - '"__*__"\n' - ' System-defined names. These names are defined by the ' - 'interpreter\n' - ' and its implementation (including the standard library). ' - 'Current\n' - ' system names are discussed in the *Special method names* ' - 'section\n' - ' and elsewhere. More will likely be defined in future ' - 'versions of\n' - ' Python. *Any* use of "__*__" names, in any context, that ' - 'does not\n' - ' follow explicitly documented use, is subject to breakage ' - 'without\n' - ' warning.\n' - '\n' - '"__*"\n' - ' Class-private names. Names in this category, when used ' - 'within the\n' - ' context of a class definition, are re-written to use a ' - 'mangled form\n' - ' to help avoid name clashes between "private" attributes ' - 'of base and\n' - ' derived classes. See section *Identifiers (Names)*.\n', - 'identifiers': '\n' - 'Identifiers and keywords\n' - '************************\n' - '\n' - 'Identifiers (also referred to as *names*) are described by ' - 'the\n' - 'following lexical definitions.\n' - '\n' - 'The syntax of identifiers in Python is based on the Unicode ' - 'standard\n' - 'annex UAX-31, with elaboration and changes as defined ' - 'below; see also\n' - '**PEP 3131** for further details.\n' - '\n' - 'Within the ASCII range (U+0001..U+007F), the valid ' - 'characters for\n' - 'identifiers are the same as in Python 2.x: the uppercase ' - 'and lowercase\n' - 'letters "A" through "Z", the underscore "_" and, except for ' - 'the first\n' - 'character, the digits "0" through "9".\n' - '\n' - 'Python 3.0 introduces additional characters from outside ' - 'the ASCII\n' - 'range (see **PEP 3131**). For these characters, the ' - 'classification\n' - 'uses the version of the Unicode Character Database as ' - 'included in the\n' - '"unicodedata" module.\n' - '\n' - 'Identifiers are unlimited in length. Case is significant.\n' - '\n' - ' identifier ::= xid_start xid_continue*\n' - ' id_start ::= \n' - ' id_continue ::= \n' - ' xid_start ::= \n' - ' xid_continue ::= \n' - '\n' - 'The Unicode category codes mentioned above stand for:\n' - '\n' - '* *Lu* - uppercase letters\n' - '\n' - '* *Ll* - lowercase letters\n' - '\n' - '* *Lt* - titlecase letters\n' - '\n' - '* *Lm* - modifier letters\n' - '\n' - '* *Lo* - other letters\n' - '\n' - '* *Nl* - letter numbers\n' - '\n' - '* *Mn* - nonspacing marks\n' - '\n' - '* *Mc* - spacing combining marks\n' - '\n' - '* *Nd* - decimal numbers\n' - '\n' - '* *Pc* - connector punctuations\n' - '\n' - '* *Other_ID_Start* - explicit list of characters in ' - 'PropList.txt to\n' - ' support backwards compatibility\n' - '\n' - '* *Other_ID_Continue* - likewise\n' - '\n' - 'All identifiers are converted into the normal form NFKC ' - 'while parsing;\n' - 'comparison of identifiers is based on NFKC.\n' - '\n' - 'A non-normative HTML file listing all valid identifier ' - 'characters for\n' - 'Unicode 4.1 can be found at http://www.dcl.hpi.uni-\n' - 'potsdam.de/home/loewis/table-3131.html.\n' - '\n' - '\n' - 'Keywords\n' - '========\n' - '\n' - 'The following identifiers are used as reserved words, or ' - '*keywords* of\n' - 'the language, and cannot be used as ordinary identifiers. ' - 'They must\n' - 'be spelled exactly as written here:\n' - '\n' - ' False class finally is return\n' - ' None continue for lambda try\n' - ' True def from nonlocal while\n' - ' and del global not with\n' - ' as elif if or yield\n' - ' assert else import pass\n' - ' break except in raise\n' - '\n' - '\n' - 'Reserved classes of identifiers\n' - '===============================\n' - '\n' - 'Certain classes of identifiers (besides keywords) have ' - 'special\n' - 'meanings. These classes are identified by the patterns of ' - 'leading and\n' - 'trailing underscore characters:\n' - '\n' - '"_*"\n' - ' Not imported by "from module import *". The special ' - 'identifier "_"\n' - ' is used in the interactive interpreter to store the ' - 'result of the\n' - ' last evaluation; it is stored in the "builtins" module. ' - 'When not\n' - ' in interactive mode, "_" has no special meaning and is ' - 'not defined.\n' - ' See section *The import statement*.\n' - '\n' - ' Note: The name "_" is often used in conjunction with\n' - ' internationalization; refer to the documentation for ' - 'the\n' - ' "gettext" module for more information on this ' - 'convention.\n' - '\n' - '"__*__"\n' - ' System-defined names. These names are defined by the ' - 'interpreter\n' - ' and its implementation (including the standard ' - 'library). Current\n' - ' system names are discussed in the *Special method names* ' - 'section\n' - ' and elsewhere. More will likely be defined in future ' - 'versions of\n' - ' Python. *Any* use of "__*__" names, in any context, ' - 'that does not\n' - ' follow explicitly documented use, is subject to breakage ' - 'without\n' - ' warning.\n' - '\n' - '"__*"\n' - ' Class-private names. Names in this category, when used ' - 'within the\n' - ' context of a class definition, are re-written to use a ' - 'mangled form\n' - ' to help avoid name clashes between "private" attributes ' - 'of base and\n' - ' derived classes. See section *Identifiers (Names)*.\n', - 'if': '\n' - 'The "if" statement\n' - '******************\n' - '\n' - 'The "if" statement is used for conditional execution:\n' - '\n' - ' if_stmt ::= "if" expression ":" suite\n' - ' ( "elif" expression ":" suite )*\n' - ' ["else" ":" suite]\n' - '\n' - 'It selects exactly one of the suites by evaluating the expressions ' - 'one\n' - 'by one until one is found to be true (see section *Boolean ' - 'operations*\n' - 'for the definition of true and false); then that suite is executed\n' - '(and no other part of the "if" statement is executed or evaluated).\n' - 'If all expressions are false, the suite of the "else" clause, if\n' - 'present, is executed.\n', - 'imaginary': '\n' - 'Imaginary literals\n' - '******************\n' - '\n' - 'Imaginary literals are described by the following lexical ' - 'definitions:\n' - '\n' - ' imagnumber ::= (floatnumber | intpart) ("j" | "J")\n' - '\n' - 'An imaginary literal yields a complex number with a real part ' - 'of 0.0.\n' - 'Complex numbers are represented as a pair of floating point ' - 'numbers\n' - 'and have the same restrictions on their range. To create a ' - 'complex\n' - 'number with a nonzero real part, add a floating point number ' - 'to it,\n' - 'e.g., "(3+4j)". Some examples of imaginary literals:\n' - '\n' - ' 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', - 'import': '\n' - 'The "import" statement\n' - '**********************\n' - '\n' - ' import_stmt ::= "import" module ["as" name] ( "," module ' - '["as" name] )*\n' - ' | "from" relative_module "import" identifier ' - '["as" name]\n' - ' ( "," identifier ["as" name] )*\n' - ' | "from" relative_module "import" "(" ' - 'identifier ["as" name]\n' - ' ( "," identifier ["as" name] )* [","] ")"\n' - ' | "from" module "import" "*"\n' - ' module ::= (identifier ".")* identifier\n' - ' relative_module ::= "."* module | "."+\n' - ' name ::= identifier\n' - '\n' - 'The basic import statement (no "from" clause) is executed in ' - 'two\n' - 'steps:\n' - '\n' - '1. find a module, loading and initializing it if necessary\n' - '\n' - '2. define a name or names in the local namespace for the scope\n' - ' where the "import" statement occurs.\n' - '\n' - 'When the statement contains multiple clauses (separated by ' - 'commas) the\n' - 'two steps are carried out separately for each clause, just as ' - 'though\n' - 'the clauses had been separated out into individiual import ' - 'statements.\n' - '\n' - 'The details of the first step, finding and loading modules are\n' - 'described in greater detail in the section on the *import ' - 'system*,\n' - 'which also describes the various types of packages and modules ' - 'that\n' - 'can be imported, as well as all the hooks that can be used to\n' - 'customize the import system. Note that failures in this step ' - 'may\n' - 'indicate either that the module could not be located, *or* that ' - 'an\n' - 'error occurred while initializing the module, which includes ' - 'execution\n' - "of the module's code.\n" - '\n' - 'If the requested module is retrieved successfully, it will be ' - 'made\n' - 'available in the local namespace in one of three ways:\n' - '\n' - '* If the module name is followed by "as", then the name ' - 'following\n' - ' "as" is bound directly to the imported module.\n' - '\n' - '* If no other name is specified, and the module being imported ' - 'is a\n' - " top level module, the module's name is bound in the local " - 'namespace\n' - ' as a reference to the imported module\n' - '\n' - '* If the module being imported is *not* a top level module, then ' - 'the\n' - ' name of the top level package that contains the module is ' - 'bound in\n' - ' the local namespace as a reference to the top level package. ' - 'The\n' - ' imported module must be accessed using its full qualified ' - 'name\n' - ' rather than directly\n' - '\n' - 'The "from" form uses a slightly more complex process:\n' - '\n' - '1. find the module specified in the "from" clause, loading and\n' - ' initializing it if necessary;\n' - '\n' - '2. for each of the identifiers specified in the "import" ' - 'clauses:\n' - '\n' - ' 1. check if the imported module has an attribute by that ' - 'name\n' - '\n' - ' 2. if not, attempt to import a submodule with that name and ' - 'then\n' - ' check the imported module again for that attribute\n' - '\n' - ' 3. if the attribute is not found, "ImportError" is raised.\n' - '\n' - ' 4. otherwise, a reference to that value is stored in the ' - 'local\n' - ' namespace, using the name in the "as" clause if it is ' - 'present,\n' - ' otherwise using the attribute name\n' - '\n' - 'Examples:\n' - '\n' - ' import foo # foo imported and bound locally\n' - ' import foo.bar.baz # foo.bar.baz imported, foo bound ' - 'locally\n' - ' import foo.bar.baz as fbb # foo.bar.baz imported and bound ' - 'as fbb\n' - ' from foo.bar import baz # foo.bar.baz imported and bound ' - 'as baz\n' - ' from foo import attr # foo imported and foo.attr bound ' - 'as attr\n' - '\n' - 'If the list of identifiers is replaced by a star ("\'*\'"), all ' - 'public\n' - 'names defined in the module are bound in the local namespace for ' - 'the\n' - 'scope where the "import" statement occurs.\n' - '\n' - 'The *public names* defined by a module are determined by ' - 'checking the\n' - 'module\'s namespace for a variable named "__all__"; if defined, ' - 'it must\n' - 'be a sequence of strings which are names defined or imported by ' - 'that\n' - 'module. The names given in "__all__" are all considered public ' - 'and\n' - 'are required to exist. If "__all__" is not defined, the set of ' - 'public\n' - "names includes all names found in the module's namespace which " - 'do not\n' - 'begin with an underscore character ("\'_\'"). "__all__" should ' - 'contain\n' - 'the entire public API. It is intended to avoid accidentally ' - 'exporting\n' - 'items that are not part of the API (such as library modules ' - 'which were\n' - 'imported and used within the module).\n' - '\n' - 'The wild card form of import --- "from module import *" --- is ' - 'only\n' - 'allowed at the module level. Attempting to use it in class or\n' - 'function definitions will raise a "SyntaxError".\n' - '\n' - 'When specifying what module to import you do not have to specify ' - 'the\n' - 'absolute name of the module. When a module or package is ' - 'contained\n' - 'within another package it is possible to make a relative import ' - 'within\n' - 'the same top package without having to mention the package name. ' - 'By\n' - 'using leading dots in the specified module or package after ' - '"from" you\n' - 'can specify how high to traverse up the current package ' - 'hierarchy\n' - 'without specifying exact names. One leading dot means the ' - 'current\n' - 'package where the module making the import exists. Two dots ' - 'means up\n' - 'one package level. Three dots is up two levels, etc. So if you ' - 'execute\n' - '"from . import mod" from a module in the "pkg" package then you ' - 'will\n' - 'end up importing "pkg.mod". If you execute "from ..subpkg2 ' - 'import mod"\n' - 'from within "pkg.subpkg1" you will import "pkg.subpkg2.mod". ' - 'The\n' - 'specification for relative imports is contained within **PEP ' - '328**.\n' - '\n' - '"importlib.import_module()" is provided to support applications ' - 'that\n' - 'determine dynamically the modules to be loaded.\n' - '\n' - '\n' - 'Future statements\n' - '=================\n' - '\n' - 'A *future statement* is a directive to the compiler that a ' - 'particular\n' - 'module should be compiled using syntax or semantics that will ' - 'be\n' - 'available in a specified future release of Python where the ' - 'feature\n' - 'becomes standard.\n' - '\n' - 'The future statement is intended to ease migration to future ' - 'versions\n' - 'of Python that introduce incompatible changes to the language. ' - 'It\n' - 'allows use of the new features on a per-module basis before the\n' - 'release in which the feature becomes standard.\n' - '\n' - ' future_statement ::= "from" "__future__" "import" feature ' - '["as" name]\n' - ' ("," feature ["as" name])*\n' - ' | "from" "__future__" "import" "(" ' - 'feature ["as" name]\n' - ' ("," feature ["as" name])* [","] ")"\n' - ' feature ::= identifier\n' - ' name ::= identifier\n' - '\n' - 'A future statement must appear near the top of the module. The ' - 'only\n' - 'lines that can appear before a future statement are:\n' - '\n' - '* the module docstring (if any),\n' - '\n' - '* comments,\n' - '\n' - '* blank lines, and\n' - '\n' - '* other future statements.\n' - '\n' - 'The features recognized by Python 3.0 are "absolute_import",\n' - '"division", "generators", "unicode_literals", "print_function",\n' - '"nested_scopes" and "with_statement". They are all redundant ' - 'because\n' - 'they are always enabled, and only kept for backwards ' - 'compatibility.\n' - '\n' - 'A future statement is recognized and treated specially at ' - 'compile\n' - 'time: Changes to the semantics of core constructs are often\n' - 'implemented by generating different code. It may even be the ' - 'case\n' - 'that a new feature introduces new incompatible syntax (such as a ' - 'new\n' - 'reserved word), in which case the compiler may need to parse ' - 'the\n' - 'module differently. Such decisions cannot be pushed off until\n' - 'runtime.\n' - '\n' - 'For any given release, the compiler knows which feature names ' - 'have\n' - 'been defined, and raises a compile-time error if a future ' - 'statement\n' - 'contains a feature not known to it.\n' - '\n' - 'The direct runtime semantics are the same as for any import ' - 'statement:\n' - 'there is a standard module "__future__", described later, and it ' - 'will\n' - 'be imported in the usual way at the time the future statement ' - 'is\n' - 'executed.\n' - '\n' - 'The interesting runtime semantics depend on the specific ' - 'feature\n' - 'enabled by the future statement.\n' - '\n' - 'Note that there is nothing special about the statement:\n' - '\n' - ' import __future__ [as name]\n' - '\n' - "That is not a future statement; it's an ordinary import " - 'statement with\n' - 'no special semantics or syntax restrictions.\n' - '\n' - 'Code compiled by calls to the built-in functions "exec()" and\n' - '"compile()" that occur in a module "M" containing a future ' - 'statement\n' - 'will, by default, use the new syntax or semantics associated ' - 'with the\n' - 'future statement. This can be controlled by optional arguments ' - 'to\n' - '"compile()" --- see the documentation of that function for ' - 'details.\n' - '\n' - 'A future statement typed at an interactive interpreter prompt ' - 'will\n' - 'take effect for the rest of the interpreter session. If an\n' - 'interpreter is started with the *-i* option, is passed a script ' - 'name\n' - 'to execute, and the script includes a future statement, it will ' - 'be in\n' - 'effect in the interactive session started after the script is\n' - 'executed.\n' - '\n' - 'See also: **PEP 236** - Back to the __future__\n' - '\n' - ' The original proposal for the __future__ mechanism.\n', - 'in': '\n' - 'Comparisons\n' - '***********\n' - '\n' - 'Unlike C, all comparison operations in Python have the same ' - 'priority,\n' - 'which is lower than that of any arithmetic, shifting or bitwise\n' - 'operation. Also unlike C, expressions like "a < b < c" have the\n' - 'interpretation that is conventional in mathematics:\n' - '\n' - ' comparison ::= or_expr ( comp_operator or_expr )*\n' - ' comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n' - ' | "is" ["not"] | ["not"] "in"\n' - '\n' - 'Comparisons yield boolean values: "True" or "False".\n' - '\n' - 'Comparisons can be chained arbitrarily, e.g., "x < y <= z" is\n' - 'equivalent to "x < y and y <= z", except that "y" is evaluated only\n' - 'once (but in both cases "z" is not evaluated at all when "x < y" is\n' - 'found to be false).\n' - '\n' - 'Formally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and ' - '*op1*,\n' - '*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... ' - 'y\n' - 'opN z" is equivalent to "a op1 b and b op2 c and ... y opN z", ' - 'except\n' - 'that each expression is evaluated at most once.\n' - '\n' - 'Note that "a op1 b op2 c" doesn\'t imply any kind of comparison ' - 'between\n' - '*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\n' - 'perhaps not pretty).\n' - '\n' - 'The operators "<", ">", "==", ">=", "<=", and "!=" compare the ' - 'values\n' - 'of two objects. The objects need not have the same type. If both ' - 'are\n' - 'numbers, they are converted to a common type. Otherwise, the "==" ' - 'and\n' - '"!=" operators *always* consider objects of different types to be\n' - 'unequal, while the "<", ">", ">=" and "<=" operators raise a\n' - '"TypeError" when comparing objects of different types that do not\n' - 'implement these operators for the given pair of types. You can\n' - 'control comparison behavior of objects of non-built-in types by\n' - 'defining rich comparison methods like "__gt__()", described in ' - 'section\n' - '*Basic customization*.\n' - '\n' - 'Comparison of objects of the same type depends on the type:\n' - '\n' - '* Numbers are compared arithmetically.\n' - '\n' - '* The values "float(\'NaN\')" and "Decimal(\'NaN\')" are special. ' - 'They\n' - ' are identical to themselves, "x is x" but are not equal to\n' - ' themselves, "x != x". Additionally, comparing any value to a\n' - ' not-a-number value will return "False". For example, both "3 <\n' - ' float(\'NaN\')" and "float(\'NaN\') < 3" will return "False".\n' - '\n' - '* Bytes objects are compared lexicographically using the numeric\n' - ' values of their elements.\n' - '\n' - '* Strings are compared lexicographically using the numeric\n' - ' equivalents (the result of the built-in function "ord()") of ' - 'their\n' - " characters. [3] String and bytes object can't be compared!\n" - '\n' - '* Tuples and lists are compared lexicographically using comparison\n' - ' of corresponding elements. This means that to compare equal, ' - 'each\n' - ' element must compare equal and the two sequences must be of the ' - 'same\n' - ' type and have the same length.\n' - '\n' - ' If not equal, the sequences are ordered the same as their first\n' - ' differing elements. For example, "[1,2,x] <= [1,2,y]" has the ' - 'same\n' - ' value as "x <= y". If the corresponding element does not exist, ' - 'the\n' - ' shorter sequence is ordered first (for example, "[1,2] < ' - '[1,2,3]").\n' - '\n' - '* Mappings (dictionaries) compare equal if and only if they have ' - 'the\n' - ' same "(key, value)" pairs. Order comparisons "(\'<\', \'<=\', ' - "'>=',\n" - ' \'>\')" raise "TypeError".\n' - '\n' - '* Sets and frozensets define comparison operators to mean subset ' - 'and\n' - ' superset tests. Those relations do not define total orderings ' - '(the\n' - ' two sets "{1,2}" and "{2,3}" are not equal, nor subsets of one\n' - ' another, nor supersets of one another). Accordingly, sets are ' - 'not\n' - ' appropriate arguments for functions which depend on total ' - 'ordering.\n' - ' For example, "min()", "max()", and "sorted()" produce undefined\n' - ' results given a list of sets as inputs.\n' - '\n' - '* Most other objects of built-in types compare unequal unless they\n' - ' are the same object; the choice whether one object is considered\n' - ' smaller or larger than another one is made arbitrarily but\n' - ' consistently within one execution of a program.\n' - '\n' - 'Comparison of objects of differing types depends on whether either ' - 'of\n' - 'the types provide explicit support for the comparison. Most ' - 'numeric\n' - 'types can be compared with one another. When cross-type comparison ' - 'is\n' - 'not supported, the comparison method returns "NotImplemented".\n' - '\n' - 'The operators "in" and "not in" test for membership. "x in s"\n' - 'evaluates to true if *x* is a member of *s*, and false otherwise. ' - '"x\n' - 'not in s" returns the negation of "x in s". All built-in sequences\n' - 'and set types support this as well as dictionary, for which "in" ' - 'tests\n' - 'whether the dictionary has a given key. For container types such as\n' - 'list, tuple, set, frozenset, dict, or collections.deque, the\n' - 'expression "x in y" is equivalent to "any(x is e or x == e for e in\n' - 'y)".\n' - '\n' - 'For the string and bytes types, "x in y" is true if and only if *x* ' - 'is\n' - 'a substring of *y*. An equivalent test is "y.find(x) != -1". ' - 'Empty\n' - 'strings are always considered to be a substring of any other ' - 'string,\n' - 'so """ in "abc"" will return "True".\n' - '\n' - 'For user-defined classes which define the "__contains__()" method, ' - '"x\n' - 'in y" is true if and only if "y.__contains__(x)" is true.\n' - '\n' - 'For user-defined classes which do not define "__contains__()" but ' - 'do\n' - 'define "__iter__()", "x in y" is true if some value "z" with "x == ' - 'z"\n' - 'is produced while iterating over "y". If an exception is raised\n' - 'during the iteration, it is as if "in" raised that exception.\n' - '\n' - 'Lastly, the old-style iteration protocol is tried: if a class ' - 'defines\n' - '"__getitem__()", "x in y" is true if and only if there is a non-\n' - 'negative integer index *i* such that "x == y[i]", and all lower\n' - 'integer indices do not raise "IndexError" exception. (If any other\n' - 'exception is raised, it is as if "in" raised that exception).\n' - '\n' - 'The operator "not in" is defined to have the inverse true value of\n' - '"in".\n' - '\n' - 'The operators "is" and "is not" test for object identity: "x is y" ' - 'is\n' - 'true if and only if *x* and *y* are the same object. "x is not y"\n' - 'yields the inverse truth value. [4]\n', - 'integers': '\n' - 'Integer literals\n' - '****************\n' - '\n' - 'Integer literals are described by the following lexical ' - 'definitions:\n' - '\n' - ' integer ::= decimalinteger | octinteger | hexinteger ' - '| bininteger\n' - ' decimalinteger ::= nonzerodigit digit* | "0"+\n' - ' nonzerodigit ::= "1"..."9"\n' - ' digit ::= "0"..."9"\n' - ' octinteger ::= "0" ("o" | "O") octdigit+\n' - ' hexinteger ::= "0" ("x" | "X") hexdigit+\n' - ' bininteger ::= "0" ("b" | "B") bindigit+\n' - ' octdigit ::= "0"..."7"\n' - ' hexdigit ::= digit | "a"..."f" | "A"..."F"\n' - ' bindigit ::= "0" | "1"\n' - '\n' - 'There is no limit for the length of integer literals apart ' - 'from what\n' - 'can be stored in available memory.\n' - '\n' - 'Note that leading zeros in a non-zero decimal number are not ' - 'allowed.\n' - 'This is for disambiguation with C-style octal literals, which ' - 'Python\n' - 'used before version 3.0.\n' - '\n' - 'Some examples of integer literals:\n' - '\n' - ' 7 2147483647 0o177 ' - '0b100110111\n' - ' 3 79228162514264337593543950336 0o377 ' - '0xdeadbeef\n', - 'lambda': '\n' - 'Lambdas\n' - '*******\n' - '\n' - ' lambda_expr ::= "lambda" [parameter_list]: expression\n' - ' lambda_expr_nocond ::= "lambda" [parameter_list]: ' - 'expression_nocond\n' - '\n' - 'Lambda expressions (sometimes called lambda forms) are used to ' - 'create\n' - 'anonymous functions. The expression "lambda arguments: ' - 'expression"\n' - 'yields a function object. The unnamed object behaves like a ' - 'function\n' - 'object defined with\n' - '\n' - ' def (arguments):\n' - ' return expression\n' - '\n' - 'See section *Function definitions* for the syntax of parameter ' - 'lists.\n' - 'Note that functions created with lambda expressions cannot ' - 'contain\n' - 'statements or annotations.\n', - 'lists': '\n' - 'List displays\n' - '*************\n' - '\n' - 'A list display is a possibly empty series of expressions enclosed ' - 'in\n' - 'square brackets:\n' - '\n' - ' list_display ::= "[" [expression_list | comprehension] "]"\n' - '\n' - 'A list display yields a new list object, the contents being ' - 'specified\n' - 'by either a list of expressions or a comprehension. When a ' - 'comma-\n' - 'separated list of expressions is supplied, its elements are ' - 'evaluated\n' - 'from left to right and placed into the list object in that ' - 'order.\n' - 'When a comprehension is supplied, the list is constructed from ' - 'the\n' - 'elements resulting from the comprehension.\n', - 'naming': '\n' - 'Naming and binding\n' - '******************\n' - '\n' - '\n' - 'Binding of names\n' - '================\n' - '\n' - '*Names* refer to objects. Names are introduced by name binding\n' - 'operations.\n' - '\n' - 'The following constructs bind names: formal parameters to ' - 'functions,\n' - '"import" statements, class and function definitions (these bind ' - 'the\n' - 'class or function name in the defining block), and targets that ' - 'are\n' - 'identifiers if occurring in an assignment, "for" loop header, or ' - 'after\n' - '"as" in a "with" statement or "except" clause. The "import" ' - 'statement\n' - 'of the form "from ... import *" binds all names defined in the\n' - 'imported module, except those beginning with an underscore. ' - 'This form\n' - 'may only be used at the module level.\n' - '\n' - 'A target occurring in a "del" statement is also considered bound ' - 'for\n' - 'this purpose (though the actual semantics are to unbind the ' - 'name).\n' - '\n' - 'Each assignment or import statement occurs within a block ' - 'defined by a\n' - 'class or function definition or at the module level (the ' - 'top-level\n' - 'code block).\n' - '\n' - 'If a name is bound in a block, it is a local variable of that ' - 'block,\n' - 'unless declared as "nonlocal" or "global". If a name is bound ' - 'at the\n' - 'module level, it is a global variable. (The variables of the ' - 'module\n' - 'code block are local and global.) If a variable is used in a ' - 'code\n' - 'block but not defined there, it is a *free variable*.\n' - '\n' - 'Each occurrence of a name in the program text refers to the ' - '*binding*\n' - 'of that name established by the following name resolution ' - 'rules.\n' - '\n' - '\n' - 'Resolution of names\n' - '===================\n' - '\n' - 'A *scope* defines the visibility of a name within a block. If a ' - 'local\n' - 'variable is defined in a block, its scope includes that block. ' - 'If the\n' - 'definition occurs in a function block, the scope extends to any ' - 'blocks\n' - 'contained within the defining one, unless a contained block ' - 'introduces\n' - 'a different binding for the name.\n' - '\n' - 'When a name is used in a code block, it is resolved using the ' - 'nearest\n' - 'enclosing scope. The set of all such scopes visible to a code ' - 'block\n' - "is called the block's *environment*.\n" - '\n' - 'When a name is not found at all, a "NameError" exception is ' - 'raised. If\n' - 'the current scope is a function scope, and the name refers to a ' - 'local\n' - 'variable that has not yet been bound to a value at the point ' - 'where the\n' - 'name is used, an "UnboundLocalError" exception is raised.\n' - '"UnboundLocalError" is a subclass of "NameError".\n' - '\n' - 'If a name binding operation occurs anywhere within a code block, ' - 'all\n' - 'uses of the name within the block are treated as references to ' - 'the\n' - 'current block. This can lead to errors when a name is used ' - 'within a\n' - 'block before it is bound. This rule is subtle. Python lacks\n' - 'declarations and allows name binding operations to occur ' - 'anywhere\n' - 'within a code block. The local variables of a code block can ' - 'be\n' - 'determined by scanning the entire text of the block for name ' - 'binding\n' - 'operations.\n' - '\n' - 'If the "global" statement occurs within a block, all uses of the ' - 'name\n' - 'specified in the statement refer to the binding of that name in ' - 'the\n' - 'top-level namespace. Names are resolved in the top-level ' - 'namespace by\n' - 'searching the global namespace, i.e. the namespace of the ' - 'module\n' - 'containing the code block, and the builtins namespace, the ' - 'namespace\n' - 'of the module "builtins". The global namespace is searched ' - 'first. If\n' - 'the name is not found there, the builtins namespace is ' - 'searched. The\n' - '"global" statement must precede all uses of the name.\n' - '\n' - 'The "global" statement has the same scope as a name binding ' - 'operation\n' - 'in the same block. If the nearest enclosing scope for a free ' - 'variable\n' - 'contains a global statement, the free variable is treated as a ' - 'global.\n' - '\n' - 'The "nonlocal" statement causes corresponding names to refer to\n' - 'previously bound variables in the nearest enclosing function ' - 'scope.\n' - '"SyntaxError" is raised at compile time if the given name does ' - 'not\n' - 'exist in any enclosing function scope.\n' - '\n' - 'The namespace for a module is automatically created the first ' - 'time a\n' - 'module is imported. The main module for a script is always ' - 'called\n' - '"__main__".\n' - '\n' - 'Class definition blocks and arguments to "exec()" and "eval()" ' - 'are\n' - 'special in the context of name resolution. A class definition is ' - 'an\n' - 'executable statement that may use and define names. These ' - 'references\n' - 'follow the normal rules for name resolution with an exception ' - 'that\n' - 'unbound local variables are looked up in the global namespace. ' - 'The\n' - 'namespace of the class definition becomes the attribute ' - 'dictionary of\n' - 'the class. The scope of names defined in a class block is ' - 'limited to\n' - 'the class block; it does not extend to the code blocks of ' - 'methods --\n' - 'this includes comprehensions and generator expressions since ' - 'they are\n' - 'implemented using a function scope. This means that the ' - 'following\n' - 'will fail:\n' - '\n' - ' class A:\n' - ' a = 42\n' - ' b = list(a + i for i in range(10))\n' - '\n' - '\n' - 'Builtins and restricted execution\n' - '=================================\n' - '\n' - 'The builtins namespace associated with the execution of a code ' - 'block\n' - 'is actually found by looking up the name "__builtins__" in its ' - 'global\n' - 'namespace; this should be a dictionary or a module (in the ' - 'latter case\n' - "the module's dictionary is used). By default, when in the " - '"__main__"\n' - 'module, "__builtins__" is the built-in module "builtins"; when ' - 'in any\n' - 'other module, "__builtins__" is an alias for the dictionary of ' - 'the\n' - '"builtins" module itself. "__builtins__" can be set to a ' - 'user-created\n' - 'dictionary to create a weak form of restricted execution.\n' - '\n' - '**CPython implementation detail:** Users should not touch\n' - '"__builtins__"; it is strictly an implementation detail. Users\n' - 'wanting to override values in the builtins namespace should ' - '"import"\n' - 'the "builtins" module and modify its attributes appropriately.\n' - '\n' - '\n' - 'Interaction with dynamic features\n' - '=================================\n' - '\n' - 'Name resolution of free variables occurs at runtime, not at ' - 'compile\n' - 'time. This means that the following code will print 42:\n' - '\n' - ' i = 10\n' - ' def f():\n' - ' print(i)\n' - ' i = 42\n' - ' f()\n' - '\n' - 'There are several cases where Python statements are illegal when ' - 'used\n' - 'in conjunction with nested scopes that contain free variables.\n' - '\n' - 'If a variable is referenced in an enclosing scope, it is illegal ' - 'to\n' - 'delete the name. An error will be reported at compile time.\n' - '\n' - 'The "eval()" and "exec()" functions do not have access to the ' - 'full\n' - 'environment for resolving names. Names may be resolved in the ' - 'local\n' - 'and global namespaces of the caller. Free variables are not ' - 'resolved\n' - 'in the nearest enclosing namespace, but in the global ' - 'namespace. [1]\n' - 'The "exec()" and "eval()" functions have optional arguments to\n' - 'override the global and local namespace. If only one namespace ' - 'is\n' - 'specified, it is used for both.\n', - 'nonlocal': '\n' - 'The "nonlocal" statement\n' - '************************\n' - '\n' - ' nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n' - '\n' - 'The "nonlocal" statement causes the listed identifiers to ' - 'refer to\n' - 'previously bound variables in the nearest enclosing scope ' - 'excluding\n' - 'globals. This is important because the default behavior for ' - 'binding is\n' - 'to search the local namespace first. The statement allows\n' - 'encapsulated code to rebind variables outside of the local ' - 'scope\n' - 'besides the global (module) scope.\n' - '\n' - 'Names listed in a "nonlocal" statement, unlike those listed in ' - 'a\n' - '"global" statement, must refer to pre-existing bindings in an\n' - 'enclosing scope (the scope in which a new binding should be ' - 'created\n' - 'cannot be determined unambiguously).\n' - '\n' - 'Names listed in a "nonlocal" statement must not collide with ' - 'pre-\n' - 'existing bindings in the local scope.\n' - '\n' - 'See also: **PEP 3104** - Access to Names in Outer Scopes\n' - '\n' - ' The specification for the "nonlocal" statement.\n', - 'numbers': '\n' - 'Numeric literals\n' - '****************\n' - '\n' - 'There are three types of numeric literals: integers, floating ' - 'point\n' - 'numbers, and imaginary numbers. There are no complex literals\n' - '(complex numbers can be formed by adding a real number and an\n' - 'imaginary number).\n' - '\n' - 'Note that numeric literals do not include a sign; a phrase like ' - '"-1"\n' - 'is actually an expression composed of the unary operator ' - '\'"-"\' and the\n' - 'literal "1".\n', - 'numeric-types': '\n' - 'Emulating numeric types\n' - '***********************\n' - '\n' - 'The following methods can be defined to emulate numeric ' - 'objects.\n' - 'Methods corresponding to operations that are not ' - 'supported by the\n' - 'particular kind of number implemented (e.g., bitwise ' - 'operations for\n' - 'non-integral numbers) should be left undefined.\n' - '\n' - 'object.__add__(self, other)\n' - 'object.__sub__(self, other)\n' - 'object.__mul__(self, other)\n' - 'object.__matmul__(self, other)\n' - 'object.__truediv__(self, other)\n' - 'object.__floordiv__(self, other)\n' - 'object.__mod__(self, other)\n' - 'object.__divmod__(self, other)\n' - 'object.__pow__(self, other[, modulo])\n' - 'object.__lshift__(self, other)\n' - 'object.__rshift__(self, other)\n' - 'object.__and__(self, other)\n' - 'object.__xor__(self, other)\n' - 'object.__or__(self, other)\n' - '\n' - ' These methods are called to implement the binary ' - 'arithmetic\n' - ' operations ("+", "-", "*", "@", "/", "//", "%", ' - '"divmod()",\n' - ' "pow()", "**", "<<", ">>", "&", "^", "|"). For ' - 'instance, to\n' - ' evaluate the expression "x + y", where *x* is an ' - 'instance of a\n' - ' class that has an "__add__()" method, "x.__add__(y)" ' - 'is called.\n' - ' The "__divmod__()" method should be the equivalent to ' - 'using\n' - ' "__floordiv__()" and "__mod__()"; it should not be ' - 'related to\n' - ' "__truediv__()". Note that "__pow__()" should be ' - 'defined to accept\n' - ' an optional third argument if the ternary version of ' - 'the built-in\n' - ' "pow()" function is to be supported.\n' - '\n' - ' If one of those methods does not support the operation ' - 'with the\n' - ' supplied arguments, it should return ' - '"NotImplemented".\n' - '\n' - 'object.__radd__(self, other)\n' - 'object.__rsub__(self, other)\n' - 'object.__rmul__(self, other)\n' - 'object.__rmatmul__(self, other)\n' - 'object.__rtruediv__(self, other)\n' - 'object.__rfloordiv__(self, other)\n' - 'object.__rmod__(self, other)\n' - 'object.__rdivmod__(self, other)\n' - 'object.__rpow__(self, other)\n' - 'object.__rlshift__(self, other)\n' - 'object.__rrshift__(self, other)\n' - 'object.__rand__(self, other)\n' - 'object.__rxor__(self, other)\n' - 'object.__ror__(self, other)\n' - '\n' - ' These methods are called to implement the binary ' - 'arithmetic\n' - ' operations ("+", "-", "*", "@", "/", "//", "%", ' - '"divmod()",\n' - ' "pow()", "**", "<<", ">>", "&", "^", "|") with ' - 'reflected (swapped)\n' - ' operands. These functions are only called if the left ' - 'operand does\n' - ' not support the corresponding operation and the ' - 'operands are of\n' - ' different types. [2] For instance, to evaluate the ' - 'expression "x -\n' - ' y", where *y* is an instance of a class that has an ' - '"__rsub__()"\n' - ' method, "y.__rsub__(x)" is called if "x.__sub__(y)" ' - 'returns\n' - ' *NotImplemented*.\n' - '\n' - ' Note that ternary "pow()" will not try calling ' - '"__rpow__()" (the\n' - ' coercion rules would become too complicated).\n' - '\n' - " Note: If the right operand's type is a subclass of the " - 'left\n' - " operand's type and that subclass provides the " - 'reflected method\n' - ' for the operation, this method will be called before ' - 'the left\n' - " operand's non-reflected method. This behavior " - 'allows subclasses\n' - " to override their ancestors' operations.\n" - '\n' - 'object.__iadd__(self, other)\n' - 'object.__isub__(self, other)\n' - 'object.__imul__(self, other)\n' - 'object.__imatmul__(self, other)\n' - 'object.__itruediv__(self, other)\n' - 'object.__ifloordiv__(self, other)\n' - 'object.__imod__(self, other)\n' - 'object.__ipow__(self, other[, modulo])\n' - 'object.__ilshift__(self, other)\n' - 'object.__irshift__(self, other)\n' - 'object.__iand__(self, other)\n' - 'object.__ixor__(self, other)\n' - 'object.__ior__(self, other)\n' - '\n' - ' These methods are called to implement the augmented ' - 'arithmetic\n' - ' assignments ("+=", "-=", "*=", "@=", "/=", "//=", ' - '"%=", "**=",\n' - ' "<<=", ">>=", "&=", "^=", "|="). These methods should ' - 'attempt to\n' - ' do the operation in-place (modifying *self*) and ' - 'return the result\n' - ' (which could be, but does not have to be, *self*). If ' - 'a specific\n' - ' method is not defined, the augmented assignment falls ' - 'back to the\n' - ' normal methods. For instance, if *x* is an instance ' - 'of a class\n' - ' with an "__iadd__()" method, "x += y" is equivalent to ' - '"x =\n' - ' x.__iadd__(y)" . Otherwise, "x.__add__(y)" and ' - '"y.__radd__(x)" are\n' - ' considered, as with the evaluation of "x + y". In ' - 'certain\n' - ' situations, augmented assignment can result in ' - 'unexpected errors\n' - " (see *Why does a_tuple[i] += ['item'] raise an " - 'exception when the\n' - ' addition works?*), but this behavior is in fact part ' - 'of the data\n' - ' model.\n' - '\n' - 'object.__neg__(self)\n' - 'object.__pos__(self)\n' - 'object.__abs__(self)\n' - 'object.__invert__(self)\n' - '\n' - ' Called to implement the unary arithmetic operations ' - '("-", "+",\n' - ' "abs()" and "~").\n' - '\n' - 'object.__complex__(self)\n' - 'object.__int__(self)\n' - 'object.__float__(self)\n' - 'object.__round__(self[, n])\n' - '\n' - ' Called to implement the built-in functions ' - '"complex()", "int()",\n' - ' "float()" and "round()". Should return a value of the ' - 'appropriate\n' - ' type.\n' - '\n' - 'object.__index__(self)\n' - '\n' - ' Called to implement "operator.index()", and whenever ' - 'Python needs\n' - ' to losslessly convert the numeric object to an integer ' - 'object (such\n' - ' as in slicing, or in the built-in "bin()", "hex()" and ' - '"oct()"\n' - ' functions). Presence of this method indicates that the ' - 'numeric\n' - ' object is an integer type. Must return an integer.\n' - '\n' - ' Note: In order to have a coherent integer type class, ' - 'when\n' - ' "__index__()" is defined "__int__()" should also be ' - 'defined, and\n' - ' both should return the same value.\n', - 'objects': '\n' - 'Objects, values and types\n' - '*************************\n' - '\n' - "*Objects* are Python's abstraction for data. All data in a " - 'Python\n' - 'program is represented by objects or by relations between ' - 'objects. (In\n' - "a sense, and in conformance to Von Neumann's model of a " - '"stored\n' - 'program computer," code is also represented by objects.)\n' - '\n' - "Every object has an identity, a type and a value. An object's\n" - '*identity* never changes once it has been created; you may ' - 'think of it\n' - 'as the object\'s address in memory. The \'"is"\' operator ' - 'compares the\n' - 'identity of two objects; the "id()" function returns an ' - 'integer\n' - 'representing its identity.\n' - '\n' - '**CPython implementation detail:** For CPython, "id(x)" is the ' - 'memory\n' - 'address where "x" is stored.\n' - '\n' - "An object's type determines the operations that the object " - 'supports\n' - '(e.g., "does it have a length?") and also defines the possible ' - 'values\n' - 'for objects of that type. The "type()" function returns an ' - "object's\n" - 'type (which is an object itself). Like its identity, an ' - "object's\n" - '*type* is also unchangeable. [1]\n' - '\n' - 'The *value* of some objects can change. Objects whose value ' - 'can\n' - 'change are said to be *mutable*; objects whose value is ' - 'unchangeable\n' - 'once they are created are called *immutable*. (The value of an\n' - 'immutable container object that contains a reference to a ' - 'mutable\n' - "object can change when the latter's value is changed; however " - 'the\n' - 'container is still considered immutable, because the collection ' - 'of\n' - 'objects it contains cannot be changed. So, immutability is ' - 'not\n' - 'strictly the same as having an unchangeable value, it is more ' - 'subtle.)\n' - "An object's mutability is determined by its type; for " - 'instance,\n' - 'numbers, strings and tuples are immutable, while dictionaries ' - 'and\n' - 'lists are mutable.\n' - '\n' - 'Objects are never explicitly destroyed; however, when they ' - 'become\n' - 'unreachable they may be garbage-collected. An implementation ' - 'is\n' - 'allowed to postpone garbage collection or omit it altogether ' - '--- it is\n' - 'a matter of implementation quality how garbage collection is\n' - 'implemented, as long as no objects are collected that are ' - 'still\n' - 'reachable.\n' - '\n' - '**CPython implementation detail:** CPython currently uses a ' - 'reference-\n' - 'counting scheme with (optional) delayed detection of cyclically ' - 'linked\n' - 'garbage, which collects most objects as soon as they become\n' - 'unreachable, but is not guaranteed to collect garbage ' - 'containing\n' - 'circular references. See the documentation of the "gc" module ' - 'for\n' - 'information on controlling the collection of cyclic garbage. ' - 'Other\n' - 'implementations act differently and CPython may change. Do not ' - 'depend\n' - 'on immediate finalization of objects when they become ' - 'unreachable (so\n' - 'you should always close files explicitly).\n' - '\n' - "Note that the use of the implementation's tracing or debugging\n" - 'facilities may keep objects alive that would normally be ' - 'collectable.\n' - 'Also note that catching an exception with a ' - '\'"try"..."except"\'\n' - 'statement may keep objects alive.\n' - '\n' - 'Some objects contain references to "external" resources such as ' - 'open\n' - 'files or windows. It is understood that these resources are ' - 'freed\n' - 'when the object is garbage-collected, but since garbage ' - 'collection is\n' - 'not guaranteed to happen, such objects also provide an explicit ' - 'way to\n' - 'release the external resource, usually a "close()" method. ' - 'Programs\n' - 'are strongly recommended to explicitly close such objects. ' - 'The\n' - '\'"try"..."finally"\' statement and the \'"with"\' statement ' - 'provide\n' - 'convenient ways to do this.\n' - '\n' - 'Some objects contain references to other objects; these are ' - 'called\n' - '*containers*. Examples of containers are tuples, lists and\n' - "dictionaries. The references are part of a container's value. " - 'In\n' - 'most cases, when we talk about the value of a container, we ' - 'imply the\n' - 'values, not the identities of the contained objects; however, ' - 'when we\n' - 'talk about the mutability of a container, only the identities ' - 'of the\n' - 'immediately contained objects are implied. So, if an ' - 'immutable\n' - 'container (like a tuple) contains a reference to a mutable ' - 'object, its\n' - 'value changes if that mutable object is changed.\n' - '\n' - 'Types affect almost all aspects of object behavior. Even the\n' - 'importance of object identity is affected in some sense: for ' - 'immutable\n' - 'types, operations that compute new values may actually return ' - 'a\n' - 'reference to any existing object with the same type and value, ' - 'while\n' - 'for mutable objects this is not allowed. E.g., after "a = 1; b ' - '= 1",\n' - '"a" and "b" may or may not refer to the same object with the ' - 'value\n' - 'one, depending on the implementation, but after "c = []; d = ' - '[]", "c"\n' - 'and "d" are guaranteed to refer to two different, unique, ' - 'newly\n' - 'created empty lists. (Note that "c = d = []" assigns the same ' - 'object\n' - 'to both "c" and "d".)\n', - 'operator-summary': '\n' - 'Operator precedence\n' - '*******************\n' - '\n' - 'The following table summarizes the operator precedence ' - 'in Python, from\n' - 'lowest precedence (least binding) to highest ' - 'precedence (most\n' - 'binding). Operators in the same box have the same ' - 'precedence. Unless\n' - 'the syntax is explicitly given, operators are binary. ' - 'Operators in\n' - 'the same box group left to right (except for ' - 'exponentiation, which\n' - 'groups from right to left).\n' - '\n' - 'Note that comparisons, membership tests, and identity ' - 'tests, all have\n' - 'the same precedence and have a left-to-right chaining ' - 'feature as\n' - 'described in the *Comparisons* section.\n' - '\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| Operator | ' - 'Description |\n' - '+=================================================+=======================================+\n' - '| "lambda" | ' - 'Lambda expression |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "if" -- "else" | ' - 'Conditional expression |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "or" | ' - 'Boolean OR |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "and" | ' - 'Boolean AND |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "not" "x" | ' - 'Boolean NOT |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "in", "not in", "is", "is not", "<", "<=", ">", | ' - 'Comparisons, including membership |\n' - '| ">=", "!=", "==" | ' - 'tests and identity tests |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "|" | ' - 'Bitwise OR |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "^" | ' - 'Bitwise XOR |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "&" | ' - 'Bitwise AND |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "<<", ">>" | ' - 'Shifts |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "+", "-" | ' - 'Addition and subtraction |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "*", "@", "/", "//", "%" | ' - 'Multiplication, matrix multiplication |\n' - '| | ' - 'division, remainder [5] |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "+x", "-x", "~x" | ' - 'Positive, negative, bitwise NOT |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "**" | ' - 'Exponentiation [6] |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "await" "x" | ' - 'Await expression |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "x[index]", "x[index:index]", | ' - 'Subscription, slicing, call, |\n' - '| "x(arguments...)", "x.attribute" | ' - 'attribute reference |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '| "(expressions...)", "[expressions...]", "{key: | ' - 'Binding or tuple display, list |\n' - '| value...}", "{expressions...}" | ' - 'display, dictionary display, set |\n' - '| | ' - 'display |\n' - '+-------------------------------------------------+---------------------------------------+\n' - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] While "abs(x%y) < abs(y)" is true mathematically, ' - 'for floats\n' - ' it may not be true numerically due to roundoff. ' - 'For example, and\n' - ' assuming a platform on which a Python float is an ' - 'IEEE 754 double-\n' - ' precision number, in order that "-1e-100 % 1e100" ' - 'have the same\n' - ' sign as "1e100", the computed result is "-1e-100 + ' - '1e100", which\n' - ' is numerically exactly equal to "1e100". The ' - 'function\n' - ' "math.fmod()" returns a result whose sign matches ' - 'the sign of the\n' - ' first argument instead, and so returns "-1e-100" ' - 'in this case.\n' - ' Which approach is more appropriate depends on the ' - 'application.\n' - '\n' - '[2] If x is very close to an exact integer multiple of ' - "y, it's\n" - ' possible for "x//y" to be one larger than ' - '"(x-x%y)//y" due to\n' - ' rounding. In such cases, Python returns the ' - 'latter result, in\n' - ' order to preserve that "divmod(x,y)[0] * y + x % ' - 'y" be very close\n' - ' to "x".\n' - '\n' - '[3] While comparisons between strings make sense at ' - 'the byte\n' - ' level, they may be counter-intuitive to users. ' - 'For example, the\n' - ' strings ""\\u00C7"" and ""\\u0043\\u0327"" compare ' - 'differently, even\n' - ' though they both represent the same unicode ' - 'character (LATIN\n' - ' CAPITAL LETTER C WITH CEDILLA). To compare ' - 'strings in a human\n' - ' recognizable way, compare using ' - '"unicodedata.normalize()".\n' - '\n' - '[4] Due to automatic garbage-collection, free lists, ' - 'and the\n' - ' dynamic nature of descriptors, you may notice ' - 'seemingly unusual\n' - ' behaviour in certain uses of the "is" operator, ' - 'like those\n' - ' involving comparisons between instance methods, or ' - 'constants.\n' - ' Check their documentation for more info.\n' - '\n' - '[5] The "%" operator is also used for string ' - 'formatting; the same\n' - ' precedence applies.\n' - '\n' - '[6] The power operator "**" binds less tightly than an ' - 'arithmetic\n' - ' or bitwise unary operator on its right, that is, ' - '"2**-1" is "0.5".\n', - 'pass': '\n' - 'The "pass" statement\n' - '********************\n' - '\n' - ' pass_stmt ::= "pass"\n' - '\n' - '"pass" is a null operation --- when it is executed, nothing ' - 'happens.\n' - 'It is useful as a placeholder when a statement is required\n' - 'syntactically, but no code needs to be executed, for example:\n' - '\n' - ' def f(arg): pass # a function that does nothing (yet)\n' - '\n' - ' class C: pass # a class with no methods (yet)\n', - 'power': '\n' - 'The power operator\n' - '******************\n' - '\n' - 'The power operator binds more tightly than unary operators on ' - 'its\n' - 'left; it binds less tightly than unary operators on its right. ' - 'The\n' - 'syntax is:\n' - '\n' - ' power ::= await ["**" u_expr]\n' - '\n' - 'Thus, in an unparenthesized sequence of power and unary ' - 'operators, the\n' - 'operators are evaluated from right to left (this does not ' - 'constrain\n' - 'the evaluation order for the operands): "-1**2" results in "-1".\n' - '\n' - 'The power operator has the same semantics as the built-in ' - '"pow()"\n' - 'function, when called with two arguments: it yields its left ' - 'argument\n' - 'raised to the power of its right argument. The numeric arguments ' - 'are\n' - 'first converted to a common type, and the result is of that ' - 'type.\n' - '\n' - 'For int operands, the result has the same type as the operands ' - 'unless\n' - 'the second argument is negative; in that case, all arguments are\n' - 'converted to float and a float result is delivered. For example,\n' - '"10**2" returns "100", but "10**-2" returns "0.01".\n' - '\n' - 'Raising "0.0" to a negative power results in a ' - '"ZeroDivisionError".\n' - 'Raising a negative number to a fractional power results in a ' - '"complex"\n' - 'number. (In earlier versions it raised a "ValueError".)\n', - 'raise': '\n' - 'The "raise" statement\n' - '*********************\n' - '\n' - ' raise_stmt ::= "raise" [expression ["from" expression]]\n' - '\n' - 'If no expressions are present, "raise" re-raises the last ' - 'exception\n' - 'that was active in the current scope. If no exception is active ' - 'in\n' - 'the current scope, a "RuntimeError" exception is raised ' - 'indicating\n' - 'that this is an error.\n' - '\n' - 'Otherwise, "raise" evaluates the first expression as the ' - 'exception\n' - 'object. It must be either a subclass or an instance of\n' - '"BaseException". If it is a class, the exception instance will ' - 'be\n' - 'obtained when needed by instantiating the class with no ' - 'arguments.\n' - '\n' - "The *type* of the exception is the exception instance's class, " - 'the\n' - '*value* is the instance itself.\n' - '\n' - 'A traceback object is normally created automatically when an ' - 'exception\n' - 'is raised and attached to it as the "__traceback__" attribute, ' - 'which\n' - 'is writable. You can create an exception and set your own ' - 'traceback in\n' - 'one step using the "with_traceback()" exception method (which ' - 'returns\n' - 'the same exception instance, with its traceback set to its ' - 'argument),\n' - 'like so:\n' - '\n' - ' raise Exception("foo occurred").with_traceback(tracebackobj)\n' - '\n' - 'The "from" clause is used for exception chaining: if given, the ' - 'second\n' - '*expression* must be another exception class or instance, which ' - 'will\n' - 'then be attached to the raised exception as the "__cause__" ' - 'attribute\n' - '(which is writable). If the raised exception is not handled, ' - 'both\n' - 'exceptions will be printed:\n' - '\n' - ' >>> try:\n' - ' ... print(1 / 0)\n' - ' ... except Exception as exc:\n' - ' ... raise RuntimeError("Something bad happened") from exc\n' - ' ...\n' - ' Traceback (most recent call last):\n' - ' File "", line 2, in \n' - ' ZeroDivisionError: int division or modulo by zero\n' - '\n' - ' The above exception was the direct cause of the following ' - 'exception:\n' - '\n' - ' Traceback (most recent call last):\n' - ' File "", line 4, in \n' - ' RuntimeError: Something bad happened\n' - '\n' - 'A similar mechanism works implicitly if an exception is raised ' - 'inside\n' - 'an exception handler or a "finally" clause: the previous ' - 'exception is\n' - 'then attached as the new exception\'s "__context__" attribute:\n' - '\n' - ' >>> try:\n' - ' ... print(1 / 0)\n' - ' ... except:\n' - ' ... raise RuntimeError("Something bad happened")\n' - ' ...\n' - ' Traceback (most recent call last):\n' - ' File "", line 2, in \n' - ' ZeroDivisionError: int division or modulo by zero\n' - '\n' - ' During handling of the above exception, another exception ' - 'occurred:\n' - '\n' - ' Traceback (most recent call last):\n' - ' File "", line 4, in \n' - ' RuntimeError: Something bad happened\n' - '\n' - 'Additional information on exceptions can be found in section\n' - '*Exceptions*, and information about handling exceptions is in ' - 'section\n' - '*The try statement*.\n', - 'return': '\n' - 'The "return" statement\n' - '**********************\n' - '\n' - ' return_stmt ::= "return" [expression_list]\n' - '\n' - '"return" may only occur syntactically nested in a function ' - 'definition,\n' - 'not within a nested class definition.\n' - '\n' - 'If an expression list is present, it is evaluated, else "None" ' - 'is\n' - 'substituted.\n' - '\n' - '"return" leaves the current function call with the expression ' - 'list (or\n' - '"None") as return value.\n' - '\n' - 'When "return" passes control out of a "try" statement with a ' - '"finally"\n' - 'clause, that "finally" clause is executed before really leaving ' - 'the\n' - 'function.\n' - '\n' - 'In a generator function, the "return" statement indicates that ' - 'the\n' - 'generator is done and will cause "StopIteration" to be raised. ' - 'The\n' - 'returned value (if any) is used as an argument to construct\n' - '"StopIteration" and becomes the "StopIteration.value" ' - 'attribute.\n', - 'sequence-types': '\n' - 'Emulating container types\n' - '*************************\n' - '\n' - 'The following methods can be defined to implement ' - 'container objects.\n' - 'Containers usually are sequences (such as lists or ' - 'tuples) or mappings\n' - '(like dictionaries), but can represent other containers ' - 'as well. The\n' - 'first set of methods is used either to emulate a ' - 'sequence or to\n' - 'emulate a mapping; the difference is that for a ' - 'sequence, the\n' - 'allowable keys should be the integers *k* for which "0 ' - '<= k < N" where\n' - '*N* is the length of the sequence, or slice objects, ' - 'which define a\n' - 'range of items. It is also recommended that mappings ' - 'provide the\n' - 'methods "keys()", "values()", "items()", "get()", ' - '"clear()",\n' - '"setdefault()", "pop()", "popitem()", "copy()", and ' - '"update()"\n' - "behaving similar to those for Python's standard " - 'dictionary objects.\n' - 'The "collections" module provides a "MutableMapping" ' - 'abstract base\n' - 'class to help create those methods from a base set of ' - '"__getitem__()",\n' - '"__setitem__()", "__delitem__()", and "keys()". Mutable ' - 'sequences\n' - 'should provide methods "append()", "count()", "index()", ' - '"extend()",\n' - '"insert()", "pop()", "remove()", "reverse()" and ' - '"sort()", like Python\n' - 'standard list objects. Finally, sequence types should ' - 'implement\n' - 'addition (meaning concatenation) and multiplication ' - '(meaning\n' - 'repetition) by defining the methods "__add__()", ' - '"__radd__()",\n' - '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" ' - 'described\n' - 'below; they should not define other numerical ' - 'operators. It is\n' - 'recommended that both mappings and sequences implement ' - 'the\n' - '"__contains__()" method to allow efficient use of the ' - '"in" operator;\n' - 'for mappings, "in" should search the mapping\'s keys; ' - 'for sequences, it\n' - 'should search through the values. It is further ' - 'recommended that both\n' - 'mappings and sequences implement the "__iter__()" method ' - 'to allow\n' - 'efficient iteration through the container; for mappings, ' - '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should ' - 'iterate\n' - 'through the values.\n' - '\n' - 'object.__len__(self)\n' - '\n' - ' Called to implement the built-in function "len()". ' - 'Should return\n' - ' the length of the object, an integer ">=" 0. Also, ' - 'an object that\n' - ' doesn\'t define a "__bool__()" method and whose ' - '"__len__()" method\n' - ' returns zero is considered to be false in a Boolean ' - 'context.\n' - '\n' - 'object.__length_hint__(self)\n' - '\n' - ' Called to implement "operator.length_hint()". Should ' - 'return an\n' - ' estimated length for the object (which may be greater ' - 'or less than\n' - ' the actual length). The length must be an integer ' - '">=" 0. This\n' - ' method is purely an optimization and is never ' - 'required for\n' - ' correctness.\n' - '\n' - ' New in version 3.4.\n' - '\n' - 'Note: Slicing is done exclusively with the following ' - 'three methods.\n' - ' A call like\n' - '\n' - ' a[1:2] = b\n' - '\n' - ' is translated to\n' - '\n' - ' a[slice(1, 2, None)] = b\n' - '\n' - ' and so forth. Missing slice items are always filled ' - 'in with "None".\n' - '\n' - 'object.__getitem__(self, key)\n' - '\n' - ' Called to implement evaluation of "self[key]". For ' - 'sequence types,\n' - ' the accepted keys should be integers and slice ' - 'objects. Note that\n' - ' the special interpretation of negative indexes (if ' - 'the class wishes\n' - ' to emulate a sequence type) is up to the ' - '"__getitem__()" method. If\n' - ' *key* is of an inappropriate type, "TypeError" may be ' - 'raised; if of\n' - ' a value outside the set of indexes for the sequence ' - '(after any\n' - ' special interpretation of negative values), ' - '"IndexError" should be\n' - ' raised. For mapping types, if *key* is missing (not ' - 'in the\n' - ' container), "KeyError" should be raised.\n' - '\n' - ' Note: "for" loops expect that an "IndexError" will be ' - 'raised for\n' - ' illegal indexes to allow proper detection of the ' - 'end of the\n' - ' sequence.\n' - '\n' - 'object.__missing__(self, key)\n' - '\n' - ' Called by "dict"."__getitem__()" to implement ' - '"self[key]" for dict\n' - ' subclasses when key is not in the dictionary.\n' - '\n' - 'object.__setitem__(self, key, value)\n' - '\n' - ' Called to implement assignment to "self[key]". Same ' - 'note as for\n' - ' "__getitem__()". This should only be implemented for ' - 'mappings if\n' - ' the objects support changes to the values for keys, ' - 'or if new keys\n' - ' can be added, or for sequences if elements can be ' - 'replaced. The\n' - ' same exceptions should be raised for improper *key* ' - 'values as for\n' - ' the "__getitem__()" method.\n' - '\n' - 'object.__delitem__(self, key)\n' - '\n' - ' Called to implement deletion of "self[key]". Same ' - 'note as for\n' - ' "__getitem__()". This should only be implemented for ' - 'mappings if\n' - ' the objects support removal of keys, or for sequences ' - 'if elements\n' - ' can be removed from the sequence. The same ' - 'exceptions should be\n' - ' raised for improper *key* values as for the ' - '"__getitem__()" method.\n' - '\n' - 'object.__iter__(self)\n' - '\n' - ' This method is called when an iterator is required ' - 'for a container.\n' - ' This method should return a new iterator object that ' - 'can iterate\n' - ' over all the objects in the container. For mappings, ' - 'it should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; ' - 'they are\n' - ' required to return themselves. For more information ' - 'on iterator\n' - ' objects, see *Iterator Types*.\n' - '\n' - 'object.__reversed__(self)\n' - '\n' - ' Called (if present) by the "reversed()" built-in to ' - 'implement\n' - ' reverse iteration. It should return a new iterator ' - 'object that\n' - ' iterates over all the objects in the container in ' - 'reverse order.\n' - '\n' - ' If the "__reversed__()" method is not provided, the ' - '"reversed()"\n' - ' built-in will fall back to using the sequence ' - 'protocol ("__len__()"\n' - ' and "__getitem__()"). Objects that support the ' - 'sequence protocol\n' - ' should only provide "__reversed__()" if they can ' - 'provide an\n' - ' implementation that is more efficient than the one ' - 'provided by\n' - ' "reversed()".\n' - '\n' - 'The membership test operators ("in" and "not in") are ' - 'normally\n' - 'implemented as an iteration through a sequence. ' - 'However, container\n' - 'objects can supply the following special method with a ' - 'more efficient\n' - 'implementation, which also does not require the object ' - 'be a sequence.\n' - '\n' - 'object.__contains__(self, item)\n' - '\n' - ' Called to implement membership test operators. ' - 'Should return true\n' - ' if *item* is in *self*, false otherwise. For mapping ' - 'objects, this\n' - ' should consider the keys of the mapping rather than ' - 'the values or\n' - ' the key-item pairs.\n' - '\n' - ' For objects that don\'t define "__contains__()", the ' - 'membership test\n' - ' first tries iteration via "__iter__()", then the old ' - 'sequence\n' - ' iteration protocol via "__getitem__()", see *this ' - 'section in the\n' - ' language reference*.\n', - 'shifting': '\n' - 'Shifting operations\n' - '*******************\n' - '\n' - 'The shifting operations have lower priority than the ' - 'arithmetic\n' - 'operations:\n' - '\n' - ' shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n' - '\n' - 'These operators accept integers as arguments. They shift the ' - 'first\n' - 'argument to the left or right by the number of bits given by ' - 'the\n' - 'second argument.\n' - '\n' - 'A right shift by *n* bits is defined as floor division by ' - '"pow(2,n)".\n' - 'A left shift by *n* bits is defined as multiplication with ' - '"pow(2,n)".\n' - '\n' - 'Note: In the current implementation, the right-hand operand ' - 'is\n' - ' required to be at most "sys.maxsize". If the right-hand ' - 'operand is\n' - ' larger than "sys.maxsize" an "OverflowError" exception is ' - 'raised.\n', - 'slicings': '\n' - 'Slicings\n' - '********\n' - '\n' - 'A slicing selects a range of items in a sequence object (e.g., ' - 'a\n' - 'string, tuple or list). Slicings may be used as expressions ' - 'or as\n' - 'targets in assignment or "del" statements. The syntax for a ' - 'slicing:\n' - '\n' - ' slicing ::= primary "[" slice_list "]"\n' - ' slice_list ::= slice_item ("," slice_item)* [","]\n' - ' slice_item ::= expression | proper_slice\n' - ' proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" ' - '[stride] ]\n' - ' lower_bound ::= expression\n' - ' upper_bound ::= expression\n' - ' stride ::= expression\n' - '\n' - 'There is ambiguity in the formal syntax here: anything that ' - 'looks like\n' - 'an expression list also looks like a slice list, so any ' - 'subscription\n' - 'can be interpreted as a slicing. Rather than further ' - 'complicating the\n' - 'syntax, this is disambiguated by defining that in this case ' - 'the\n' - 'interpretation as a subscription takes priority over the\n' - 'interpretation as a slicing (this is the case if the slice ' - 'list\n' - 'contains no proper slice).\n' - '\n' - 'The semantics for a slicing are as follows. The primary is ' - 'indexed\n' - '(using the same "__getitem__()" method as normal subscription) ' - 'with a\n' - 'key that is constructed from the slice list, as follows. If ' - 'the slice\n' - 'list contains at least one comma, the key is a tuple ' - 'containing the\n' - 'conversion of the slice items; otherwise, the conversion of ' - 'the lone\n' - 'slice item is the key. The conversion of a slice item that is ' - 'an\n' - 'expression is that expression. The conversion of a proper ' - 'slice is a\n' - 'slice object (see section *The standard type hierarchy*) ' - 'whose\n' - '"start", "stop" and "step" attributes are the values of the\n' - 'expressions given as lower bound, upper bound and stride,\n' - 'respectively, substituting "None" for missing expressions.\n', - 'specialattrs': '\n' - 'Special Attributes\n' - '******************\n' - '\n' - 'The implementation adds a few special read-only attributes ' - 'to several\n' - 'object types, where they are relevant. Some of these are ' - 'not reported\n' - 'by the "dir()" built-in function.\n' - '\n' - 'object.__dict__\n' - '\n' - ' A dictionary or other mapping object used to store an ' - "object's\n" - ' (writable) attributes.\n' - '\n' - 'instance.__class__\n' - '\n' - ' The class to which a class instance belongs.\n' - '\n' - 'class.__bases__\n' - '\n' - ' The tuple of base classes of a class object.\n' - '\n' - 'class.__name__\n' - '\n' - ' The name of the class or type.\n' - '\n' - 'class.__qualname__\n' - '\n' - ' The *qualified name* of the class or type.\n' - '\n' - ' New in version 3.3.\n' - '\n' - 'class.__mro__\n' - '\n' - ' This attribute is a tuple of classes that are ' - 'considered when\n' - ' looking for base classes during method resolution.\n' - '\n' - 'class.mro()\n' - '\n' - ' This method can be overridden by a metaclass to ' - 'customize the\n' - ' method resolution order for its instances. It is ' - 'called at class\n' - ' instantiation, and its result is stored in "__mro__".\n' - '\n' - 'class.__subclasses__()\n' - '\n' - ' Each class keeps a list of weak references to its ' - 'immediate\n' - ' subclasses. This method returns a list of all those ' - 'references\n' - ' still alive. Example:\n' - '\n' - ' >>> int.__subclasses__()\n' - " []\n" - '\n' - '-[ Footnotes ]-\n' - '\n' - '[1] Additional information on these special methods may be ' - 'found\n' - ' in the Python Reference Manual (*Basic ' - 'customization*).\n' - '\n' - '[2] As a consequence, the list "[1, 2]" is considered ' - 'equal to\n' - ' "[1.0, 2.0]", and similarly for tuples.\n' - '\n' - "[3] They must have since the parser can't tell the type of " - 'the\n' - ' operands.\n' - '\n' - '[4] Cased characters are those with general category ' - 'property\n' - ' being one of "Lu" (Letter, uppercase), "Ll" (Letter, ' - 'lowercase),\n' - ' or "Lt" (Letter, titlecase).\n' - '\n' - '[5] To format only a tuple you should therefore provide a\n' - ' singleton tuple whose only element is the tuple to be ' - 'formatted.\n', - 'specialnames': '\n' - 'Special method names\n' - '********************\n' - '\n' - 'A class can implement certain operations that are invoked ' - 'by special\n' - 'syntax (such as arithmetic operations or subscripting and ' - 'slicing) by\n' - "defining methods with special names. This is Python's " - 'approach to\n' - '*operator overloading*, allowing classes to define their ' - 'own behavior\n' - 'with respect to language operators. For instance, if a ' - 'class defines\n' - 'a method named "__getitem__()", and "x" is an instance of ' - 'this class,\n' - 'then "x[i]" is roughly equivalent to ' - '"type(x).__getitem__(x, i)".\n' - 'Except where mentioned, attempts to execute an operation ' - 'raise an\n' - 'exception when no appropriate method is defined ' - '(typically\n' - '"AttributeError" or "TypeError").\n' - '\n' - 'When implementing a class that emulates any built-in type, ' - 'it is\n' - 'important that the emulation only be implemented to the ' - 'degree that it\n' - 'makes sense for the object being modelled. For example, ' - 'some\n' - 'sequences may work well with retrieval of individual ' - 'elements, but\n' - 'extracting a slice may not make sense. (One example of ' - 'this is the\n' - '"NodeList" interface in the W3C\'s Document Object ' - 'Model.)\n' - '\n' - '\n' - 'Basic customization\n' - '===================\n' - '\n' - 'object.__new__(cls[, ...])\n' - '\n' - ' Called to create a new instance of class *cls*. ' - '"__new__()" is a\n' - ' static method (special-cased so you need not declare it ' - 'as such)\n' - ' that takes the class of which an instance was requested ' - 'as its\n' - ' first argument. The remaining arguments are those ' - 'passed to the\n' - ' object constructor expression (the call to the class). ' - 'The return\n' - ' value of "__new__()" should be the new object instance ' - '(usually an\n' - ' instance of *cls*).\n' - '\n' - ' Typical implementations create a new instance of the ' - 'class by\n' - ' invoking the superclass\'s "__new__()" method using\n' - ' "super(currentclass, cls).__new__(cls[, ...])" with ' - 'appropriate\n' - ' arguments and then modifying the newly-created instance ' - 'as\n' - ' necessary before returning it.\n' - '\n' - ' If "__new__()" returns an instance of *cls*, then the ' - 'new\n' - ' instance\'s "__init__()" method will be invoked like\n' - ' "__init__(self[, ...])", where *self* is the new ' - 'instance and the\n' - ' remaining arguments are the same as were passed to ' - '"__new__()".\n' - '\n' - ' If "__new__()" does not return an instance of *cls*, ' - 'then the new\n' - ' instance\'s "__init__()" method will not be invoked.\n' - '\n' - ' "__new__()" is intended mainly to allow subclasses of ' - 'immutable\n' - ' types (like int, str, or tuple) to customize instance ' - 'creation. It\n' - ' is also commonly overridden in custom metaclasses in ' - 'order to\n' - ' customize class creation.\n' - '\n' - 'object.__init__(self[, ...])\n' - '\n' - ' Called after the instance has been created (by ' - '"__new__()"), but\n' - ' before it is returned to the caller. The arguments are ' - 'those\n' - ' passed to the class constructor expression. If a base ' - 'class has an\n' - ' "__init__()" method, the derived class\'s "__init__()" ' - 'method, if\n' - ' any, must explicitly call it to ensure proper ' - 'initialization of the\n' - ' base class part of the instance; for example:\n' - ' "BaseClass.__init__(self, [args...])".\n' - '\n' - ' Because "__new__()" and "__init__()" work together in ' - 'constructing\n' - ' objects ("__new__()" to create it, and "__init__()" to ' - 'customise\n' - ' it), no non-"None" value may be returned by ' - '"__init__()"; doing so\n' - ' will cause a "TypeError" to be raised at runtime.\n' - '\n' - 'object.__del__(self)\n' - '\n' - ' Called when the instance is about to be destroyed. ' - 'This is also\n' - ' called a destructor. If a base class has a "__del__()" ' - 'method, the\n' - ' derived class\'s "__del__()" method, if any, must ' - 'explicitly call it\n' - ' to ensure proper deletion of the base class part of the ' - 'instance.\n' - ' Note that it is possible (though not recommended!) for ' - 'the\n' - ' "__del__()" method to postpone destruction of the ' - 'instance by\n' - ' creating a new reference to it. It may then be called ' - 'at a later\n' - ' time when this new reference is deleted. It is not ' - 'guaranteed that\n' - ' "__del__()" methods are called for objects that still ' - 'exist when\n' - ' the interpreter exits.\n' - '\n' - ' Note: "del x" doesn\'t directly call "x.__del__()" --- ' - 'the former\n' - ' decrements the reference count for "x" by one, and ' - 'the latter is\n' - ' only called when "x"\'s reference count reaches ' - 'zero. Some common\n' - ' situations that may prevent the reference count of an ' - 'object from\n' - ' going to zero include: circular references between ' - 'objects (e.g.,\n' - ' a doubly-linked list or a tree data structure with ' - 'parent and\n' - ' child pointers); a reference to the object on the ' - 'stack frame of\n' - ' a function that caught an exception (the traceback ' - 'stored in\n' - ' "sys.exc_info()[2]" keeps the stack frame alive); or ' - 'a reference\n' - ' to the object on the stack frame that raised an ' - 'unhandled\n' - ' exception in interactive mode (the traceback stored ' - 'in\n' - ' "sys.last_traceback" keeps the stack frame alive). ' - 'The first\n' - ' situation can only be remedied by explicitly breaking ' - 'the cycles;\n' - ' the second can be resolved by freeing the reference ' - 'to the\n' - ' traceback object when it is no longer useful, and the ' - 'third can\n' - ' be resolved by storing "None" in ' - '"sys.last_traceback". Circular\n' - ' references which are garbage are detected and cleaned ' - 'up when the\n' - " cyclic garbage collector is enabled (it's on by " - 'default). Refer\n' - ' to the documentation for the "gc" module for more ' - 'information\n' - ' about this topic.\n' - '\n' - ' Warning: Due to the precarious circumstances under ' - 'which\n' - ' "__del__()" methods are invoked, exceptions that ' - 'occur during\n' - ' their execution are ignored, and a warning is printed ' - 'to\n' - ' "sys.stderr" instead. Also, when "__del__()" is ' - 'invoked in\n' - ' response to a module being deleted (e.g., when ' - 'execution of the\n' - ' program is done), other globals referenced by the ' - '"__del__()"\n' - ' method may already have been deleted or in the ' - 'process of being\n' - ' torn down (e.g. the import machinery shutting down). ' - 'For this\n' - ' reason, "__del__()" methods should do the absolute ' - 'minimum needed\n' - ' to maintain external invariants. Starting with ' - 'version 1.5,\n' - ' Python guarantees that globals whose name begins with ' - 'a single\n' - ' underscore are deleted from their module before other ' - 'globals are\n' - ' deleted; if no other references to such globals ' - 'exist, this may\n' - ' help in assuring that imported modules are still ' - 'available at the\n' - ' time when the "__del__()" method is called.\n' - '\n' - 'object.__repr__(self)\n' - '\n' - ' Called by the "repr()" built-in function to compute the ' - '"official"\n' - ' string representation of an object. If at all ' - 'possible, this\n' - ' should look like a valid Python expression that could ' - 'be used to\n' - ' recreate an object with the same value (given an ' - 'appropriate\n' - ' environment). If this is not possible, a string of the ' - 'form\n' - ' "<...some useful description...>" should be returned. ' - 'The return\n' - ' value must be a string object. If a class defines ' - '"__repr__()" but\n' - ' not "__str__()", then "__repr__()" is also used when an ' - '"informal"\n' - ' string representation of instances of that class is ' - 'required.\n' - '\n' - ' This is typically used for debugging, so it is ' - 'important that the\n' - ' representation is information-rich and unambiguous.\n' - '\n' - 'object.__str__(self)\n' - '\n' - ' Called by "str(object)" and the built-in functions ' - '"format()" and\n' - ' "print()" to compute the "informal" or nicely printable ' - 'string\n' - ' representation of an object. The return value must be ' - 'a *string*\n' - ' object.\n' - '\n' - ' This method differs from "object.__repr__()" in that ' - 'there is no\n' - ' expectation that "__str__()" return a valid Python ' - 'expression: a\n' - ' more convenient or concise representation can be used.\n' - '\n' - ' The default implementation defined by the built-in type ' - '"object"\n' - ' calls "object.__repr__()".\n' - '\n' - 'object.__bytes__(self)\n' - '\n' - ' Called by "bytes()" to compute a byte-string ' - 'representation of an\n' - ' object. This should return a "bytes" object.\n' - '\n' - 'object.__format__(self, format_spec)\n' - '\n' - ' Called by the "format()" built-in function (and by ' - 'extension, the\n' - ' "str.format()" method of class "str") to produce a ' - '"formatted"\n' - ' string representation of an object. The "format_spec" ' - 'argument is a\n' - ' string that contains a description of the formatting ' - 'options\n' - ' desired. The interpretation of the "format_spec" ' - 'argument is up to\n' - ' the type implementing "__format__()", however most ' - 'classes will\n' - ' either delegate formatting to one of the built-in ' - 'types, or use a\n' - ' similar formatting option syntax.\n' - '\n' - ' See *Format Specification Mini-Language* for a ' - 'description of the\n' - ' standard formatting syntax.\n' - '\n' - ' The return value must be a string object.\n' - '\n' - ' Changed in version 3.4: The __format__ method of ' - '"object" itself\n' - ' raises a "TypeError" if passed any non-empty string.\n' - '\n' - 'object.__lt__(self, other)\n' - 'object.__le__(self, other)\n' - 'object.__eq__(self, other)\n' - 'object.__ne__(self, other)\n' - 'object.__gt__(self, other)\n' - 'object.__ge__(self, other)\n' - '\n' - ' These are the so-called "rich comparison" methods. The\n' - ' correspondence between operator symbols and method ' - 'names is as\n' - ' follows: "xy" calls\n' - ' "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n' - '\n' - ' A rich comparison method may return the singleton ' - '"NotImplemented"\n' - ' if it does not implement the operation for a given pair ' - 'of\n' - ' arguments. By convention, "False" and "True" are ' - 'returned for a\n' - ' successful comparison. However, these methods can ' - 'return any value,\n' - ' so if the comparison operator is used in a Boolean ' - 'context (e.g.,\n' - ' in the condition of an "if" statement), Python will ' - 'call "bool()"\n' - ' on the value to determine if the result is true or ' - 'false.\n' - '\n' - ' By default, "__ne__()" delegates to "__eq__()" and ' - 'inverts the\n' - ' result unless it is "NotImplemented". There are no ' - 'other implied\n' - ' relationships among the comparison operators, for ' - 'example, the\n' - ' truth of "(x.__hash__".\n' - '\n' - ' If a class that does not override "__eq__()" wishes to ' - 'suppress\n' - ' hash support, it should include "__hash__ = None" in ' - 'the class\n' - ' definition. A class which defines its own "__hash__()" ' - 'that\n' - ' explicitly raises a "TypeError" would be incorrectly ' - 'identified as\n' - ' hashable by an "isinstance(obj, collections.Hashable)" ' - 'call.\n' - '\n' - ' Note: By default, the "__hash__()" values of str, bytes ' - 'and\n' - ' datetime objects are "salted" with an unpredictable ' - 'random value.\n' - ' Although they remain constant within an individual ' - 'Python\n' - ' process, they are not predictable between repeated ' - 'invocations of\n' - ' Python.This is intended to provide protection against ' - 'a denial-\n' - ' of-service caused by carefully-chosen inputs that ' - 'exploit the\n' - ' worst case performance of a dict insertion, O(n^2) ' - 'complexity.\n' - ' See ' - 'http://www.ocert.org/advisories/ocert-2011-003.html for\n' - ' details.Changing hash values affects the iteration ' - 'order of\n' - ' dicts, sets and other mappings. Python has never ' - 'made guarantees\n' - ' about this ordering (and it typically varies between ' - '32-bit and\n' - ' 64-bit builds).See also "PYTHONHASHSEED".\n' - '\n' - ' Changed in version 3.3: Hash randomization is enabled ' - 'by default.\n' - '\n' - 'object.__bool__(self)\n' - '\n' - ' Called to implement truth value testing and the ' - 'built-in operation\n' - ' "bool()"; should return "False" or "True". When this ' - 'method is not\n' - ' defined, "__len__()" is called, if it is defined, and ' - 'the object is\n' - ' considered true if its result is nonzero. If a class ' - 'defines\n' - ' neither "__len__()" nor "__bool__()", all its instances ' - 'are\n' - ' considered true.\n' - '\n' - '\n' - 'Customizing attribute access\n' - '============================\n' - '\n' - 'The following methods can be defined to customize the ' - 'meaning of\n' - 'attribute access (use of, assignment to, or deletion of ' - '"x.name") for\n' - 'class instances.\n' - '\n' - 'object.__getattr__(self, name)\n' - '\n' - ' Called when an attribute lookup has not found the ' - 'attribute in the\n' - ' usual places (i.e. it is not an instance attribute nor ' - 'is it found\n' - ' in the class tree for "self"). "name" is the attribute ' - 'name. This\n' - ' method should return the (computed) attribute value or ' - 'raise an\n' - ' "AttributeError" exception.\n' - '\n' - ' Note that if the attribute is found through the normal ' - 'mechanism,\n' - ' "__getattr__()" is not called. (This is an intentional ' - 'asymmetry\n' - ' between "__getattr__()" and "__setattr__()".) This is ' - 'done both for\n' - ' efficiency reasons and because otherwise ' - '"__getattr__()" would have\n' - ' no way to access other attributes of the instance. ' - 'Note that at\n' - ' least for instance variables, you can fake total ' - 'control by not\n' - ' inserting any values in the instance attribute ' - 'dictionary (but\n' - ' instead inserting them in another object). See the\n' - ' "__getattribute__()" method below for a way to actually ' - 'get total\n' - ' control over attribute access.\n' - '\n' - 'object.__getattribute__(self, name)\n' - '\n' - ' Called unconditionally to implement attribute accesses ' - 'for\n' - ' instances of the class. If the class also defines ' - '"__getattr__()",\n' - ' the latter will not be called unless ' - '"__getattribute__()" either\n' - ' calls it explicitly or raises an "AttributeError". This ' - 'method\n' - ' should return the (computed) attribute value or raise ' - 'an\n' - ' "AttributeError" exception. In order to avoid infinite ' - 'recursion in\n' - ' this method, its implementation should always call the ' - 'base class\n' - ' method with the same name to access any attributes it ' - 'needs, for\n' - ' example, "object.__getattribute__(self, name)".\n' - '\n' - ' Note: This method may still be bypassed when looking up ' - 'special\n' - ' methods as the result of implicit invocation via ' - 'language syntax\n' - ' or built-in functions. See *Special method lookup*.\n' - '\n' - 'object.__setattr__(self, name, value)\n' - '\n' - ' Called when an attribute assignment is attempted. This ' - 'is called\n' - ' instead of the normal mechanism (i.e. store the value ' - 'in the\n' - ' instance dictionary). *name* is the attribute name, ' - '*value* is the\n' - ' value to be assigned to it.\n' - '\n' - ' If "__setattr__()" wants to assign to an instance ' - 'attribute, it\n' - ' should call the base class method with the same name, ' - 'for example,\n' - ' "object.__setattr__(self, name, value)".\n' - '\n' - 'object.__delattr__(self, name)\n' - '\n' - ' Like "__setattr__()" but for attribute deletion instead ' - 'of\n' - ' assignment. This should only be implemented if "del ' - 'obj.name" is\n' - ' meaningful for the object.\n' - '\n' - 'object.__dir__(self)\n' - '\n' - ' Called when "dir()" is called on the object. A sequence ' - 'must be\n' - ' returned. "dir()" converts the returned sequence to a ' - 'list and\n' - ' sorts it.\n' - '\n' - '\n' - 'Implementing Descriptors\n' - '------------------------\n' - '\n' - 'The following methods only apply when an instance of the ' - 'class\n' - 'containing the method (a so-called *descriptor* class) ' - 'appears in an\n' - '*owner* class (the descriptor must be in either the ' - "owner's class\n" - 'dictionary or in the class dictionary for one of its ' - 'parents). In the\n' - 'examples below, "the attribute" refers to the attribute ' - 'whose name is\n' - 'the key of the property in the owner class\' "__dict__".\n' - '\n' - 'object.__get__(self, instance, owner)\n' - '\n' - ' Called to get the attribute of the owner class (class ' - 'attribute\n' - ' access) or of an instance of that class (instance ' - 'attribute\n' - ' access). *owner* is always the owner class, while ' - '*instance* is the\n' - ' instance that the attribute was accessed through, or ' - '"None" when\n' - ' the attribute is accessed through the *owner*. This ' - 'method should\n' - ' return the (computed) attribute value or raise an ' - '"AttributeError"\n' - ' exception.\n' - '\n' - 'object.__set__(self, instance, value)\n' - '\n' - ' Called to set the attribute on an instance *instance* ' - 'of the owner\n' - ' class to a new value, *value*.\n' - '\n' - 'object.__delete__(self, instance)\n' - '\n' - ' Called to delete the attribute on an instance ' - '*instance* of the\n' - ' owner class.\n' - '\n' - 'The attribute "__objclass__" is interpreted by the ' - '"inspect" module as\n' - 'specifying the class where this object was defined ' - '(setting this\n' - 'appropriately can assist in runtime introspection of ' - 'dynamic class\n' - 'attributes). For callables, it may indicate that an ' - 'instance of the\n' - 'given type (or a subclass) is expected or required as the ' - 'first\n' - 'positional argument (for example, CPython sets this ' - 'attribute for\n' - 'unbound methods that are implemented in C).\n' - '\n' - '\n' - 'Invoking Descriptors\n' - '--------------------\n' - '\n' - 'In general, a descriptor is an object attribute with ' - '"binding\n' - 'behavior", one whose attribute access has been overridden ' - 'by methods\n' - 'in the descriptor protocol: "__get__()", "__set__()", ' - 'and\n' - '"__delete__()". If any of those methods are defined for an ' - 'object, it\n' - 'is said to be a descriptor.\n' - '\n' - 'The default behavior for attribute access is to get, set, ' - 'or delete\n' - "the attribute from an object's dictionary. For instance, " - '"a.x" has a\n' - 'lookup chain starting with "a.__dict__[\'x\']", then\n' - '"type(a).__dict__[\'x\']", and continuing through the base ' - 'classes of\n' - '"type(a)" excluding metaclasses.\n' - '\n' - 'However, if the looked-up value is an object defining one ' - 'of the\n' - 'descriptor methods, then Python may override the default ' - 'behavior and\n' - 'invoke the descriptor method instead. Where this occurs ' - 'in the\n' - 'precedence chain depends on which descriptor methods were ' - 'defined and\n' - 'how they were called.\n' - '\n' - 'The starting point for descriptor invocation is a binding, ' - '"a.x". How\n' - 'the arguments are assembled depends on "a":\n' - '\n' - 'Direct Call\n' - ' The simplest and least common call is when user code ' - 'directly\n' - ' invokes a descriptor method: "x.__get__(a)".\n' - '\n' - 'Instance Binding\n' - ' If binding to an object instance, "a.x" is transformed ' - 'into the\n' - ' call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n' - '\n' - 'Class Binding\n' - ' If binding to a class, "A.x" is transformed into the ' - 'call:\n' - ' "A.__dict__[\'x\'].__get__(None, A)".\n' - '\n' - 'Super Binding\n' - ' If "a" is an instance of "super", then the binding ' - '"super(B,\n' - ' obj).m()" searches "obj.__class__.__mro__" for the base ' - 'class "A"\n' - ' immediately preceding "B" and then invokes the ' - 'descriptor with the\n' - ' call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n' - '\n' - 'For instance bindings, the precedence of descriptor ' - 'invocation depends\n' - 'on the which descriptor methods are defined. A descriptor ' - 'can define\n' - 'any combination of "__get__()", "__set__()" and ' - '"__delete__()". If it\n' - 'does not define "__get__()", then accessing the attribute ' - 'will return\n' - 'the descriptor object itself unless there is a value in ' - "the object's\n" - 'instance dictionary. If the descriptor defines ' - '"__set__()" and/or\n' - '"__delete__()", it is a data descriptor; if it defines ' - 'neither, it is\n' - 'a non-data descriptor. Normally, data descriptors define ' - 'both\n' - '"__get__()" and "__set__()", while non-data descriptors ' - 'have just the\n' - '"__get__()" method. Data descriptors with "__set__()" and ' - '"__get__()"\n' - 'defined always override a redefinition in an instance ' - 'dictionary. In\n' - 'contrast, non-data descriptors can be overridden by ' - 'instances.\n' - '\n' - 'Python methods (including "staticmethod()" and ' - '"classmethod()") are\n' - 'implemented as non-data descriptors. Accordingly, ' - 'instances can\n' - 'redefine and override methods. This allows individual ' - 'instances to\n' - 'acquire behaviors that differ from other instances of the ' - 'same class.\n' - '\n' - 'The "property()" function is implemented as a data ' - 'descriptor.\n' - 'Accordingly, instances cannot override the behavior of a ' - 'property.\n' - '\n' - '\n' - '__slots__\n' - '---------\n' - '\n' - 'By default, instances of classes have a dictionary for ' - 'attribute\n' - 'storage. This wastes space for objects having very few ' - 'instance\n' - 'variables. The space consumption can become acute when ' - 'creating large\n' - 'numbers of instances.\n' - '\n' - 'The default can be overridden by defining *__slots__* in a ' - 'class\n' - 'definition. The *__slots__* declaration takes a sequence ' - 'of instance\n' - 'variables and reserves just enough space in each instance ' - 'to hold a\n' - 'value for each variable. Space is saved because ' - '*__dict__* is not\n' - 'created for each instance.\n' - '\n' - 'object.__slots__\n' - '\n' - ' This class variable can be assigned a string, iterable, ' - 'or sequence\n' - ' of strings with variable names used by instances. ' - '*__slots__*\n' - ' reserves space for the declared variables and prevents ' - 'the\n' - ' automatic creation of *__dict__* and *__weakref__* for ' - 'each\n' - ' instance.\n' - '\n' - '\n' - 'Notes on using *__slots__*\n' - '~~~~~~~~~~~~~~~~~~~~~~~~~~\n' - '\n' - '* When inheriting from a class without *__slots__*, the ' - '*__dict__*\n' - ' attribute of that class will always be accessible, so a ' - '*__slots__*\n' - ' definition in the subclass is meaningless.\n' - '\n' - '* Without a *__dict__* variable, instances cannot be ' - 'assigned new\n' - ' variables not listed in the *__slots__* definition. ' - 'Attempts to\n' - ' assign to an unlisted variable name raises ' - '"AttributeError". If\n' - ' dynamic assignment of new variables is desired, then ' - 'add\n' - ' "\'__dict__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' - '\n' - '* Without a *__weakref__* variable for each instance, ' - 'classes\n' - ' defining *__slots__* do not support weak references to ' - 'its\n' - ' instances. If weak reference support is needed, then ' - 'add\n' - ' "\'__weakref__\'" to the sequence of strings in the ' - '*__slots__*\n' - ' declaration.\n' - '\n' - '* *__slots__* are implemented at the class level by ' - 'creating\n' - ' descriptors (*Implementing Descriptors*) for each ' - 'variable name. As\n' - ' a result, class attributes cannot be used to set default ' - 'values for\n' - ' instance variables defined by *__slots__*; otherwise, ' - 'the class\n' - ' attribute would overwrite the descriptor assignment.\n' - '\n' - '* The action of a *__slots__* declaration is limited to ' - 'the class\n' - ' where it is defined. As a result, subclasses will have ' - 'a *__dict__*\n' - ' unless they also define *__slots__* (which must only ' - 'contain names\n' - ' of any *additional* slots).\n' - '\n' - '* If a class defines a slot also defined in a base class, ' - 'the\n' - ' instance variable defined by the base class slot is ' - 'inaccessible\n' - ' (except by retrieving its descriptor directly from the ' - 'base class).\n' - ' This renders the meaning of the program undefined. In ' - 'the future, a\n' - ' check may be added to prevent this.\n' - '\n' - '* Nonempty *__slots__* does not work for classes derived ' - 'from\n' - ' "variable-length" built-in types such as "int", "bytes" ' - 'and "tuple".\n' - '\n' - '* Any non-string iterable may be assigned to *__slots__*. ' - 'Mappings\n' - ' may also be used; however, in the future, special ' - 'meaning may be\n' - ' assigned to the values corresponding to each key.\n' - '\n' - '* *__class__* assignment works only if both classes have ' - 'the same\n' - ' *__slots__*.\n' - '\n' - '\n' - 'Customizing class creation\n' - '==========================\n' - '\n' - 'By default, classes are constructed using "type()". The ' - 'class body is\n' - 'executed in a new namespace and the class name is bound ' - 'locally to the\n' - 'result of "type(name, bases, namespace)".\n' - '\n' - 'The class creation process can be customised by passing ' - 'the\n' - '"metaclass" keyword argument in the class definition line, ' - 'or by\n' - 'inheriting from an existing class that included such an ' - 'argument. In\n' - 'the following example, both "MyClass" and "MySubclass" are ' - 'instances\n' - 'of "Meta":\n' - '\n' - ' class Meta(type):\n' - ' pass\n' - '\n' - ' class MyClass(metaclass=Meta):\n' - ' pass\n' - '\n' - ' class MySubclass(MyClass):\n' - ' pass\n' - '\n' - 'Any other keyword arguments that are specified in the ' - 'class definition\n' - 'are passed through to all metaclass operations described ' - 'below.\n' - '\n' - 'When a class definition is executed, the following steps ' - 'occur:\n' - '\n' - '* the appropriate metaclass is determined\n' - '\n' - '* the class namespace is prepared\n' - '\n' - '* the class body is executed\n' - '\n' - '* the class object is created\n' - '\n' - '\n' - 'Determining the appropriate metaclass\n' - '-------------------------------------\n' - '\n' - 'The appropriate metaclass for a class definition is ' - 'determined as\n' - 'follows:\n' - '\n' - '* if no bases and no explicit metaclass are given, then ' - '"type()" is\n' - ' used\n' - '\n' - '* if an explicit metaclass is given and it is *not* an ' - 'instance of\n' - ' "type()", then it is used directly as the metaclass\n' - '\n' - '* if an instance of "type()" is given as the explicit ' - 'metaclass, or\n' - ' bases are defined, then the most derived metaclass is ' - 'used\n' - '\n' - 'The most derived metaclass is selected from the explicitly ' - 'specified\n' - 'metaclass (if any) and the metaclasses (i.e. "type(cls)") ' - 'of all\n' - 'specified base classes. The most derived metaclass is one ' - 'which is a\n' - 'subtype of *all* of these candidate metaclasses. If none ' - 'of the\n' - 'candidate metaclasses meets that criterion, then the class ' - 'definition\n' - 'will fail with "TypeError".\n' - '\n' - '\n' - 'Preparing the class namespace\n' - '-----------------------------\n' - '\n' - 'Once the appropriate metaclass has been identified, then ' - 'the class\n' - 'namespace is prepared. If the metaclass has a ' - '"__prepare__" attribute,\n' - 'it is called as "namespace = metaclass.__prepare__(name, ' - 'bases,\n' - '**kwds)" (where the additional keyword arguments, if any, ' - 'come from\n' - 'the class definition).\n' - '\n' - 'If the metaclass has no "__prepare__" attribute, then the ' - 'class\n' - 'namespace is initialised as an empty "dict()" instance.\n' - '\n' - 'See also: **PEP 3115** - Metaclasses in Python 3000\n' - '\n' - ' Introduced the "__prepare__" namespace hook\n' - '\n' - '\n' - 'Executing the class body\n' - '------------------------\n' - '\n' - 'The class body is executed (approximately) as "exec(body, ' - 'globals(),\n' - 'namespace)". The key difference from a normal call to ' - '"exec()" is that\n' - 'lexical scoping allows the class body (including any ' - 'methods) to\n' - 'reference names from the current and outer scopes when the ' - 'class\n' - 'definition occurs inside a function.\n' - '\n' - 'However, even when the class definition occurs inside the ' - 'function,\n' - 'methods defined inside the class still cannot see names ' - 'defined at the\n' - 'class scope. Class variables must be accessed through the ' - 'first\n' - 'parameter of instance or class methods, and cannot be ' - 'accessed at all\n' - 'from static methods.\n' - '\n' - '\n' - 'Creating the class object\n' - '-------------------------\n' - '\n' - 'Once the class namespace has been populated by executing ' - 'the class\n' - 'body, the class object is created by calling ' - '"metaclass(name, bases,\n' - 'namespace, **kwds)" (the additional keywords passed here ' - 'are the same\n' - 'as those passed to "__prepare__").\n' - '\n' - 'This class object is the one that will be referenced by ' - 'the zero-\n' - 'argument form of "super()". "__class__" is an implicit ' - 'closure\n' - 'reference created by the compiler if any methods in a ' - 'class body refer\n' - 'to either "__class__" or "super". This allows the zero ' - 'argument form\n' - 'of "super()" to correctly identify the class being defined ' - 'based on\n' - 'lexical scoping, while the class or instance that was used ' - 'to make the\n' - 'current call is identified based on the first argument ' - 'passed to the\n' - 'method.\n' - '\n' - 'After the class object is created, it is passed to the ' - 'class\n' - 'decorators included in the class definition (if any) and ' - 'the resulting\n' - 'object is bound in the local namespace as the defined ' - 'class.\n' - '\n' - 'See also: **PEP 3135** - New super\n' - '\n' - ' Describes the implicit "__class__" closure reference\n' - '\n' - '\n' - 'Metaclass example\n' - '-----------------\n' - '\n' - 'The potential uses for metaclasses are boundless. Some ' - 'ideas that have\n' - 'been explored include logging, interface checking, ' - 'automatic\n' - 'delegation, automatic property creation, proxies, ' - 'frameworks, and\n' - 'automatic resource locking/synchronization.\n' - '\n' - 'Here is an example of a metaclass that uses an\n' - '"collections.OrderedDict" to remember the order that class ' - 'variables\n' - 'are defined:\n' - '\n' - ' class OrderedClass(type):\n' - '\n' - ' @classmethod\n' - ' def __prepare__(metacls, name, bases, **kwds):\n' - ' return collections.OrderedDict()\n' - '\n' - ' def __new__(cls, name, bases, namespace, **kwds):\n' - ' result = type.__new__(cls, name, bases, ' - 'dict(namespace))\n' - ' result.members = tuple(namespace)\n' - ' return result\n' - '\n' - ' class A(metaclass=OrderedClass):\n' - ' def one(self): pass\n' - ' def two(self): pass\n' - ' def three(self): pass\n' - ' def four(self): pass\n' - '\n' - ' >>> A.members\n' - " ('__module__', 'one', 'two', 'three', 'four')\n" - '\n' - 'When the class definition for *A* gets executed, the ' - 'process begins\n' - 'with calling the metaclass\'s "__prepare__()" method which ' - 'returns an\n' - 'empty "collections.OrderedDict". That mapping records the ' - 'methods and\n' - 'attributes of *A* as they are defined within the body of ' - 'the class\n' - 'statement. Once those definitions are executed, the ' - 'ordered dictionary\n' - 'is fully populated and the metaclass\'s "__new__()" method ' - 'gets\n' - 'invoked. That method builds the new type and it saves the ' - 'ordered\n' - 'dictionary keys in an attribute called "members".\n' - '\n' - '\n' - 'Customizing instance and subclass checks\n' - '========================================\n' - '\n' - 'The following methods are used to override the default ' - 'behavior of the\n' - '"isinstance()" and "issubclass()" built-in functions.\n' - '\n' - 'In particular, the metaclass "abc.ABCMeta" implements ' - 'these methods in\n' - 'order to allow the addition of Abstract Base Classes ' - '(ABCs) as\n' - '"virtual base classes" to any class or type (including ' - 'built-in\n' - 'types), including other ABCs.\n' - '\n' - 'class.__instancecheck__(self, instance)\n' - '\n' - ' Return true if *instance* should be considered a ' - '(direct or\n' - ' indirect) instance of *class*. If defined, called to ' - 'implement\n' - ' "isinstance(instance, class)".\n' - '\n' - 'class.__subclasscheck__(self, subclass)\n' - '\n' - ' Return true if *subclass* should be considered a ' - '(direct or\n' - ' indirect) subclass of *class*. If defined, called to ' - 'implement\n' - ' "issubclass(subclass, class)".\n' - '\n' - 'Note that these methods are looked up on the type ' - '(metaclass) of a\n' - 'class. They cannot be defined as class methods in the ' - 'actual class.\n' - 'This is consistent with the lookup of special methods that ' - 'are called\n' - 'on instances, only in this case the instance is itself a ' - 'class.\n' - '\n' - 'See also: **PEP 3119** - Introducing Abstract Base ' - 'Classes\n' - '\n' - ' Includes the specification for customizing ' - '"isinstance()" and\n' - ' "issubclass()" behavior through "__instancecheck__()" ' - 'and\n' - ' "__subclasscheck__()", with motivation for this ' - 'functionality in\n' - ' the context of adding Abstract Base Classes (see the ' - '"abc"\n' - ' module) to the language.\n' - '\n' - '\n' - 'Emulating callable objects\n' - '==========================\n' - '\n' - 'object.__call__(self[, args...])\n' - '\n' - ' Called when the instance is "called" as a function; if ' - 'this method\n' - ' is defined, "x(arg1, arg2, ...)" is a shorthand for\n' - ' "x.__call__(arg1, arg2, ...)".\n' - '\n' - '\n' - 'Emulating container types\n' - '=========================\n' - '\n' - 'The following methods can be defined to implement ' - 'container objects.\n' - 'Containers usually are sequences (such as lists or tuples) ' - 'or mappings\n' - '(like dictionaries), but can represent other containers as ' - 'well. The\n' - 'first set of methods is used either to emulate a sequence ' - 'or to\n' - 'emulate a mapping; the difference is that for a sequence, ' - 'the\n' - 'allowable keys should be the integers *k* for which "0 <= ' - 'k < N" where\n' - '*N* is the length of the sequence, or slice objects, which ' - 'define a\n' - 'range of items. It is also recommended that mappings ' - 'provide the\n' - 'methods "keys()", "values()", "items()", "get()", ' - '"clear()",\n' - '"setdefault()", "pop()", "popitem()", "copy()", and ' - '"update()"\n' - "behaving similar to those for Python's standard dictionary " - 'objects.\n' - 'The "collections" module provides a "MutableMapping" ' - 'abstract base\n' - 'class to help create those methods from a base set of ' - '"__getitem__()",\n' - '"__setitem__()", "__delitem__()", and "keys()". Mutable ' - 'sequences\n' - 'should provide methods "append()", "count()", "index()", ' - '"extend()",\n' - '"insert()", "pop()", "remove()", "reverse()" and "sort()", ' - 'like Python\n' - 'standard list objects. Finally, sequence types should ' - 'implement\n' - 'addition (meaning concatenation) and multiplication ' - '(meaning\n' - 'repetition) by defining the methods "__add__()", ' - '"__radd__()",\n' - '"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" ' - 'described\n' - 'below; they should not define other numerical operators. ' - 'It is\n' - 'recommended that both mappings and sequences implement ' - 'the\n' - '"__contains__()" method to allow efficient use of the "in" ' - 'operator;\n' - 'for mappings, "in" should search the mapping\'s keys; for ' - 'sequences, it\n' - 'should search through the values. It is further ' - 'recommended that both\n' - 'mappings and sequences implement the "__iter__()" method ' - 'to allow\n' - 'efficient iteration through the container; for mappings, ' - '"__iter__()"\n' - 'should be the same as "keys()"; for sequences, it should ' - 'iterate\n' - 'through the values.\n' - '\n' - 'object.__len__(self)\n' - '\n' - ' Called to implement the built-in function "len()". ' - 'Should return\n' - ' the length of the object, an integer ">=" 0. Also, an ' - 'object that\n' - ' doesn\'t define a "__bool__()" method and whose ' - '"__len__()" method\n' - ' returns zero is considered to be false in a Boolean ' - 'context.\n' - '\n' - 'object.__length_hint__(self)\n' - '\n' - ' Called to implement "operator.length_hint()". Should ' - 'return an\n' - ' estimated length for the object (which may be greater ' - 'or less than\n' - ' the actual length). The length must be an integer ">=" ' - '0. This\n' - ' method is purely an optimization and is never required ' - 'for\n' - ' correctness.\n' - '\n' - ' New in version 3.4.\n' - '\n' - 'Note: Slicing is done exclusively with the following three ' - 'methods.\n' - ' A call like\n' - '\n' - ' a[1:2] = b\n' - '\n' - ' is translated to\n' - '\n' - ' a[slice(1, 2, None)] = b\n' - '\n' - ' and so forth. Missing slice items are always filled in ' - 'with "None".\n' - '\n' - 'object.__getitem__(self, key)\n' - '\n' - ' Called to implement evaluation of "self[key]". For ' - 'sequence types,\n' - ' the accepted keys should be integers and slice ' - 'objects. Note that\n' - ' the special interpretation of negative indexes (if the ' - 'class wishes\n' - ' to emulate a sequence type) is up to the ' - '"__getitem__()" method. If\n' - ' *key* is of an inappropriate type, "TypeError" may be ' - 'raised; if of\n' - ' a value outside the set of indexes for the sequence ' - '(after any\n' - ' special interpretation of negative values), ' - '"IndexError" should be\n' - ' raised. For mapping types, if *key* is missing (not in ' - 'the\n' - ' container), "KeyError" should be raised.\n' - '\n' - ' Note: "for" loops expect that an "IndexError" will be ' - 'raised for\n' - ' illegal indexes to allow proper detection of the end ' - 'of the\n' - ' sequence.\n' - '\n' - 'object.__missing__(self, key)\n' - '\n' - ' Called by "dict"."__getitem__()" to implement ' - '"self[key]" for dict\n' - ' subclasses when key is not in the dictionary.\n' - '\n' - 'object.__setitem__(self, key, value)\n' - '\n' - ' Called to implement assignment to "self[key]". Same ' - 'note as for\n' - ' "__getitem__()". This should only be implemented for ' - 'mappings if\n' - ' the objects support changes to the values for keys, or ' - 'if new keys\n' - ' can be added, or for sequences if elements can be ' - 'replaced. The\n' - ' same exceptions should be raised for improper *key* ' - 'values as for\n' - ' the "__getitem__()" method.\n' - '\n' - 'object.__delitem__(self, key)\n' - '\n' - ' Called to implement deletion of "self[key]". Same note ' - 'as for\n' - ' "__getitem__()". This should only be implemented for ' - 'mappings if\n' - ' the objects support removal of keys, or for sequences ' - 'if elements\n' - ' can be removed from the sequence. The same exceptions ' - 'should be\n' - ' raised for improper *key* values as for the ' - '"__getitem__()" method.\n' - '\n' - 'object.__iter__(self)\n' - '\n' - ' This method is called when an iterator is required for ' - 'a container.\n' - ' This method should return a new iterator object that ' - 'can iterate\n' - ' over all the objects in the container. For mappings, ' - 'it should\n' - ' iterate over the keys of the container.\n' - '\n' - ' Iterator objects also need to implement this method; ' - 'they are\n' - ' required to return themselves. For more information on ' - 'iterator\n' - ' objects, see *Iterator Types*.\n' - '\n' - 'object.__reversed__(self)\n' - '\n' - ' Called (if present) by the "reversed()" built-in to ' - 'implement\n' - ' reverse iteration. It should return a new iterator ' - 'object that\n' - ' iterates over all the objects in the container in ' - 'reverse order.\n' - '\n' - ' If the "__reversed__()" method is not provided, the ' - '"reversed()"\n' - ' built-in will fall back to using the sequence protocol ' - '("__len__()"\n' - ' and "__getitem__()"). Objects that support the ' - 'sequence protocol\n' - ' should only provide "__reversed__()" if they can ' - 'provide an\n' - ' implementation that is more efficient than the one ' - 'provided by\n' - ' "reversed()".\n' - '\n' - 'The membership test operators ("in" and "not in") are ' - 'normally\n' - 'implemented as an iteration through a sequence. However, ' - 'container\n' - 'objects can supply the following special method with a ' - 'more efficient\n' - 'implementation, which also does not require the object be ' - 'a sequence.\n' - '\n' - 'object.__contains__(self, item)\n' - '\n' - ' Called to implement membership test operators. Should ' - 'return true\n' - ' if *item* is in *self*, false otherwise. For mapping ' - 'objects, this\n' - ' should consider the keys of the mapping rather than the ' - 'values or\n' - ' the key-item pairs.\n' - '\n' - ' For objects that don\'t define "__contains__()", the ' - 'membership test\n' - ' first tries iteration via "__iter__()", then the old ' - 'sequence\n' - ' iteration protocol via "__getitem__()", see *this ' - 'section in the\n' - ' language reference*.\n' - '\n' - '\n' - 'Emulating numeric types\n' - '=======================\n' - '\n' - 'The following methods can be defined to emulate numeric ' - 'objects.\n' - 'Methods corresponding to operations that are not supported ' - 'by the\n' - 'particular kind of number implemented (e.g., bitwise ' - 'operations for\n' - 'non-integral numbers) should be left undefined.\n' - '\n' - 'object.__add__(self, other)\n' - 'object.__sub__(self, other)\n' - 'object.__mul__(self, other)\n' - 'object.__matmul__(self, other)\n' - 'object.__truediv__(self, other)\n' - 'object.__floordiv__(self, other)\n' - 'object.__mod__(self, other)\n' - 'object.__divmod__(self, other)\n' - 'object.__pow__(self, other[, modulo])\n' - 'object.__lshift__(self, other)\n' - 'object.__rshift__(self, other)\n' - 'object.__and__(self, other)\n' - 'object.__xor__(self, other)\n' - 'object.__or__(self, other)\n' - '\n' - ' These methods are called to implement the binary ' - 'arithmetic\n' - ' operations ("+", "-", "*", "@", "/", "//", "%", ' - '"divmod()",\n' - ' "pow()", "**", "<<", ">>", "&", "^", "|"). For ' - 'instance, to\n' - ' evaluate the expression "x + y", where *x* is an ' - 'instance of a\n' - ' class that has an "__add__()" method, "x.__add__(y)" is ' - 'called.\n' - ' The "__divmod__()" method should be the equivalent to ' - 'using\n' - ' "__floordiv__()" and "__mod__()"; it should not be ' - 'related to\n' - ' "__truediv__()". Note that "__pow__()" should be ' - 'defined to accept\n' - ' an optional third argument if the ternary version of ' - 'the built-in\n' - ' "pow()" function is to be supported.\n' - '\n' - ' If one of those methods does not support the operation ' - 'with the\n' - ' supplied arguments, it should return "NotImplemented".\n' - '\n' - 'object.__radd__(self, other)\n' - 'object.__rsub__(self, other)\n' - 'object.__rmul__(self, other)\n' - 'object.__rmatmul__(self, other)\n' - 'object.__rtruediv__(self, other)\n' - 'object.__rfloordiv__(self, other)\n' - 'object.__rmod__(self, other)\n' - 'object.__rdivmod__(self, other)\n' - 'object.__rpow__(self, other)\n' - 'object.__rlshift__(self, other)\n' - 'object.__rrshift__(self, other)\n' - 'object.__rand__(self, other)\n' - 'object.__rxor__(self, other)\n' - 'object.__ror__(self, other)\n' - '\n' - ' These methods are called to implement the binary ' - 'arithmetic\n' - ' operations ("+", "-", "*", "@", "/", "//", "%", ' - '"divmod()",\n' - ' "pow()", "**", "<<", ">>", "&", "^", "|") with ' - 'reflected (swapped)\n' - ' operands. These functions are only called if the left ' - 'operand does\n' - ' not support the corresponding operation and the ' - 'operands are of\n' - ' different types. [2] For instance, to evaluate the ' - 'expression "x -\n' - ' y", where *y* is an instance of a class that has an ' - '"__rsub__()"\n' - ' method, "y.__rsub__(x)" is called if "x.__sub__(y)" ' - 'returns\n' - ' *NotImplemented*.\n' - '\n' - ' Note that ternary "pow()" will not try calling ' - '"__rpow__()" (the\n' - ' coercion rules would become too complicated).\n' - '\n' - " Note: If the right operand's type is a subclass of the " - 'left\n' - " operand's type and that subclass provides the " - 'reflected method\n' - ' for the operation, this method will be called before ' - 'the left\n' - " operand's non-reflected method. This behavior allows " - 'subclasses\n' - " to override their ancestors' operations.\n" - '\n' - 'object.__iadd__(self, other)\n' - 'object.__isub__(self, other)\n' - 'object.__imul__(self, other)\n' - 'object.__imatmul__(self, other)\n' - 'object.__itruediv__(self, other)\n' - 'object.__ifloordiv__(self, other)\n' - 'object.__imod__(self, other)\n' - 'object.__ipow__(self, other[, modulo])\n' - 'object.__ilshift__(self, other)\n' - 'object.__irshift__(self, other)\n' - 'object.__iand__(self, other)\n' - 'object.__ixor__(self, other)\n' - 'object.__ior__(self, other)\n' - '\n' - ' These methods are called to implement the augmented ' - 'arithmetic\n' - ' assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", ' - '"**=",\n' - ' "<<=", ">>=", "&=", "^=", "|="). These methods should ' - 'attempt to\n' - ' do the operation in-place (modifying *self*) and return ' - 'the result\n' - ' (which could be, but does not have to be, *self*). If ' - 'a specific\n' - ' method is not defined, the augmented assignment falls ' - 'back to the\n' - ' normal methods. For instance, if *x* is an instance of ' - 'a class\n' - ' with an "__iadd__()" method, "x += y" is equivalent to ' - '"x =\n' - ' x.__iadd__(y)" . Otherwise, "x.__add__(y)" and ' - '"y.__radd__(x)" are\n' - ' considered, as with the evaluation of "x + y". In ' - 'certain\n' - ' situations, augmented assignment can result in ' - 'unexpected errors\n' - " (see *Why does a_tuple[i] += ['item'] raise an " - 'exception when the\n' - ' addition works?*), but this behavior is in fact part of ' - 'the data\n' - ' model.\n' - '\n' - 'object.__neg__(self)\n' - 'object.__pos__(self)\n' - 'object.__abs__(self)\n' - 'object.__invert__(self)\n' - '\n' - ' Called to implement the unary arithmetic operations ' - '("-", "+",\n' - ' "abs()" and "~").\n' - '\n' - 'object.__complex__(self)\n' - 'object.__int__(self)\n' - 'object.__float__(self)\n' - 'object.__round__(self[, n])\n' - '\n' - ' Called to implement the built-in functions "complex()", ' - '"int()",\n' - ' "float()" and "round()". Should return a value of the ' - 'appropriate\n' - ' type.\n' - '\n' - 'object.__index__(self)\n' - '\n' - ' Called to implement "operator.index()", and whenever ' - 'Python needs\n' - ' to losslessly convert the numeric object to an integer ' - 'object (such\n' - ' as in slicing, or in the built-in "bin()", "hex()" and ' - '"oct()"\n' - ' functions). Presence of this method indicates that the ' - 'numeric\n' - ' object is an integer type. Must return an integer.\n' - '\n' - ' Note: In order to have a coherent integer type class, ' - 'when\n' - ' "__index__()" is defined "__int__()" should also be ' - 'defined, and\n' - ' both should return the same value.\n' - '\n' - '\n' - 'With Statement Context Managers\n' - '===============================\n' - '\n' - 'A *context manager* is an object that defines the runtime ' - 'context to\n' - 'be established when executing a "with" statement. The ' - 'context manager\n' - 'handles the entry into, and the exit from, the desired ' - 'runtime context\n' - 'for the execution of the block of code. Context managers ' - 'are normally\n' - 'invoked using the "with" statement (described in section ' - '*The with\n' - 'statement*), but can also be used by directly invoking ' - 'their methods.\n' - '\n' - 'Typical uses of context managers include saving and ' - 'restoring various\n' - 'kinds of global state, locking and unlocking resources, ' - 'closing opened\n' - 'files, etc.\n' - '\n' - 'For more information on context managers, see *Context ' - 'Manager Types*.\n' - '\n' - 'object.__enter__(self)\n' - '\n' - ' Enter the runtime context related to this object. The ' - '"with"\n' - " statement will bind this method's return value to the " - 'target(s)\n' - ' specified in the "as" clause of the statement, if any.\n' - '\n' - 'object.__exit__(self, exc_type, exc_value, traceback)\n' - '\n' - ' Exit the runtime context related to this object. The ' - 'parameters\n' - ' describe the exception that caused the context to be ' - 'exited. If the\n' - ' context was exited without an exception, all three ' - 'arguments will\n' - ' be "None".\n' - '\n' - ' If an exception is supplied, and the method wishes to ' - 'suppress the\n' - ' exception (i.e., prevent it from being propagated), it ' - 'should\n' - ' return a true value. Otherwise, the exception will be ' - 'processed\n' - ' normally upon exit from this method.\n' - '\n' - ' Note that "__exit__()" methods should not reraise the ' - 'passed-in\n' - " exception; this is the caller's responsibility.\n" - '\n' - 'See also: **PEP 0343** - The "with" statement\n' - '\n' - ' The specification, background, and examples for the ' - 'Python "with"\n' - ' statement.\n' - '\n' - '\n' - 'Special method lookup\n' - '=====================\n' - '\n' - 'For custom classes, implicit invocations of special ' - 'methods are only\n' - "guaranteed to work correctly if defined on an object's " - 'type, not in\n' - "the object's instance dictionary. That behaviour is the " - 'reason why\n' - 'the following code raises an exception:\n' - '\n' - ' >>> class C:\n' - ' ... pass\n' - ' ...\n' - ' >>> c = C()\n' - ' >>> c.__len__ = lambda: 5\n' - ' >>> len(c)\n' - ' Traceback (most recent call last):\n' - ' File "", line 1, in \n' - " TypeError: object of type 'C' has no len()\n" - '\n' - 'The rationale behind this behaviour lies with a number of ' - 'special\n' - 'methods such as "__hash__()" and "__repr__()" that are ' - 'implemented by\n' - 'all objects, including type objects. If the implicit ' - 'lookup of these\n' - 'methods used the conventional lookup process, they would ' - 'fail when\n' - 'invoked on the type object itself:\n' - '\n' - ' >>> 1 .__hash__() == hash(1)\n' - ' True\n' - ' >>> int.__hash__() == hash(int)\n' - ' Traceback (most recent call last):\n' - ' File "", line 1, in \n' - " TypeError: descriptor '__hash__' of 'int' object needs " - 'an argument\n' - '\n' - 'Incorrectly attempting to invoke an unbound method of a ' - 'class in this\n' - "way is sometimes referred to as 'metaclass confusion', and " - 'is avoided\n' - 'by bypassing the instance when looking up special ' - 'methods:\n' - '\n' - ' >>> type(1).__hash__(1) == hash(1)\n' - ' True\n' - ' >>> type(int).__hash__(int) == hash(int)\n' - ' True\n' - '\n' - 'In addition to bypassing any instance attributes in the ' - 'interest of\n' - 'correctness, implicit special method lookup generally also ' - 'bypasses\n' - 'the "__getattribute__()" method even of the object\'s ' - 'metaclass:\n' - '\n' - ' >>> class Meta(type):\n' - ' ... def __getattribute__(*args):\n' - ' ... print("Metaclass getattribute invoked")\n' - ' ... return type.__getattribute__(*args)\n' - ' ...\n' - ' >>> class C(object, metaclass=Meta):\n' - ' ... def __len__(self):\n' - ' ... return 10\n' - ' ... def __getattribute__(*args):\n' - ' ... print("Class getattribute invoked")\n' - ' ... return object.__getattribute__(*args)\n' - ' ...\n' - ' >>> c = C()\n' - ' >>> c.__len__() # Explicit lookup via ' - 'instance\n' - ' Class getattribute invoked\n' - ' 10\n' - ' >>> type(c).__len__(c) # Explicit lookup via ' - 'type\n' - ' Metaclass getattribute invoked\n' - ' 10\n' - ' >>> len(c) # Implicit lookup\n' - ' 10\n' - '\n' - 'Bypassing the "__getattribute__()" machinery in this ' - 'fashion provides\n' - 'significant scope for speed optimisations within the ' - 'interpreter, at\n' - 'the cost of some flexibility in the handling of special ' - 'methods (the\n' - 'special method *must* be set on the class object itself in ' - 'order to be\n' - 'consistently invoked by the interpreter).\n', - 'string-methods': '\n' - 'String Methods\n' - '**************\n' - '\n' - 'Strings implement all of the *common* sequence ' - 'operations, along with\n' - 'the additional methods described below.\n' - '\n' - 'Strings also support two styles of string formatting, ' - 'one providing a\n' - 'large degree of flexibility and customization (see ' - '"str.format()",\n' - '*Format String Syntax* and *String Formatting*) and the ' - 'other based on\n' - 'C "printf" style formatting that handles a narrower ' - 'range of types and\n' - 'is slightly harder to use correctly, but is often faster ' - 'for the cases\n' - 'it can handle (*printf-style String Formatting*).\n' - '\n' - 'The *Text Processing Services* section of the standard ' - 'library covers\n' - 'a number of other modules that provide various text ' - 'related utilities\n' - '(including regular expression support in the "re" ' - 'module).\n' - '\n' - 'str.capitalize()\n' - '\n' - ' Return a copy of the string with its first character ' - 'capitalized\n' - ' and the rest lowercased.\n' - '\n' - 'str.casefold()\n' - '\n' - ' Return a casefolded copy of the string. Casefolded ' - 'strings may be\n' - ' used for caseless matching.\n' - '\n' - ' Casefolding is similar to lowercasing but more ' - 'aggressive because\n' - ' it is intended to remove all case distinctions in a ' - 'string. For\n' - ' example, the German lowercase letter "\'?\'" is ' - 'equivalent to ""ss"".\n' - ' Since it is already lowercase, "lower()" would do ' - 'nothing to "\'?\'";\n' - ' "casefold()" converts it to ""ss"".\n' - '\n' - ' The casefolding algorithm is described in section ' - '3.13 of the\n' - ' Unicode Standard.\n' - '\n' - ' New in version 3.3.\n' - '\n' - 'str.center(width[, fillchar])\n' - '\n' - ' Return centered in a string of length *width*. ' - 'Padding is done\n' - ' using the specified *fillchar* (default is an ASCII ' - 'space). The\n' - ' original string is returned if *width* is less than ' - 'or equal to\n' - ' "len(s)".\n' - '\n' - 'str.count(sub[, start[, end]])\n' - '\n' - ' Return the number of non-overlapping occurrences of ' - 'substring *sub*\n' - ' in the range [*start*, *end*]. Optional arguments ' - '*start* and\n' - ' *end* are interpreted as in slice notation.\n' - '\n' - 'str.encode(encoding="utf-8", errors="strict")\n' - '\n' - ' Return an encoded version of the string as a bytes ' - 'object. Default\n' - ' encoding is "\'utf-8\'". *errors* may be given to set ' - 'a different\n' - ' error handling scheme. The default for *errors* is ' - '"\'strict\'",\n' - ' meaning that encoding errors raise a "UnicodeError". ' - 'Other possible\n' - ' values are "\'ignore\'", "\'replace\'", ' - '"\'xmlcharrefreplace\'",\n' - ' "\'backslashreplace\'" and any other name registered ' - 'via\n' - ' "codecs.register_error()", see section *Error ' - 'Handlers*. For a list\n' - ' of possible encodings, see section *Standard ' - 'Encodings*.\n' - '\n' - ' Changed in version 3.1: Support for keyword arguments ' - 'added.\n' - '\n' - 'str.endswith(suffix[, start[, end]])\n' - '\n' - ' Return "True" if the string ends with the specified ' - '*suffix*,\n' - ' otherwise return "False". *suffix* can also be a ' - 'tuple of suffixes\n' - ' to look for. With optional *start*, test beginning ' - 'at that\n' - ' position. With optional *end*, stop comparing at ' - 'that position.\n' - '\n' - 'str.expandtabs(tabsize=8)\n' - '\n' - ' Return a copy of the string where all tab characters ' - 'are replaced\n' - ' by one or more spaces, depending on the current ' - 'column and the\n' - ' given tab size. Tab positions occur every *tabsize* ' - 'characters\n' - ' (default is 8, giving tab positions at columns 0, 8, ' - '16 and so on).\n' - ' To expand the string, the current column is set to ' - 'zero and the\n' - ' string is examined character by character. If the ' - 'character is a\n' - ' tab ("\\t"), one or more space characters are ' - 'inserted in the result\n' - ' until the current column is equal to the next tab ' - 'position. (The\n' - ' tab character itself is not copied.) If the ' - 'character is a newline\n' - ' ("\\n") or return ("\\r"), it is copied and the ' - 'current column is\n' - ' reset to zero. Any other character is copied ' - 'unchanged and the\n' - ' current column is incremented by one regardless of ' - 'how the\n' - ' character is represented when printed.\n' - '\n' - " >>> '01\\t012\\t0123\\t01234'.expandtabs()\n" - " '01 012 0123 01234'\n" - " >>> '01\\t012\\t0123\\t01234'.expandtabs(4)\n" - " '01 012 0123 01234'\n" - '\n' - 'str.find(sub[, start[, end]])\n' - '\n' - ' Return the lowest index in the string where substring ' - '*sub* is\n' - ' found, such that *sub* is contained in the slice ' - '"s[start:end]".\n' - ' Optional arguments *start* and *end* are interpreted ' - 'as in slice\n' - ' notation. Return "-1" if *sub* is not found.\n' - '\n' - ' Note: The "find()" method should be used only if you ' - 'need to know\n' - ' the position of *sub*. To check if *sub* is a ' - 'substring or not,\n' - ' use the "in" operator:\n' - '\n' - " >>> 'Py' in 'Python'\n" - ' True\n' - '\n' - 'str.format(*args, **kwargs)\n' - '\n' - ' Perform a string formatting operation. The string on ' - 'which this\n' - ' method is called can contain literal text or ' - 'replacement fields\n' - ' delimited by braces "{}". Each replacement field ' - 'contains either\n' - ' the numeric index of a positional argument, or the ' - 'name of a\n' - ' keyword argument. Returns a copy of the string where ' - 'each\n' - ' replacement field is replaced with the string value ' - 'of the\n' - ' corresponding argument.\n' - '\n' - ' >>> "The sum of 1 + 2 is {0}".format(1+2)\n' - " 'The sum of 1 + 2 is 3'\n" - '\n' - ' See *Format String Syntax* for a description of the ' - 'various\n' - ' formatting options that can be specified in format ' - 'strings.\n' - '\n' - 'str.format_map(mapping)\n' - '\n' - ' Similar to "str.format(**mapping)", except that ' - '"mapping" is used\n' - ' directly and not copied to a "dict". This is useful ' - 'if for example\n' - ' "mapping" is a dict subclass:\n' - '\n' - ' >>> class Default(dict):\n' - ' ... def __missing__(self, key):\n' - ' ... return key\n' - ' ...\n' - " >>> '{name} was born in " - "{country}'.format_map(Default(name='Guido'))\n" - " 'Guido was born in country'\n" - '\n' - ' New in version 3.2.\n' - '\n' - 'str.index(sub[, start[, end]])\n' - '\n' - ' Like "find()", but raise "ValueError" when the ' - 'substring is not\n' - ' found.\n' - '\n' - 'str.isalnum()\n' - '\n' - ' Return true if all characters in the string are ' - 'alphanumeric and\n' - ' there is at least one character, false otherwise. A ' - 'character "c"\n' - ' is alphanumeric if one of the following returns ' - '"True":\n' - ' "c.isalpha()", "c.isdecimal()", "c.isdigit()", or ' - '"c.isnumeric()".\n' - '\n' - 'str.isalpha()\n' - '\n' - ' Return true if all characters in the string are ' - 'alphabetic and\n' - ' there is at least one character, false otherwise. ' - 'Alphabetic\n' - ' characters are those characters defined in the ' - 'Unicode character\n' - ' database as "Letter", i.e., those with general ' - 'category property\n' - ' being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note ' - 'that this is\n' - ' different from the "Alphabetic" property defined in ' - 'the Unicode\n' - ' Standard.\n' - '\n' - 'str.isdecimal()\n' - '\n' - ' Return true if all characters in the string are ' - 'decimal characters\n' - ' and there is at least one character, false otherwise. ' - 'Decimal\n' - ' characters are those from general category "Nd". This ' - 'category\n' - ' includes digit characters, and all characters that ' - 'can be used to\n' - ' form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC ' - 'DIGIT ZERO.\n' - '\n' - 'str.isdigit()\n' - '\n' - ' Return true if all characters in the string are ' - 'digits and there is\n' - ' at least one character, false otherwise. Digits ' - 'include decimal\n' - ' characters and digits that need special handling, ' - 'such as the\n' - ' compatibility superscript digits. Formally, a digit ' - 'is a character\n' - ' that has the property value Numeric_Type=Digit or\n' - ' Numeric_Type=Decimal.\n' - '\n' - 'str.isidentifier()\n' - '\n' - ' Return true if the string is a valid identifier ' - 'according to the\n' - ' language definition, section *Identifiers and ' - 'keywords*.\n' - '\n' - ' Use "keyword.iskeyword()" to test for reserved ' - 'identifiers such as\n' - ' "def" and "class".\n' - '\n' - 'str.islower()\n' - '\n' - ' Return true if all cased characters [4] in the string ' - 'are lowercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' - '\n' - 'str.isnumeric()\n' - '\n' - ' Return true if all characters in the string are ' - 'numeric characters,\n' - ' and there is at least one character, false otherwise. ' - 'Numeric\n' - ' characters include digit characters, and all ' - 'characters that have\n' - ' the Unicode numeric value property, e.g. U+2155, ' - 'VULGAR FRACTION\n' - ' ONE FIFTH. Formally, numeric characters are those ' - 'with the\n' - ' property value Numeric_Type=Digit, ' - 'Numeric_Type=Decimal or\n' - ' Numeric_Type=Numeric.\n' - '\n' - 'str.isprintable()\n' - '\n' - ' Return true if all characters in the string are ' - 'printable or the\n' - ' string is empty, false otherwise. Nonprintable ' - 'characters are\n' - ' those characters defined in the Unicode character ' - 'database as\n' - ' "Other" or "Separator", excepting the ASCII space ' - '(0x20) which is\n' - ' considered printable. (Note that printable ' - 'characters in this\n' - ' context are those which should not be escaped when ' - '"repr()" is\n' - ' invoked on a string. It has no bearing on the ' - 'handling of strings\n' - ' written to "sys.stdout" or "sys.stderr".)\n' - '\n' - 'str.isspace()\n' - '\n' - ' Return true if there are only whitespace characters ' - 'in the string\n' - ' and there is at least one character, false ' - 'otherwise. Whitespace\n' - ' characters are those characters defined in the ' - 'Unicode character\n' - ' database as "Other" or "Separator" and those with ' - 'bidirectional\n' - ' property being one of "WS", "B", or "S".\n' - '\n' - 'str.istitle()\n' - '\n' - ' Return true if the string is a titlecased string and ' - 'there is at\n' - ' least one character, for example uppercase characters ' - 'may only\n' - ' follow uncased characters and lowercase characters ' - 'only cased ones.\n' - ' Return false otherwise.\n' - '\n' - 'str.isupper()\n' - '\n' - ' Return true if all cased characters [4] in the string ' - 'are uppercase\n' - ' and there is at least one cased character, false ' - 'otherwise.\n' - '\n' - 'str.join(iterable)\n' - '\n' - ' Return a string which is the concatenation of the ' - 'strings in the\n' - ' *iterable* *iterable*. A "TypeError" will be raised ' - 'if there are\n' - ' any non-string values in *iterable*, including ' - '"bytes" objects.\n' - ' The separator between elements is the string ' - 'providing this method.\n' - '\n' - 'str.ljust(width[, fillchar])\n' - '\n' - ' Return the string left justified in a string of ' - 'length *width*.\n' - ' Padding is done using the specified *fillchar* ' - '(default is an ASCII\n' - ' space). The original string is returned if *width* is ' - 'less than or\n' - ' equal to "len(s)".\n' - '\n' - 'str.lower()\n' - '\n' - ' Return a copy of the string with all the cased ' - 'characters [4]\n' - ' converted to lowercase.\n' - '\n' - ' The lowercasing algorithm used is described in ' - 'section 3.13 of the\n' - ' Unicode Standard.\n' - '\n' - 'str.lstrip([chars])\n' - '\n' - ' Return a copy of the string with leading characters ' - 'removed. The\n' - ' *chars* argument is a string specifying the set of ' - 'characters to be\n' - ' removed. If omitted or "None", the *chars* argument ' - 'defaults to\n' - ' removing whitespace. The *chars* argument is not a ' - 'prefix; rather,\n' - ' all combinations of its values are stripped:\n' - '\n' - " >>> ' spacious '.lstrip()\n" - " 'spacious '\n" - " >>> 'www.example.com'.lstrip('cmowz.')\n" - " 'example.com'\n" - '\n' - 'static str.maketrans(x[, y[, z]])\n' - '\n' - ' This static method returns a translation table usable ' - 'for\n' - ' "str.translate()".\n' - '\n' - ' If there is only one argument, it must be a ' - 'dictionary mapping\n' - ' Unicode ordinals (integers) or characters (strings of ' - 'length 1) to\n' - ' Unicode ordinals, strings (of arbitrary lengths) or ' - 'None.\n' - ' Character keys will then be converted to ordinals.\n' - '\n' - ' If there are two arguments, they must be strings of ' - 'equal length,\n' - ' and in the resulting dictionary, each character in x ' - 'will be mapped\n' - ' to the character at the same position in y. If there ' - 'is a third\n' - ' argument, it must be a string, whose characters will ' - 'be mapped to\n' - ' None in the result.\n' - '\n' - 'str.partition(sep)\n' - '\n' - ' Split the string at the first occurrence of *sep*, ' - 'and return a\n' - ' 3-tuple containing the part before the separator, the ' - 'separator\n' - ' itself, and the part after the separator. If the ' - 'separator is not\n' - ' found, return a 3-tuple containing the string itself, ' - 'followed by\n' - ' two empty strings.\n' - '\n' - 'str.replace(old, new[, count])\n' - '\n' - ' Return a copy of the string with all occurrences of ' - 'substring *old*\n' - ' replaced by *new*. If the optional argument *count* ' - 'is given, only\n' - ' the first *count* occurrences are replaced.\n' - '\n' - 'str.rfind(sub[, start[, end]])\n' - '\n' - ' Return the highest index in the string where ' - 'substring *sub* is\n' - ' found, such that *sub* is contained within ' - '"s[start:end]".\n' - ' Optional arguments *start* and *end* are interpreted ' - 'as in slice\n' - ' notation. Return "-1" on failure.\n' - '\n' - 'str.rindex(sub[, start[, end]])\n' - '\n' - ' Like "rfind()" but raises "ValueError" when the ' - 'substring *sub* is\n' - ' not found.\n' - '\n' - 'str.rjust(width[, fillchar])\n' - '\n' - ' Return the string right justified in a string of ' - 'length *width*.\n' - ' Padding is done using the specified *fillchar* ' - '(default is an ASCII\n' - ' space). The original string is returned if *width* is ' - 'less than or\n' - ' equal to "len(s)".\n' - '\n' - 'str.rpartition(sep)\n' - '\n' - ' Split the string at the last occurrence of *sep*, and ' - 'return a\n' - ' 3-tuple containing the part before the separator, the ' - 'separator\n' - ' itself, and the part after the separator. If the ' - 'separator is not\n' - ' found, return a 3-tuple containing two empty strings, ' - 'followed by\n' - ' the string itself.\n' - '\n' - 'str.rsplit(sep=None, maxsplit=-1)\n' - '\n' - ' Return a list of the words in the string, using *sep* ' - 'as the\n' - ' delimiter string. If *maxsplit* is given, at most ' - '*maxsplit* splits\n' - ' are done, the *rightmost* ones. If *sep* is not ' - 'specified or\n' - ' "None", any whitespace string is a separator. Except ' - 'for splitting\n' - ' from the right, "rsplit()" behaves like "split()" ' - 'which is\n' - ' described in detail below.\n' - '\n' - 'str.rstrip([chars])\n' - '\n' - ' Return a copy of the string with trailing characters ' - 'removed. The\n' - ' *chars* argument is a string specifying the set of ' - 'characters to be\n' - ' removed. If omitted or "None", the *chars* argument ' - 'defaults to\n' - ' removing whitespace. The *chars* argument is not a ' - 'suffix; rather,\n' - ' all combinations of its values are stripped:\n' - '\n' - " >>> ' spacious '.rstrip()\n" - " ' spacious'\n" - " >>> 'mississippi'.rstrip('ipz')\n" - " 'mississ'\n" - '\n' - 'str.split(sep=None, maxsplit=-1)\n' - '\n' - ' Return a list of the words in the string, using *sep* ' - 'as the\n' - ' delimiter string. If *maxsplit* is given, at most ' - '*maxsplit*\n' - ' splits are done (thus, the list will have at most ' - '"maxsplit+1"\n' - ' elements). If *maxsplit* is not specified or "-1", ' - 'then there is\n' - ' no limit on the number of splits (all possible splits ' - 'are made).\n' - '\n' - ' If *sep* is given, consecutive delimiters are not ' - 'grouped together\n' - ' and are deemed to delimit empty strings (for ' - 'example,\n' - ' "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', ' - '\'2\']"). The *sep* argument\n' - ' may consist of multiple characters (for example,\n' - ' "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', ' - '\'3\']"). Splitting an\n' - ' empty string with a specified separator returns ' - '"[\'\']".\n' - '\n' - ' For example:\n' - '\n' - " >>> '1,2,3'.split(',')\n" - " ['1', '2', '3']\n" - " >>> '1,2,3'.split(',', maxsplit=1)\n" - " ['1', '2,3']\n" - " >>> '1,2,,3,'.split(',')\n" - " ['1', '2', '', '3', '']\n" - '\n' - ' If *sep* is not specified or is "None", a different ' - 'splitting\n' - ' algorithm is applied: runs of consecutive whitespace ' - 'are regarded\n' - ' as a single separator, and the result will contain no ' - 'empty strings\n' - ' at the start or end if the string has leading or ' - 'trailing\n' - ' whitespace. Consequently, splitting an empty string ' - 'or a string\n' - ' consisting of just whitespace with a "None" separator ' - 'returns "[]".\n' - '\n' - ' For example:\n' - '\n' - " >>> '1 2 3'.split()\n" - " ['1', '2', '3']\n" - " >>> '1 2 3'.split(maxsplit=1)\n" - " ['1', '2 3']\n" - " >>> ' 1 2 3 '.split()\n" - " ['1', '2', '3']\n" - '\n' - 'str.splitlines([keepends])\n' - '\n' - ' Return a list of the lines in the string, breaking at ' - 'line\n' - ' boundaries. Line breaks are not included in the ' - 'resulting list\n' - ' unless *keepends* is given and true.\n' - '\n' - ' This method splits on the following line boundaries. ' - 'In\n' - ' particular, the boundaries are a superset of ' - '*universal newlines*.\n' - '\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | Representation | ' - 'Description |\n' - ' ' - '+=========================+===============================+\n' - ' | "\\n" | Line ' - 'Feed |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\r" | Carriage ' - 'Return |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\r\\n" | Carriage Return + Line ' - 'Feed |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\v" or "\\x0b" | Line ' - 'Tabulation |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\f" or "\\x0c" | Form ' - 'Feed |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\x1c" | File ' - 'Separator |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\x1d" | Group ' - 'Separator |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\x1e" | Record ' - 'Separator |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\x85" | Next Line (C1 Control ' - 'Code) |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\u2028" | Line ' - 'Separator |\n' - ' ' - '+-------------------------+-------------------------------+\n' - ' | "\\u2029" | Paragraph ' - 'Separator |\n' - ' ' - '+-------------------------+-------------------------------+\n' - '\n' - ' Changed in version 3.2: "\\v" and "\\f" added to list ' - 'of line\n' - ' boundaries.\n' - '\n' - ' For example:\n' - '\n' - " >>> 'ab c\\n\\nde fg\\rkl\\r\\n'.splitlines()\n" - " ['ab c', '', 'de fg', 'kl']\n" - " >>> 'ab c\\n\\nde " - "fg\\rkl\\r\\n'.splitlines(keepends=True)\n" - " ['ab c\\n', '\\n', 'de fg\\r', 'kl\\r\\n']\n" - '\n' - ' Unlike "split()" when a delimiter string *sep* is ' - 'given, this\n' - ' method returns an empty list for the empty string, ' - 'and a terminal\n' - ' line break does not result in an extra line:\n' - '\n' - ' >>> "".splitlines()\n' - ' []\n' - ' >>> "One line\\n".splitlines()\n' - " ['One line']\n" - '\n' - ' For comparison, "split(\'\\n\')" gives:\n' - '\n' - " >>> ''.split('\\n')\n" - " ['']\n" - " >>> 'Two lines\\n'.split('\\n')\n" - " ['Two lines', '']\n" - '\n' - 'str.startswith(prefix[, start[, end]])\n' - '\n' - ' Return "True" if string starts with the *prefix*, ' - 'otherwise return\n' - ' "False". *prefix* can also be a tuple of prefixes to ' - 'look for.\n' - ' With optional *start*, test string beginning at that ' - 'position.\n' - ' With optional *end*, stop comparing string at that ' - 'position.\n' - '\n' - 'str.strip([chars])\n' - '\n' - ' Return a copy of the string with the leading and ' - 'trailing\n' - ' characters removed. The *chars* argument is a string ' - 'specifying the\n' - ' set of characters to be removed. If omitted or ' - '"None", the *chars*\n' - ' argument defaults to removing whitespace. The *chars* ' - 'argument is\n' - ' not a prefix or suffix; rather, all combinations of ' - 'its values are\n' - ' stripped:\n' - '\n' - " >>> ' spacious '.strip()\n" - " 'spacious'\n" - " >>> 'www.example.com'.strip('cmowz.')\n" - " 'example'\n" - '\n' - ' The outermost leading and trailing *chars* argument ' - 'values are\n' - ' stripped from the string. Characters are removed from ' - 'the leading\n' - ' end until reaching a string character that is not ' - 'contained in the\n' - ' set of characters in *chars*. A similar action takes ' - 'place on the\n' - ' trailing end. For example:\n' - '\n' - " >>> comment_string = '#....... Section 3.2.1 Issue " - "#32 .......'\n" - " >>> comment_string.strip('.#! ')\n" - " 'Section 3.2.1 Issue #32'\n" - '\n' - 'str.swapcase()\n' - '\n' - ' Return a copy of the string with uppercase characters ' - 'converted to\n' - ' lowercase and vice versa. Note that it is not ' - 'necessarily true that\n' - ' "s.swapcase().swapcase() == s".\n' - '\n' - 'str.title()\n' - '\n' - ' Return a titlecased version of the string where words ' - 'start with an\n' - ' uppercase character and the remaining characters are ' - 'lowercase.\n' - '\n' - ' For example:\n' - '\n' - " >>> 'Hello world'.title()\n" - " 'Hello World'\n" - '\n' - ' The algorithm uses a simple language-independent ' - 'definition of a\n' - ' word as groups of consecutive letters. The ' - 'definition works in\n' - ' many contexts but it means that apostrophes in ' - 'contractions and\n' - ' possessives form word boundaries, which may not be ' - 'the desired\n' - ' result:\n' - '\n' - ' >>> "they\'re bill\'s friends from the ' - 'UK".title()\n' - ' "They\'Re Bill\'S Friends From The Uk"\n' - '\n' - ' A workaround for apostrophes can be constructed using ' - 'regular\n' - ' expressions:\n' - '\n' - ' >>> import re\n' - ' >>> def titlecase(s):\n' - ' ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n' - ' ... lambda mo: ' - 'mo.group(0)[0].upper() +\n' - ' ... ' - 'mo.group(0)[1:].lower(),\n' - ' ... s)\n' - ' ...\n' - ' >>> titlecase("they\'re bill\'s friends.")\n' - ' "They\'re Bill\'s Friends."\n' - '\n' - 'str.translate(table)\n' - '\n' - ' Return a copy of the string in which each character ' - 'has been mapped\n' - ' through the given translation table. The table must ' - 'be an object\n' - ' that implements indexing via "__getitem__()", ' - 'typically a *mapping*\n' - ' or *sequence*. When indexed by a Unicode ordinal (an ' - 'integer), the\n' - ' table object can do any of the following: return a ' - 'Unicode ordinal\n' - ' or a string, to map the character to one or more ' - 'other characters;\n' - ' return "None", to delete the character from the ' - 'return string; or\n' - ' raise a "LookupError" exception, to map the character ' - 'to itself.\n' - '\n' - ' You can use "str.maketrans()" to create a translation ' - 'map from\n' - ' character-to-character mappings in different ' - 'formats.\n' - '\n' - ' See also the "codecs" module for a more flexible ' - 'approach to custom\n' - ' character mappings.\n' - '\n' - 'str.upper()\n' - '\n' - ' Return a copy of the string with all the cased ' - 'characters [4]\n' - ' converted to uppercase. Note that ' - '"str.upper().isupper()" might be\n' - ' "False" if "s" contains uncased characters or if the ' - 'Unicode\n' - ' category of the resulting character(s) is not "Lu" ' - '(Letter,\n' - ' uppercase), but e.g. "Lt" (Letter, titlecase).\n' - '\n' - ' The uppercasing algorithm used is described in ' - 'section 3.13 of the\n' - ' Unicode Standard.\n' - '\n' - 'str.zfill(width)\n' - '\n' - ' Return a copy of the string left filled with ASCII ' - '"\'0\'" digits to\n' - ' make a string of length *width*. A leading sign ' - 'prefix\n' - ' ("\'+\'"/"\'-\'") is handled by inserting the padding ' - '*after* the sign\n' - ' character rather than before. The original string is ' - 'returned if\n' - ' *width* is less than or equal to "len(s)".\n' - '\n' - ' For example:\n' - '\n' - ' >>> "42".zfill(5)\n' - " '00042'\n" - ' >>> "-42".zfill(5)\n' - " '-0042'\n", - 'strings': '\n' - 'String and Bytes literals\n' - '*************************\n' - '\n' - 'String literals are described by the following lexical ' - 'definitions:\n' - '\n' - ' stringliteral ::= [stringprefix](shortstring | ' - 'longstring)\n' - ' stringprefix ::= "r" | "u" | "R" | "U"\n' - ' shortstring ::= "\'" shortstringitem* "\'" | \'"\' ' - 'shortstringitem* \'"\'\n' - ' longstring ::= "\'\'\'" longstringitem* "\'\'\'" | ' - '\'"""\' longstringitem* \'"""\'\n' - ' shortstringitem ::= shortstringchar | stringescapeseq\n' - ' longstringitem ::= longstringchar | stringescapeseq\n' - ' shortstringchar ::= \n' - ' longstringchar ::= \n' - ' stringescapeseq ::= "\\" \n' - '\n' - ' bytesliteral ::= bytesprefix(shortbytes | longbytes)\n' - ' bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | ' - '"rb" | "rB" | "Rb" | "RB"\n' - ' shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' ' - 'shortbytesitem* \'"\'\n' - ' longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | ' - '\'"""\' longbytesitem* \'"""\'\n' - ' shortbytesitem ::= shortbyteschar | bytesescapeseq\n' - ' longbytesitem ::= longbyteschar | bytesescapeseq\n' - ' shortbyteschar ::= \n' - ' longbyteschar ::= \n' - ' bytesescapeseq ::= "\\" \n' - '\n' - 'One syntactic restriction not indicated by these productions is ' - 'that\n' - 'whitespace is not allowed between the "stringprefix" or ' - '"bytesprefix"\n' - 'and the rest of the literal. The source character set is ' - 'defined by\n' - 'the encoding declaration; it is UTF-8 if no encoding ' - 'declaration is\n' - 'given in the source file; see section *Encoding declarations*.\n' - '\n' - 'In plain English: Both types of literals can be enclosed in ' - 'matching\n' - 'single quotes ("\'") or double quotes ("""). They can also be ' - 'enclosed\n' - 'in matching groups of three single or double quotes (these are\n' - 'generally referred to as *triple-quoted strings*). The ' - 'backslash\n' - '("\\") character is used to escape characters that otherwise ' - 'have a\n' - 'special meaning, such as newline, backslash itself, or the ' - 'quote\n' - 'character.\n' - '\n' - 'Bytes literals are always prefixed with "\'b\'" or "\'B\'"; ' - 'they produce\n' - 'an instance of the "bytes" type instead of the "str" type. ' - 'They may\n' - 'only contain ASCII characters; bytes with a numeric value of ' - '128 or\n' - 'greater must be expressed with escapes.\n' - '\n' - 'As of Python 3.3 it is possible again to prefix string literals ' - 'with a\n' - '"u" prefix to simplify maintenance of dual 2.x and 3.x ' - 'codebases.\n' - '\n' - 'Both string and bytes literals may optionally be prefixed with ' - 'a\n' - 'letter "\'r\'" or "\'R\'"; such strings are called *raw ' - 'strings* and treat\n' - 'backslashes as literal characters. As a result, in string ' - 'literals,\n' - '"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated ' - 'specially.\n' - "Given that Python 2.x's raw unicode literals behave differently " - 'than\n' - 'Python 3.x\'s the "\'ur\'" syntax is not supported.\n' - '\n' - 'New in version 3.3: The "\'rb\'" prefix of raw bytes literals ' - 'has been\n' - 'added as a synonym of "\'br\'".\n' - '\n' - 'New in version 3.3: Support for the unicode legacy literal\n' - '("u\'value\'") was reintroduced to simplify the maintenance of ' - 'dual\n' - 'Python 2.x and 3.x codebases. See **PEP 414** for more ' - 'information.\n' - '\n' - 'In triple-quoted literals, unescaped newlines and quotes are ' - 'allowed\n' - '(and are retained), except that three unescaped quotes in a ' - 'row\n' - 'terminate the literal. (A "quote" is the character used to ' - 'open the\n' - 'literal, i.e. either "\'" or """.)\n' - '\n' - 'Unless an "\'r\'" or "\'R\'" prefix is present, escape ' - 'sequences in string\n' - 'and bytes literals are interpreted according to rules similar ' - 'to those\n' - 'used by Standard C. The recognized escape sequences are:\n' - '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | ' - 'Notes |\n' - '+===================+===================================+=========+\n' - '| "\\newline" | Backslash and newline ignored ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\\" | Backslash ("\\") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\\'" | Single quote ("\'") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\"" | Double quote (""") ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\a" | ASCII Bell (BEL) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\b" | ASCII Backspace (BS) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\f" | ASCII Formfeed (FF) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\n" | ASCII Linefeed (LF) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\r" | ASCII Carriage Return (CR) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\t" | ASCII Horizontal Tab (TAB) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\v" | ASCII Vertical Tab (VT) ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\ooo" | Character with octal value *ooo* | ' - '(1,3) |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\xhh" | Character with hex value *hh* | ' - '(2,3) |\n' - '+-------------------+-----------------------------------+---------+\n' - '\n' - 'Escape sequences only recognized in string literals are:\n' - '\n' - '+-------------------+-----------------------------------+---------+\n' - '| Escape Sequence | Meaning | ' - 'Notes |\n' - '+===================+===================================+=========+\n' - '| "\\N{name}" | Character named *name* in the | ' - '(4) |\n' - '| | Unicode database ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\uxxxx" | Character with 16-bit hex value | ' - '(5) |\n' - '| | *xxxx* ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '| "\\Uxxxxxxxx" | Character with 32-bit hex value | ' - '(6) |\n' - '| | *xxxxxxxx* ' - '| |\n' - '+-------------------+-----------------------------------+---------+\n' - '\n' - 'Notes:\n' - '\n' - '1. As in Standard C, up to three octal digits are accepted.\n' - '\n' - '2. Unlike in Standard C, exactly two hex digits are required.\n' - '\n' - '3. In a bytes literal, hexadecimal and octal escapes denote ' - 'the\n' - ' byte with the given value. In a string literal, these ' - 'escapes\n' - ' denote a Unicode character with the given value.\n' - '\n' - '4. Changed in version 3.3: Support for name aliases [1] has ' - 'been\n' - ' added.\n' - '\n' - '5. Individual code units which form parts of a surrogate pair ' - 'can\n' - ' be encoded using this escape sequence. Exactly four hex ' - 'digits are\n' - ' required.\n' - '\n' - '6. Any Unicode character can be encoded this way. Exactly ' - 'eight\n' - ' hex digits are required.\n' - '\n' - 'Unlike Standard C, all unrecognized escape sequences are left ' - 'in the\n' - 'string unchanged, i.e., *the backslash is left in the result*. ' - '(This\n' - 'behavior is useful when debugging: if an escape sequence is ' - 'mistyped,\n' - 'the resulting output is more easily recognized as broken.) It ' - 'is also\n' - 'important to note that the escape sequences only recognized in ' - 'string\n' - 'literals fall into the category of unrecognized escapes for ' - 'bytes\n' - 'literals.\n' - '\n' - 'Even in a raw literal, quotes can be escaped with a backslash, ' - 'but the\n' - 'backslash remains in the result; for example, "r"\\""" is a ' - 'valid\n' - 'string literal consisting of two characters: a backslash and a ' - 'double\n' - 'quote; "r"\\"" is not a valid string literal (even a raw string ' - 'cannot\n' - 'end in an odd number of backslashes). Specifically, *a raw ' - 'literal\n' - 'cannot end in a single backslash* (since the backslash would ' - 'escape\n' - 'the following quote character). Note also that a single ' - 'backslash\n' - 'followed by a newline is interpreted as those two characters as ' - 'part\n' - 'of the literal, *not* as a line continuation.\n', - 'subscriptions': '\n' - 'Subscriptions\n' - '*************\n' - '\n' - 'A subscription selects an item of a sequence (string, ' - 'tuple or list)\n' - 'or mapping (dictionary) object:\n' - '\n' - ' subscription ::= primary "[" expression_list "]"\n' - '\n' - 'The primary must evaluate to an object that supports ' - 'subscription\n' - '(lists or dictionaries for example). User-defined ' - 'objects can support\n' - 'subscription by defining a "__getitem__()" method.\n' - '\n' - 'For built-in objects, there are two types of objects that ' - 'support\n' - 'subscription:\n' - '\n' - 'If the primary is a mapping, the expression list must ' - 'evaluate to an\n' - 'object whose value is one of the keys of the mapping, and ' - 'the\n' - 'subscription selects the value in the mapping that ' - 'corresponds to that\n' - 'key. (The expression list is a tuple except if it has ' - 'exactly one\n' - 'item.)\n' - '\n' - 'If the primary is a sequence, the expression (list) must ' - 'evaluate to\n' - 'an integer or a slice (as discussed in the following ' - 'section).\n' - '\n' - 'The formal syntax makes no special provision for negative ' - 'indices in\n' - 'sequences; however, built-in sequences all provide a ' - '"__getitem__()"\n' - 'method that interprets negative indices by adding the ' - 'length of the\n' - 'sequence to the index (so that "x[-1]" selects the last ' - 'item of "x").\n' - 'The resulting value must be a nonnegative integer less ' - 'than the number\n' - 'of items in the sequence, and the subscription selects ' - 'the item whose\n' - 'index is that value (counting from zero). Since the ' - 'support for\n' - "negative indices and slicing occurs in the object's " - '"__getitem__()"\n' - 'method, subclasses overriding this method will need to ' - 'explicitly add\n' - 'that support.\n' - '\n' - "A string's items are characters. A character is not a " - 'separate data\n' - 'type but a string of exactly one character.\n', - 'truth': '\n' - 'Truth Value Testing\n' - '*******************\n' - '\n' - 'Any object can be tested for truth value, for use in an "if" or\n' - '"while" condition or as operand of the Boolean operations below. ' - 'The\n' - 'following values are considered false:\n' - '\n' - '* "None"\n' - '\n' - '* "False"\n' - '\n' - '* zero of any numeric type, for example, "0", "0.0", "0j".\n' - '\n' - '* any empty sequence, for example, "\'\'", "()", "[]".\n' - '\n' - '* any empty mapping, for example, "{}".\n' - '\n' - '* instances of user-defined classes, if the class defines a\n' - ' "__bool__()" or "__len__()" method, when that method returns ' - 'the\n' - ' integer zero or "bool" value "False". [1]\n' - '\n' - 'All other values are considered true --- so objects of many types ' - 'are\n' - 'always true.\n' - '\n' - 'Operations and built-in functions that have a Boolean result ' - 'always\n' - 'return "0" or "False" for false and "1" or "True" for true, ' - 'unless\n' - 'otherwise stated. (Important exception: the Boolean operations ' - '"or"\n' - 'and "and" always return one of their operands.)\n', - 'try': '\n' - 'The "try" statement\n' - '*******************\n' - '\n' - 'The "try" statement specifies exception handlers and/or cleanup ' - 'code\n' - 'for a group of statements:\n' - '\n' - ' try_stmt ::= try1_stmt | try2_stmt\n' - ' try1_stmt ::= "try" ":" suite\n' - ' ("except" [expression ["as" identifier]] ":" ' - 'suite)+\n' - ' ["else" ":" suite]\n' - ' ["finally" ":" suite]\n' - ' try2_stmt ::= "try" ":" suite\n' - ' "finally" ":" suite\n' - '\n' - 'The "except" clause(s) specify one or more exception handlers. When ' - 'no\n' - 'exception occurs in the "try" clause, no exception handler is\n' - 'executed. When an exception occurs in the "try" suite, a search for ' - 'an\n' - 'exception handler is started. This search inspects the except ' - 'clauses\n' - 'in turn until one is found that matches the exception. An ' - 'expression-\n' - 'less except clause, if present, must be last; it matches any\n' - 'exception. For an except clause with an expression, that ' - 'expression\n' - 'is evaluated, and the clause matches the exception if the ' - 'resulting\n' - 'object is "compatible" with the exception. An object is ' - 'compatible\n' - 'with an exception if it is the class or a base class of the ' - 'exception\n' - 'object or a tuple containing an item compatible with the ' - 'exception.\n' - '\n' - 'If no except clause matches the exception, the search for an ' - 'exception\n' - 'handler continues in the surrounding code and on the invocation ' - 'stack.\n' - '[1]\n' - '\n' - 'If the evaluation of an expression in the header of an except ' - 'clause\n' - 'raises an exception, the original search for a handler is canceled ' - 'and\n' - 'a search starts for the new exception in the surrounding code and ' - 'on\n' - 'the call stack (it is treated as if the entire "try" statement ' - 'raised\n' - 'the exception).\n' - '\n' - 'When a matching except clause is found, the exception is assigned ' - 'to\n' - 'the target specified after the "as" keyword in that except clause, ' - 'if\n' - "present, and the except clause's suite is executed. All except\n" - 'clauses must have an executable block. When the end of this block ' - 'is\n' - 'reached, execution continues normally after the entire try ' - 'statement.\n' - '(This means that if two nested handlers exist for the same ' - 'exception,\n' - 'and the exception occurs in the try clause of the inner handler, ' - 'the\n' - 'outer handler will not handle the exception.)\n' - '\n' - 'When an exception has been assigned using "as target", it is ' - 'cleared\n' - 'at the end of the except clause. This is as if\n' - '\n' - ' except E as N:\n' - ' foo\n' - '\n' - 'was translated to\n' - '\n' - ' except E as N:\n' - ' try:\n' - ' foo\n' - ' finally:\n' - ' del N\n' - '\n' - 'This means the exception must be assigned to a different name to ' - 'be\n' - 'able to refer to it after the except clause. Exceptions are ' - 'cleared\n' - 'because with the traceback attached to them, they form a reference\n' - 'cycle with the stack frame, keeping all locals in that frame alive\n' - 'until the next garbage collection occurs.\n' - '\n' - "Before an except clause's suite is executed, details about the\n" - 'exception are stored in the "sys" module and can be accessed via\n' - '"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of ' - 'the\n' - 'exception class, the exception instance and a traceback object ' - '(see\n' - 'section *The standard type hierarchy*) identifying the point in ' - 'the\n' - 'program where the exception occurred. "sys.exc_info()" values are\n' - 'restored to their previous values (before the call) when returning\n' - 'from a function that handled an exception.\n' - '\n' - 'The optional "else" clause is executed if and when control flows ' - 'off\n' - 'the end of the "try" clause. [2] Exceptions in the "else" clause ' - 'are\n' - 'not handled by the preceding "except" clauses.\n' - '\n' - 'If "finally" is present, it specifies a \'cleanup\' handler. The ' - '"try"\n' - 'clause is executed, including any "except" and "else" clauses. If ' - 'an\n' - 'exception occurs in any of the clauses and is not handled, the\n' - 'exception is temporarily saved. The "finally" clause is executed. ' - 'If\n' - 'there is a saved exception it is re-raised at the end of the ' - '"finally"\n' - 'clause. If the "finally" clause raises another exception, the ' - 'saved\n' - 'exception is set as the context of the new exception. If the ' - '"finally"\n' - 'clause executes a "return" or "break" statement, the saved ' - 'exception\n' - 'is discarded:\n' - '\n' - ' >>> def f():\n' - ' ... try:\n' - ' ... 1/0\n' - ' ... finally:\n' - ' ... return 42\n' - ' ...\n' - ' >>> f()\n' - ' 42\n' - '\n' - 'The exception information is not available to the program during\n' - 'execution of the "finally" clause.\n' - '\n' - 'When a "return", "break" or "continue" statement is executed in ' - 'the\n' - '"try" suite of a "try"..."finally" statement, the "finally" clause ' - 'is\n' - 'also executed \'on the way out.\' A "continue" statement is illegal ' - 'in\n' - 'the "finally" clause. (The reason is a problem with the current\n' - 'implementation --- this restriction may be lifted in the future).\n' - '\n' - 'The return value of a function is determined by the last "return"\n' - 'statement executed. Since the "finally" clause always executes, a\n' - '"return" statement executed in the "finally" clause will always be ' - 'the\n' - 'last one executed:\n' - '\n' - ' >>> def foo():\n' - ' ... try:\n' - " ... return 'try'\n" - ' ... finally:\n' - " ... return 'finally'\n" - ' ...\n' - ' >>> foo()\n' - " 'finally'\n" - '\n' - 'Additional information on exceptions can be found in section\n' - '*Exceptions*, and information on using the "raise" statement to\n' - 'generate exceptions may be found in section *The raise statement*.\n', - 'types': '\n' - 'The standard type hierarchy\n' - '***************************\n' - '\n' - 'Below is a list of the types that are built into Python. ' - 'Extension\n' - 'modules (written in C, Java, or other languages, depending on ' - 'the\n' - 'implementation) can define additional types. Future versions of\n' - 'Python may add types to the type hierarchy (e.g., rational ' - 'numbers,\n' - 'efficiently stored arrays of integers, etc.), although such ' - 'additions\n' - 'will often be provided via the standard library instead.\n' - '\n' - 'Some of the type descriptions below contain a paragraph listing\n' - "'special attributes.' These are attributes that provide access " - 'to the\n' - 'implementation and are not intended for general use. Their ' - 'definition\n' - 'may change in the future.\n' - '\n' - 'None\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name ' - '"None". It\n' - ' is used to signify the absence of a value in many situations, ' - 'e.g.,\n' - " it is returned from functions that don't explicitly return\n" - ' anything. Its truth value is false.\n' - '\n' - 'NotImplemented\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the built-in name\n' - ' "NotImplemented". Numeric methods and rich comparison methods\n' - ' should return this value if they do not implement the ' - 'operation for\n' - ' the operands provided. (The interpreter will then try the\n' - ' reflected operation, or some other fallback, depending on the\n' - ' operator.) Its truth value is true.\n' - '\n' - ' See *Implementing the arithmetic operations* for more ' - 'details.\n' - '\n' - 'Ellipsis\n' - ' This type has a single value. There is a single object with ' - 'this\n' - ' value. This object is accessed through the literal "..." or ' - 'the\n' - ' built-in name "Ellipsis". Its truth value is true.\n' - '\n' - '"numbers.Number"\n' - ' These are created by numeric literals and returned as results ' - 'by\n' - ' arithmetic operators and arithmetic built-in functions. ' - 'Numeric\n' - ' objects are immutable; once created their value never ' - 'changes.\n' - ' Python numbers are of course strongly related to mathematical\n' - ' numbers, but subject to the limitations of numerical ' - 'representation\n' - ' in computers.\n' - '\n' - ' Python distinguishes between integers, floating point numbers, ' - 'and\n' - ' complex numbers:\n' - '\n' - ' "numbers.Integral"\n' - ' These represent elements from the mathematical set of ' - 'integers\n' - ' (positive and negative).\n' - '\n' - ' There are two types of integers:\n' - '\n' - ' Integers ("int")\n' - '\n' - ' These represent numbers in an unlimited range, subject ' - 'to\n' - ' available (virtual) memory only. For the purpose of ' - 'shift\n' - ' and mask operations, a binary representation is assumed, ' - 'and\n' - " negative numbers are represented in a variant of 2's\n" - ' complement which gives the illusion of an infinite ' - 'string of\n' - ' sign bits extending to the left.\n' - '\n' - ' Booleans ("bool")\n' - ' These represent the truth values False and True. The ' - 'two\n' - ' objects representing the values "False" and "True" are ' - 'the\n' - ' only Boolean objects. The Boolean type is a subtype of ' - 'the\n' - ' integer type, and Boolean values behave like the values ' - '0 and\n' - ' 1, respectively, in almost all contexts, the exception ' - 'being\n' - ' that when converted to a string, the strings ""False"" ' - 'or\n' - ' ""True"" are returned, respectively.\n' - '\n' - ' The rules for integer representation are intended to give ' - 'the\n' - ' most meaningful interpretation of shift and mask ' - 'operations\n' - ' involving negative integers.\n' - '\n' - ' "numbers.Real" ("float")\n' - ' These represent machine-level double precision floating ' - 'point\n' - ' numbers. You are at the mercy of the underlying machine\n' - ' architecture (and C or Java implementation) for the ' - 'accepted\n' - ' range and handling of overflow. Python does not support ' - 'single-\n' - ' precision floating point numbers; the savings in processor ' - 'and\n' - ' memory usage that are usually the reason for using these ' - 'are\n' - ' dwarfed by the overhead of using objects in Python, so ' - 'there is\n' - ' no reason to complicate the language with two kinds of ' - 'floating\n' - ' point numbers.\n' - '\n' - ' "numbers.Complex" ("complex")\n' - ' These represent complex numbers as a pair of machine-level\n' - ' double precision floating point numbers. The same caveats ' - 'apply\n' - ' as for floating point numbers. The real and imaginary parts ' - 'of a\n' - ' complex number "z" can be retrieved through the read-only\n' - ' attributes "z.real" and "z.imag".\n' - '\n' - 'Sequences\n' - ' These represent finite ordered sets indexed by non-negative\n' - ' numbers. The built-in function "len()" returns the number of ' - 'items\n' - ' of a sequence. When the length of a sequence is *n*, the index ' - 'set\n' - ' contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence ' - '*a* is\n' - ' selected by "a[i]".\n' - '\n' - ' Sequences also support slicing: "a[i:j]" selects all items ' - 'with\n' - ' index *k* such that *i* "<=" *k* "<" *j*. When used as an\n' - ' expression, a slice is a sequence of the same type. This ' - 'implies\n' - ' that the index set is renumbered so that it starts at 0.\n' - '\n' - ' Some sequences also support "extended slicing" with a third ' - '"step"\n' - ' parameter: "a[i:j:k]" selects all items of *a* with index *x* ' - 'where\n' - ' "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n' - '\n' - ' Sequences are distinguished according to their mutability:\n' - '\n' - ' Immutable sequences\n' - ' An object of an immutable sequence type cannot change once ' - 'it is\n' - ' created. (If the object contains references to other ' - 'objects,\n' - ' these other objects may be mutable and may be changed; ' - 'however,\n' - ' the collection of objects directly referenced by an ' - 'immutable\n' - ' object cannot change.)\n' - '\n' - ' The following types are immutable sequences:\n' - '\n' - ' Strings\n' - ' A string is a sequence of values that represent Unicode ' - 'code\n' - ' points. All the code points in the range "U+0000 - ' - 'U+10FFFF"\n' - " can be represented in a string. Python doesn't have a " - '"char"\n' - ' type; instead, every code point in the string is ' - 'represented\n' - ' as a string object with length "1". The built-in ' - 'function\n' - ' "ord()" converts a code point from its string form to ' - 'an\n' - ' integer in the range "0 - 10FFFF"; "chr()" converts an\n' - ' integer in the range "0 - 10FFFF" to the corresponding ' - 'length\n' - ' "1" string object. "str.encode()" can be used to convert ' - 'a\n' - ' "str" to "bytes" using the given text encoding, and\n' - ' "bytes.decode()" can be used to achieve the opposite.\n' - '\n' - ' Tuples\n' - ' The items of a tuple are arbitrary Python objects. ' - 'Tuples of\n' - ' two or more items are formed by comma-separated lists ' - 'of\n' - " expressions. A tuple of one item (a 'singleton') can " - 'be\n' - ' formed by affixing a comma to an expression (an ' - 'expression by\n' - ' itself does not create a tuple, since parentheses must ' - 'be\n' - ' usable for grouping of expressions). An empty tuple can ' - 'be\n' - ' formed by an empty pair of parentheses.\n' - '\n' - ' Bytes\n' - ' A bytes object is an immutable array. The items are ' - '8-bit\n' - ' bytes, represented by integers in the range 0 <= x < ' - '256.\n' - ' Bytes literals (like "b\'abc\'") and the built-in ' - 'function\n' - ' "bytes()" can be used to construct bytes objects. ' - 'Also,\n' - ' bytes objects can be decoded to strings via the ' - '"decode()"\n' - ' method.\n' - '\n' - ' Mutable sequences\n' - ' Mutable sequences can be changed after they are created. ' - 'The\n' - ' subscription and slicing notations can be used as the ' - 'target of\n' - ' assignment and "del" (delete) statements.\n' - '\n' - ' There are currently two intrinsic mutable sequence types:\n' - '\n' - ' Lists\n' - ' The items of a list are arbitrary Python objects. Lists ' - 'are\n' - ' formed by placing a comma-separated list of expressions ' - 'in\n' - ' square brackets. (Note that there are no special cases ' - 'needed\n' - ' to form lists of length 0 or 1.)\n' - '\n' - ' Byte Arrays\n' - ' A bytearray object is a mutable array. They are created ' - 'by\n' - ' the built-in "bytearray()" constructor. Aside from ' - 'being\n' - ' mutable (and hence unhashable), byte arrays otherwise ' - 'provide\n' - ' the same interface and functionality as immutable bytes\n' - ' objects.\n' - '\n' - ' The extension module "array" provides an additional example ' - 'of a\n' - ' mutable sequence type, as does the "collections" module.\n' - '\n' - 'Set types\n' - ' These represent unordered, finite sets of unique, immutable\n' - ' objects. As such, they cannot be indexed by any subscript. ' - 'However,\n' - ' they can be iterated over, and the built-in function "len()"\n' - ' returns the number of items in a set. Common uses for sets are ' - 'fast\n' - ' membership testing, removing duplicates from a sequence, and\n' - ' computing mathematical operations such as intersection, ' - 'union,\n' - ' difference, and symmetric difference.\n' - '\n' - ' For set elements, the same immutability rules apply as for\n' - ' dictionary keys. Note that numeric types obey the normal rules ' - 'for\n' - ' numeric comparison: if two numbers compare equal (e.g., "1" ' - 'and\n' - ' "1.0"), only one of them can be contained in a set.\n' - '\n' - ' There are currently two intrinsic set types:\n' - '\n' - ' Sets\n' - ' These represent a mutable set. They are created by the ' - 'built-in\n' - ' "set()" constructor and can be modified afterwards by ' - 'several\n' - ' methods, such as "add()".\n' - '\n' - ' Frozen sets\n' - ' These represent an immutable set. They are created by the\n' - ' built-in "frozenset()" constructor. As a frozenset is ' - 'immutable\n' - ' and *hashable*, it can be used again as an element of ' - 'another\n' - ' set, or as a dictionary key.\n' - '\n' - 'Mappings\n' - ' These represent finite sets of objects indexed by arbitrary ' - 'index\n' - ' sets. The subscript notation "a[k]" selects the item indexed ' - 'by "k"\n' - ' from the mapping "a"; this can be used in expressions and as ' - 'the\n' - ' target of assignments or "del" statements. The built-in ' - 'function\n' - ' "len()" returns the number of items in a mapping.\n' - '\n' - ' There is currently a single intrinsic mapping type:\n' - '\n' - ' Dictionaries\n' - ' These represent finite sets of objects indexed by nearly\n' - ' arbitrary values. The only types of values not acceptable ' - 'as\n' - ' keys are values containing lists or dictionaries or other\n' - ' mutable types that are compared by value rather than by ' - 'object\n' - ' identity, the reason being that the efficient ' - 'implementation of\n' - " dictionaries requires a key's hash value to remain " - 'constant.\n' - ' Numeric types used for keys obey the normal rules for ' - 'numeric\n' - ' comparison: if two numbers compare equal (e.g., "1" and ' - '"1.0")\n' - ' then they can be used interchangeably to index the same\n' - ' dictionary entry.\n' - '\n' - ' Dictionaries are mutable; they can be created by the ' - '"{...}"\n' - ' notation (see section *Dictionary displays*).\n' - '\n' - ' The extension modules "dbm.ndbm" and "dbm.gnu" provide\n' - ' additional examples of mapping types, as does the ' - '"collections"\n' - ' module.\n' - '\n' - 'Callable types\n' - ' These are the types to which the function call operation (see\n' - ' section *Calls*) can be applied:\n' - '\n' - ' User-defined functions\n' - ' A user-defined function object is created by a function\n' - ' definition (see section *Function definitions*). It should ' - 'be\n' - ' called with an argument list containing the same number of ' - 'items\n' - " as the function's formal parameter list.\n" - '\n' - ' Special attributes:\n' - '\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | Attribute | ' - 'Meaning | |\n' - ' ' - '+===========================+=================================+=============+\n' - ' | "__doc__" | The function\'s ' - 'documentation | Writable |\n' - ' | | string, or "None" ' - 'if | |\n' - ' | | unavailable; not inherited ' - 'by | |\n' - ' | | ' - 'subclasses | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__name__" | The function\'s ' - 'name | Writable |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__qualname__" | The function\'s *qualified ' - 'name* | Writable |\n' - ' | | New in version ' - '3.3. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__module__" | The name of the module ' - 'the | Writable |\n' - ' | | function was defined in, ' - 'or | |\n' - ' | | "None" if ' - 'unavailable. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__defaults__" | A tuple containing ' - 'default | Writable |\n' - ' | | argument values for ' - 'those | |\n' - ' | | arguments that have ' - 'defaults, | |\n' - ' | | or "None" if no arguments ' - 'have | |\n' - ' | | a default ' - 'value | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__code__" | The code object ' - 'representing | Writable |\n' - ' | | the compiled function ' - 'body. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__globals__" | A reference to the ' - 'dictionary | Read-only |\n' - ' | | that holds the ' - "function's | |\n" - ' | | global variables --- the ' - 'global | |\n' - ' | | namespace of the module ' - 'in | |\n' - ' | | which the function was ' - 'defined. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__dict__" | The namespace ' - 'supporting | Writable |\n' - ' | | arbitrary function ' - 'attributes. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__closure__" | "None" or a tuple of cells ' - 'that | Read-only |\n' - ' | | contain bindings for ' - 'the | |\n' - " | | function's free " - 'variables. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__annotations__" | A dict containing ' - 'annotations | Writable |\n' - ' | | of parameters. The keys of ' - 'the | |\n' - ' | | dict are the parameter ' - 'names, | |\n' - ' | | and "\'return\'" for the ' - 'return | |\n' - ' | | annotation, if ' - 'provided. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - ' | "__kwdefaults__" | A dict containing defaults ' - 'for | Writable |\n' - ' | | keyword-only ' - 'parameters. | |\n' - ' ' - '+---------------------------+---------------------------------+-------------+\n' - '\n' - ' Most of the attributes labelled "Writable" check the type ' - 'of the\n' - ' assigned value.\n' - '\n' - ' Function objects also support getting and setting ' - 'arbitrary\n' - ' attributes, which can be used, for example, to attach ' - 'metadata\n' - ' to functions. Regular attribute dot-notation is used to ' - 'get and\n' - ' set such attributes. *Note that the current implementation ' - 'only\n' - ' supports function attributes on user-defined functions. ' - 'Function\n' - ' attributes on built-in functions may be supported in the\n' - ' future.*\n' - '\n' - " Additional information about a function's definition can " - 'be\n' - ' retrieved from its code object; see the description of ' - 'internal\n' - ' types below.\n' - '\n' - ' Instance methods\n' - ' An instance method object combines a class, a class ' - 'instance and\n' - ' any callable object (normally a user-defined function).\n' - '\n' - ' Special read-only attributes: "__self__" is the class ' - 'instance\n' - ' object, "__func__" is the function object; "__doc__" is ' - 'the\n' - ' method\'s documentation (same as "__func__.__doc__"); ' - '"__name__"\n' - ' is the method name (same as "__func__.__name__"); ' - '"__module__"\n' - ' is the name of the module the method was defined in, or ' - '"None"\n' - ' if unavailable.\n' - '\n' - ' Methods also support accessing (but not setting) the ' - 'arbitrary\n' - ' function attributes on the underlying function object.\n' - '\n' - ' User-defined method objects may be created when getting an\n' - ' attribute of a class (perhaps via an instance of that ' - 'class), if\n' - ' that attribute is a user-defined function object or a ' - 'class\n' - ' method object.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'user-\n' - ' defined function object from a class via one of its ' - 'instances,\n' - ' its "__self__" attribute is the instance, and the method ' - 'object\n' - ' is said to be bound. The new method\'s "__func__" ' - 'attribute is\n' - ' the original function object.\n' - '\n' - ' When a user-defined method object is created by retrieving\n' - ' another method object from a class or instance, the ' - 'behaviour is\n' - ' the same as for a function object, except that the ' - '"__func__"\n' - ' attribute of the new instance is not the original method ' - 'object\n' - ' but its "__func__" attribute.\n' - '\n' - ' When an instance method object is created by retrieving a ' - 'class\n' - ' method object from a class or instance, its "__self__" ' - 'attribute\n' - ' is the class itself, and its "__func__" attribute is the\n' - ' function object underlying the class method.\n' - '\n' - ' When an instance method object is called, the underlying\n' - ' function ("__func__") is called, inserting the class ' - 'instance\n' - ' ("__self__") in front of the argument list. For instance, ' - 'when\n' - ' "C" is a class which contains a definition for a function ' - '"f()",\n' - ' and "x" is an instance of "C", calling "x.f(1)" is ' - 'equivalent to\n' - ' calling "C.f(x, 1)".\n' - '\n' - ' When an instance method object is derived from a class ' - 'method\n' - ' object, the "class instance" stored in "__self__" will ' - 'actually\n' - ' be the class itself, so that calling either "x.f(1)" or ' - '"C.f(1)"\n' - ' is equivalent to calling "f(C,1)" where "f" is the ' - 'underlying\n' - ' function.\n' - '\n' - ' Note that the transformation from function object to ' - 'instance\n' - ' method object happens each time the attribute is retrieved ' - 'from\n' - ' the instance. In some cases, a fruitful optimization is ' - 'to\n' - ' assign the attribute to a local variable and call that ' - 'local\n' - ' variable. Also notice that this transformation only happens ' - 'for\n' - ' user-defined functions; other callable objects (and all ' - 'non-\n' - ' callable objects) are retrieved without transformation. It ' - 'is\n' - ' also important to note that user-defined functions which ' - 'are\n' - ' attributes of a class instance are not converted to bound\n' - ' methods; this *only* happens when the function is an ' - 'attribute\n' - ' of the class.\n' - '\n' - ' Generator functions\n' - ' A function or method which uses the "yield" statement (see\n' - ' section *The yield statement*) is called a *generator ' - 'function*.\n' - ' Such a function, when called, always returns an iterator ' - 'object\n' - ' which can be used to execute the body of the function: ' - 'calling\n' - ' the iterator\'s "iterator.__next__()" method will cause ' - 'the\n' - ' function to execute until it provides a value using the ' - '"yield"\n' - ' statement. When the function executes a "return" statement ' - 'or\n' - ' falls off the end, a "StopIteration" exception is raised ' - 'and the\n' - ' iterator will have reached the end of the set of values to ' - 'be\n' - ' returned.\n' - '\n' - ' Coroutine functions\n' - ' A function or method which is defined using "async def" is\n' - ' called a *coroutine function*. Such a function, when ' - 'called,\n' - ' returns a *coroutine* object. It may contain "await"\n' - ' expressions, as well as "async with" and "async for" ' - 'statements.\n' - ' See also the *Coroutine Objects* section.\n' - '\n' - ' Built-in functions\n' - ' A built-in function object is a wrapper around a C ' - 'function.\n' - ' Examples of built-in functions are "len()" and ' - '"math.sin()"\n' - ' ("math" is a standard built-in module). The number and type ' - 'of\n' - ' the arguments are determined by the C function. Special ' - 'read-\n' - ' only attributes: "__doc__" is the function\'s ' - 'documentation\n' - ' string, or "None" if unavailable; "__name__" is the ' - "function's\n" - ' name; "__self__" is set to "None" (but see the next item);\n' - ' "__module__" is the name of the module the function was ' - 'defined\n' - ' in or "None" if unavailable.\n' - '\n' - ' Built-in methods\n' - ' This is really a different disguise of a built-in function, ' - 'this\n' - ' time containing an object passed to the C function as an\n' - ' implicit extra argument. An example of a built-in method ' - 'is\n' - ' "alist.append()", assuming *alist* is a list object. In ' - 'this\n' - ' case, the special read-only attribute "__self__" is set to ' - 'the\n' - ' object denoted by *alist*.\n' - '\n' - ' Classes\n' - ' Classes are callable. These objects normally act as ' - 'factories\n' - ' for new instances of themselves, but variations are ' - 'possible for\n' - ' class types that override "__new__()". The arguments of ' - 'the\n' - ' call are passed to "__new__()" and, in the typical case, ' - 'to\n' - ' "__init__()" to initialize the new instance.\n' - '\n' - ' Class Instances\n' - ' Instances of arbitrary classes can be made callable by ' - 'defining\n' - ' a "__call__()" method in their class.\n' - '\n' - 'Modules\n' - ' Modules are a basic organizational unit of Python code, and ' - 'are\n' - ' created by the *import system* as invoked either by the ' - '"import"\n' - ' statement (see "import"), or by calling functions such as\n' - ' "importlib.import_module()" and built-in "__import__()". A ' - 'module\n' - ' object has a namespace implemented by a dictionary object ' - '(this is\n' - ' the dictionary referenced by the "__globals__" attribute of\n' - ' functions defined in the module). Attribute references are\n' - ' translated to lookups in this dictionary, e.g., "m.x" is ' - 'equivalent\n' - ' to "m.__dict__["x"]". A module object does not contain the ' - 'code\n' - " object used to initialize the module (since it isn't needed " - 'once\n' - ' the initialization is done).\n' - '\n' - " Attribute assignment updates the module's namespace " - 'dictionary,\n' - ' e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n' - '\n' - ' Special read-only attribute: "__dict__" is the module\'s ' - 'namespace\n' - ' as a dictionary object.\n' - '\n' - ' **CPython implementation detail:** Because of the way CPython\n' - ' clears module dictionaries, the module dictionary will be ' - 'cleared\n' - ' when the module falls out of scope even if the dictionary ' - 'still has\n' - ' live references. To avoid this, copy the dictionary or keep ' - 'the\n' - ' module around while using its dictionary directly.\n' - '\n' - ' Predefined (writable) attributes: "__name__" is the module\'s ' - 'name;\n' - ' "__doc__" is the module\'s documentation string, or "None" if\n' - ' unavailable; "__file__" is the pathname of the file from which ' - 'the\n' - ' module was loaded, if it was loaded from a file. The ' - '"__file__"\n' - ' attribute may be missing for certain types of modules, such as ' - 'C\n' - ' modules that are statically linked into the interpreter; for\n' - ' extension modules loaded dynamically from a shared library, it ' - 'is\n' - ' the pathname of the shared library file.\n' - '\n' - 'Custom classes\n' - ' Custom class types are typically created by class definitions ' - '(see\n' - ' section *Class definitions*). A class has a namespace ' - 'implemented\n' - ' by a dictionary object. Class attribute references are ' - 'translated\n' - ' to lookups in this dictionary, e.g., "C.x" is translated to\n' - ' "C.__dict__["x"]" (although there are a number of hooks which ' - 'allow\n' - ' for other means of locating attributes). When the attribute ' - 'name is\n' - ' not found there, the attribute search continues in the base\n' - ' classes. This search of the base classes uses the C3 method\n' - ' resolution order which behaves correctly even in the presence ' - 'of\n' - " 'diamond' inheritance structures where there are multiple\n" - ' inheritance paths leading back to a common ancestor. ' - 'Additional\n' - ' details on the C3 MRO used by Python can be found in the\n' - ' documentation accompanying the 2.3 release at\n' - ' https://www.python.org/download/releases/2.3/mro/.\n' - '\n' - ' When a class attribute reference (for class "C", say) would ' - 'yield a\n' - ' class method object, it is transformed into an instance ' - 'method\n' - ' object whose "__self__" attributes is "C". When it would ' - 'yield a\n' - ' static method object, it is transformed into the object ' - 'wrapped by\n' - ' the static method object. See section *Implementing ' - 'Descriptors*\n' - ' for another way in which attributes retrieved from a class ' - 'may\n' - ' differ from those actually contained in its "__dict__".\n' - '\n' - " Class attribute assignments update the class's dictionary, " - 'never\n' - ' the dictionary of a base class.\n' - '\n' - ' A class object can be called (see above) to yield a class ' - 'instance\n' - ' (see below).\n' - '\n' - ' Special attributes: "__name__" is the class name; "__module__" ' - 'is\n' - ' the module name in which the class was defined; "__dict__" is ' - 'the\n' - ' dictionary containing the class\'s namespace; "__bases__" is a ' - 'tuple\n' - ' (possibly empty or a singleton) containing the base classes, ' - 'in the\n' - ' order of their occurrence in the base class list; "__doc__" is ' - 'the\n' - " class's documentation string, or None if undefined.\n" - '\n' - 'Class instances\n' - ' A class instance is created by calling a class object (see ' - 'above).\n' - ' A class instance has a namespace implemented as a dictionary ' - 'which\n' - ' is the first place in which attribute references are ' - 'searched.\n' - " When an attribute is not found there, and the instance's class " - 'has\n' - ' an attribute by that name, the search continues with the ' - 'class\n' - ' attributes. If a class attribute is found that is a ' - 'user-defined\n' - ' function object, it is transformed into an instance method ' - 'object\n' - ' whose "__self__" attribute is the instance. Static method ' - 'and\n' - ' class method objects are also transformed; see above under\n' - ' "Classes". See section *Implementing Descriptors* for another ' - 'way\n' - ' in which attributes of a class retrieved via its instances ' - 'may\n' - " differ from the objects actually stored in the class's " - '"__dict__".\n' - " If no class attribute is found, and the object's class has a\n" - ' "__getattr__()" method, that is called to satisfy the lookup.\n' - '\n' - " Attribute assignments and deletions update the instance's\n" - " dictionary, never a class's dictionary. If the class has a\n" - ' "__setattr__()" or "__delattr__()" method, this is called ' - 'instead\n' - ' of updating the instance dictionary directly.\n' - '\n' - ' Class instances can pretend to be numbers, sequences, or ' - 'mappings\n' - ' if they have methods with certain special names. See section\n' - ' *Special method names*.\n' - '\n' - ' Special attributes: "__dict__" is the attribute dictionary;\n' - ' "__class__" is the instance\'s class.\n' - '\n' - 'I/O objects (also known as file objects)\n' - ' A *file object* represents an open file. Various shortcuts ' - 'are\n' - ' available to create file objects: the "open()" built-in ' - 'function,\n' - ' and also "os.popen()", "os.fdopen()", and the "makefile()" ' - 'method\n' - ' of socket objects (and perhaps by other functions or methods\n' - ' provided by extension modules).\n' - '\n' - ' The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n' - ' initialized to file objects corresponding to the ' - "interpreter's\n" - ' standard input, output and error streams; they are all open in ' - 'text\n' - ' mode and therefore follow the interface defined by the\n' - ' "io.TextIOBase" abstract class.\n' - '\n' - 'Internal types\n' - ' A few types used internally by the interpreter are exposed to ' - 'the\n' - ' user. Their definitions may change with future versions of ' - 'the\n' - ' interpreter, but they are mentioned here for completeness.\n' - '\n' - ' Code objects\n' - ' Code objects represent *byte-compiled* executable Python ' - 'code,\n' - ' or *bytecode*. The difference between a code object and a\n' - ' function object is that the function object contains an ' - 'explicit\n' - " reference to the function's globals (the module in which it " - 'was\n' - ' defined), while a code object contains no context; also ' - 'the\n' - ' default argument values are stored in the function object, ' - 'not\n' - ' in the code object (because they represent values ' - 'calculated at\n' - ' run-time). Unlike function objects, code objects are ' - 'immutable\n' - ' and contain no references (directly or indirectly) to ' - 'mutable\n' - ' objects.\n' - '\n' - ' Special read-only attributes: "co_name" gives the function ' - 'name;\n' - ' "co_argcount" is the number of positional arguments ' - '(including\n' - ' arguments with default values); "co_nlocals" is the number ' - 'of\n' - ' local variables used by the function (including ' - 'arguments);\n' - ' "co_varnames" is a tuple containing the names of the local\n' - ' variables (starting with the argument names); "co_cellvars" ' - 'is a\n' - ' tuple containing the names of local variables that are\n' - ' referenced by nested functions; "co_freevars" is a tuple\n' - ' containing the names of free variables; "co_code" is a ' - 'string\n' - ' representing the sequence of bytecode instructions; ' - '"co_consts"\n' - ' is a tuple containing the literals used by the bytecode;\n' - ' "co_names" is a tuple containing the names used by the ' - 'bytecode;\n' - ' "co_filename" is the filename from which the code was ' - 'compiled;\n' - ' "co_firstlineno" is the first line number of the function;\n' - ' "co_lnotab" is a string encoding the mapping from bytecode\n' - ' offsets to line numbers (for details see the source code of ' - 'the\n' - ' interpreter); "co_stacksize" is the required stack size\n' - ' (including local variables); "co_flags" is an integer ' - 'encoding a\n' - ' number of flags for the interpreter.\n' - '\n' - ' The following flag bits are defined for "co_flags": bit ' - '"0x04"\n' - ' is set if the function uses the "*arguments" syntax to ' - 'accept an\n' - ' arbitrary number of positional arguments; bit "0x08" is set ' - 'if\n' - ' the function uses the "**keywords" syntax to accept ' - 'arbitrary\n' - ' keyword arguments; bit "0x20" is set if the function is a\n' - ' generator.\n' - '\n' - ' Future feature declarations ("from __future__ import ' - 'division")\n' - ' also use bits in "co_flags" to indicate whether a code ' - 'object\n' - ' was compiled with a particular feature enabled: bit ' - '"0x2000" is\n' - ' set if the function was compiled with future division ' - 'enabled;\n' - ' bits "0x10" and "0x1000" were used in earlier versions of\n' - ' Python.\n' - '\n' - ' Other bits in "co_flags" are reserved for internal use.\n' - '\n' - ' If a code object represents a function, the first item in\n' - ' "co_consts" is the documentation string of the function, ' - 'or\n' - ' "None" if undefined.\n' - '\n' - ' Frame objects\n' - ' Frame objects represent execution frames. They may occur ' - 'in\n' - ' traceback objects (see below).\n' - '\n' - ' Special read-only attributes: "f_back" is to the previous ' - 'stack\n' - ' frame (towards the caller), or "None" if this is the ' - 'bottom\n' - ' stack frame; "f_code" is the code object being executed in ' - 'this\n' - ' frame; "f_locals" is the dictionary used to look up local\n' - ' variables; "f_globals" is used for global variables;\n' - ' "f_builtins" is used for built-in (intrinsic) names; ' - '"f_lasti"\n' - ' gives the precise instruction (this is an index into the\n' - ' bytecode string of the code object).\n' - '\n' - ' Special writable attributes: "f_trace", if not "None", is ' - 'a\n' - ' function called at the start of each source code line (this ' - 'is\n' - ' used by the debugger); "f_lineno" is the current line ' - 'number of\n' - ' the frame --- writing to this from within a trace function ' - 'jumps\n' - ' to the given line (only for the bottom-most frame). A ' - 'debugger\n' - ' can implement a Jump command (aka Set Next Statement) by ' - 'writing\n' - ' to f_lineno.\n' - '\n' - ' Frame objects support one method:\n' - '\n' - ' frame.clear()\n' - '\n' - ' This method clears all references to local variables ' - 'held by\n' - ' the frame. Also, if the frame belonged to a generator, ' - 'the\n' - ' generator is finalized. This helps break reference ' - 'cycles\n' - ' involving frame objects (for example when catching an\n' - ' exception and storing its traceback for later use).\n' - '\n' - ' "RuntimeError" is raised if the frame is currently ' - 'executing.\n' - '\n' - ' New in version 3.4.\n' - '\n' - ' Traceback objects\n' - ' Traceback objects represent a stack trace of an exception. ' - 'A\n' - ' traceback object is created when an exception occurs. When ' - 'the\n' - ' search for an exception handler unwinds the execution ' - 'stack, at\n' - ' each unwound level a traceback object is inserted in front ' - 'of\n' - ' the current traceback. When an exception handler is ' - 'entered,\n' - ' the stack trace is made available to the program. (See ' - 'section\n' - ' *The try statement*.) It is accessible as the third item of ' - 'the\n' - ' tuple returned by "sys.exc_info()". When the program ' - 'contains no\n' - ' suitable handler, the stack trace is written (nicely ' - 'formatted)\n' - ' to the standard error stream; if the interpreter is ' - 'interactive,\n' - ' it is also made available to the user as ' - '"sys.last_traceback".\n' - '\n' - ' Special read-only attributes: "tb_next" is the next level ' - 'in the\n' - ' stack trace (towards the frame where the exception ' - 'occurred), or\n' - ' "None" if there is no next level; "tb_frame" points to the\n' - ' execution frame of the current level; "tb_lineno" gives the ' - 'line\n' - ' number where the exception occurred; "tb_lasti" indicates ' - 'the\n' - ' precise instruction. The line number and last instruction ' - 'in\n' - ' the traceback may differ from the line number of its frame\n' - ' object if the exception occurred in a "try" statement with ' - 'no\n' - ' matching except clause or with a finally clause.\n' - '\n' - ' Slice objects\n' - ' Slice objects are used to represent slices for ' - '"__getitem__()"\n' - ' methods. They are also created by the built-in "slice()"\n' - ' function.\n' - '\n' - ' Special read-only attributes: "start" is the lower bound; ' - '"stop"\n' - ' is the upper bound; "step" is the step value; each is ' - '"None" if\n' - ' omitted. These attributes can have any type.\n' - '\n' - ' Slice objects support one method:\n' - '\n' - ' slice.indices(self, length)\n' - '\n' - ' This method takes a single integer argument *length* ' - 'and\n' - ' computes information about the slice that the slice ' - 'object\n' - ' would describe if applied to a sequence of *length* ' - 'items.\n' - ' It returns a tuple of three integers; respectively these ' - 'are\n' - ' the *start* and *stop* indices and the *step* or stride\n' - ' length of the slice. Missing or out-of-bounds indices ' - 'are\n' - ' handled in a manner consistent with regular slices.\n' - '\n' - ' Static method objects\n' - ' Static method objects provide a way of defeating the\n' - ' transformation of function objects to method objects ' - 'described\n' - ' above. A static method object is a wrapper around any ' - 'other\n' - ' object, usually a user-defined method object. When a ' - 'static\n' - ' method object is retrieved from a class or a class ' - 'instance, the\n' - ' object actually returned is the wrapped object, which is ' - 'not\n' - ' subject to any further transformation. Static method ' - 'objects are\n' - ' not themselves callable, although the objects they wrap ' - 'usually\n' - ' are. Static method objects are created by the built-in\n' - ' "staticmethod()" constructor.\n' - '\n' - ' Class method objects\n' - ' A class method object, like a static method object, is a ' - 'wrapper\n' - ' around another object that alters the way in which that ' - 'object\n' - ' is retrieved from classes and class instances. The ' - 'behaviour of\n' - ' class method objects upon such retrieval is described ' - 'above,\n' - ' under "User-defined methods". Class method objects are ' - 'created\n' - ' by the built-in "classmethod()" constructor.\n', - 'typesfunctions': '\n' - 'Functions\n' - '*********\n' - '\n' - 'Function objects are created by function definitions. ' - 'The only\n' - 'operation on a function object is to call it: ' - '"func(argument-list)".\n' - '\n' - 'There are really two flavors of function objects: ' - 'built-in functions\n' - 'and user-defined functions. Both support the same ' - 'operation (to call\n' - 'the function), but the implementation is different, ' - 'hence the\n' - 'different object types.\n' - '\n' - 'See *Function definitions* for more information.\n', - 'typesmapping': '\n' - 'Mapping Types --- "dict"\n' - '************************\n' - '\n' - 'A *mapping* object maps *hashable* values to arbitrary ' - 'objects.\n' - 'Mappings are mutable objects. There is currently only one ' - 'standard\n' - 'mapping type, the *dictionary*. (For other containers see ' - 'the built-\n' - 'in "list", "set", and "tuple" classes, and the ' - '"collections" module.)\n' - '\n' - "A dictionary's keys are *almost* arbitrary values. Values " - 'that are\n' - 'not *hashable*, that is, values containing lists, ' - 'dictionaries or\n' - 'other mutable types (that are compared by value rather ' - 'than by object\n' - 'identity) may not be used as keys. Numeric types used for ' - 'keys obey\n' - 'the normal rules for numeric comparison: if two numbers ' - 'compare equal\n' - '(such as "1" and "1.0") then they can be used ' - 'interchangeably to index\n' - 'the same dictionary entry. (Note however, that since ' - 'computers store\n' - 'floating-point numbers as approximations it is usually ' - 'unwise to use\n' - 'them as dictionary keys.)\n' - '\n' - 'Dictionaries can be created by placing a comma-separated ' - 'list of "key:\n' - 'value" pairs within braces, for example: "{\'jack\': 4098, ' - "'sjoerd':\n" - '4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the ' - '"dict"\n' - 'constructor.\n' - '\n' - 'class class dict(**kwarg)\n' - 'class class dict(mapping, **kwarg)\n' - 'class class dict(iterable, **kwarg)\n' - '\n' - ' Return a new dictionary initialized from an optional ' - 'positional\n' - ' argument and a possibly empty set of keyword ' - 'arguments.\n' - '\n' - ' If no positional argument is given, an empty dictionary ' - 'is created.\n' - ' If a positional argument is given and it is a mapping ' - 'object, a\n' - ' dictionary is created with the same key-value pairs as ' - 'the mapping\n' - ' object. Otherwise, the positional argument must be an ' - '*iterable*\n' - ' object. Each item in the iterable must itself be an ' - 'iterable with\n' - ' exactly two objects. The first object of each item ' - 'becomes a key\n' - ' in the new dictionary, and the second object the ' - 'corresponding\n' - ' value. If a key occurs more than once, the last value ' - 'for that key\n' - ' becomes the corresponding value in the new dictionary.\n' - '\n' - ' If keyword arguments are given, the keyword arguments ' - 'and their\n' - ' values are added to the dictionary created from the ' - 'positional\n' - ' argument. If a key being added is already present, the ' - 'value from\n' - ' the keyword argument replaces the value from the ' - 'positional\n' - ' argument.\n' - '\n' - ' To illustrate, the following examples all return a ' - 'dictionary equal\n' - ' to "{"one": 1, "two": 2, "three": 3}":\n' - '\n' - ' >>> a = dict(one=1, two=2, three=3)\n' - " >>> b = {'one': 1, 'two': 2, 'three': 3}\n" - " >>> c = dict(zip(['one', 'two', 'three'], [1, 2, " - '3]))\n' - " >>> d = dict([('two', 2), ('one', 1), ('three', " - '3)])\n' - " >>> e = dict({'three': 3, 'one': 1, 'two': 2})\n" - ' >>> a == b == c == d == e\n' - ' True\n' - '\n' - ' Providing keyword arguments as in the first example ' - 'only works for\n' - ' keys that are valid Python identifiers. Otherwise, any ' - 'valid keys\n' - ' can be used.\n' - '\n' - ' These are the operations that dictionaries support (and ' - 'therefore,\n' - ' custom mapping types should support too):\n' - '\n' - ' len(d)\n' - '\n' - ' Return the number of items in the dictionary *d*.\n' - '\n' - ' d[key]\n' - '\n' - ' Return the item of *d* with key *key*. Raises a ' - '"KeyError" if\n' - ' *key* is not in the map.\n' - '\n' - ' If a subclass of dict defines a method ' - '"__missing__()" and *key*\n' - ' is not present, the "d[key]" operation calls that ' - 'method with\n' - ' the key *key* as argument. The "d[key]" operation ' - 'then returns\n' - ' or raises whatever is returned or raised by the\n' - ' "__missing__(key)" call. No other operations or ' - 'methods invoke\n' - ' "__missing__()". If "__missing__()" is not defined, ' - '"KeyError"\n' - ' is raised. "__missing__()" must be a method; it ' - 'cannot be an\n' - ' instance variable:\n' - '\n' - ' >>> class Counter(dict):\n' - ' ... def __missing__(self, key):\n' - ' ... return 0\n' - ' >>> c = Counter()\n' - " >>> c['red']\n" - ' 0\n' - " >>> c['red'] += 1\n" - " >>> c['red']\n" - ' 1\n' - '\n' - ' The example above shows part of the implementation ' - 'of\n' - ' "collections.Counter". A different "__missing__" ' - 'method is used\n' - ' by "collections.defaultdict".\n' - '\n' - ' d[key] = value\n' - '\n' - ' Set "d[key]" to *value*.\n' - '\n' - ' del d[key]\n' - '\n' - ' Remove "d[key]" from *d*. Raises a "KeyError" if ' - '*key* is not\n' - ' in the map.\n' - '\n' - ' key in d\n' - '\n' - ' Return "True" if *d* has a key *key*, else "False".\n' - '\n' - ' key not in d\n' - '\n' - ' Equivalent to "not key in d".\n' - '\n' - ' iter(d)\n' - '\n' - ' Return an iterator over the keys of the dictionary. ' - 'This is a\n' - ' shortcut for "iter(d.keys())".\n' - '\n' - ' clear()\n' - '\n' - ' Remove all items from the dictionary.\n' - '\n' - ' copy()\n' - '\n' - ' Return a shallow copy of the dictionary.\n' - '\n' - ' classmethod fromkeys(seq[, value])\n' - '\n' - ' Create a new dictionary with keys from *seq* and ' - 'values set to\n' - ' *value*.\n' - '\n' - ' "fromkeys()" is a class method that returns a new ' - 'dictionary.\n' - ' *value* defaults to "None".\n' - '\n' - ' get(key[, default])\n' - '\n' - ' Return the value for *key* if *key* is in the ' - 'dictionary, else\n' - ' *default*. If *default* is not given, it defaults to ' - '"None", so\n' - ' that this method never raises a "KeyError".\n' - '\n' - ' items()\n' - '\n' - ' Return a new view of the dictionary\'s items ("(key, ' - 'value)"\n' - ' pairs). See the *documentation of view objects*.\n' - '\n' - ' keys()\n' - '\n' - " Return a new view of the dictionary's keys. See " - 'the\n' - ' *documentation of view objects*.\n' - '\n' - ' pop(key[, default])\n' - '\n' - ' If *key* is in the dictionary, remove it and return ' - 'its value,\n' - ' else return *default*. If *default* is not given ' - 'and *key* is\n' - ' not in the dictionary, a "KeyError" is raised.\n' - '\n' - ' popitem()\n' - '\n' - ' Remove and return an arbitrary "(key, value)" pair ' - 'from the\n' - ' dictionary.\n' - '\n' - ' "popitem()" is useful to destructively iterate over ' - 'a\n' - ' dictionary, as often used in set algorithms. If the ' - 'dictionary\n' - ' is empty, calling "popitem()" raises a "KeyError".\n' - '\n' - ' setdefault(key[, default])\n' - '\n' - ' If *key* is in the dictionary, return its value. If ' - 'not, insert\n' - ' *key* with a value of *default* and return ' - '*default*. *default*\n' - ' defaults to "None".\n' - '\n' - ' update([other])\n' - '\n' - ' Update the dictionary with the key/value pairs from ' - '*other*,\n' - ' overwriting existing keys. Return "None".\n' - '\n' - ' "update()" accepts either another dictionary object ' - 'or an\n' - ' iterable of key/value pairs (as tuples or other ' - 'iterables of\n' - ' length two). If keyword arguments are specified, ' - 'the dictionary\n' - ' is then updated with those key/value pairs: ' - '"d.update(red=1,\n' - ' blue=2)".\n' - '\n' - ' values()\n' - '\n' - " Return a new view of the dictionary's values. See " - 'the\n' - ' *documentation of view objects*.\n' - '\n' - ' Dictionaries compare equal if and only if they have the ' - 'same "(key,\n' - ' value)" pairs. Order comparisons (\'<\', \'<=\', ' - "'>=', '>') raise\n" - ' "TypeError".\n' - '\n' - 'See also: "types.MappingProxyType" can be used to create a ' - 'read-only\n' - ' view of a "dict".\n' - '\n' - '\n' - 'Dictionary view objects\n' - '=======================\n' - '\n' - 'The objects returned by "dict.keys()", "dict.values()" ' - 'and\n' - '"dict.items()" are *view objects*. They provide a dynamic ' - 'view on the\n' - "dictionary's entries, which means that when the dictionary " - 'changes,\n' - 'the view reflects these changes.\n' - '\n' - 'Dictionary views can be iterated over to yield their ' - 'respective data,\n' - 'and support membership tests:\n' - '\n' - 'len(dictview)\n' - '\n' - ' Return the number of entries in the dictionary.\n' - '\n' - 'iter(dictview)\n' - '\n' - ' Return an iterator over the keys, values or items ' - '(represented as\n' - ' tuples of "(key, value)") in the dictionary.\n' - '\n' - ' Keys and values are iterated over in an arbitrary order ' - 'which is\n' - ' non-random, varies across Python implementations, and ' - 'depends on\n' - " the dictionary's history of insertions and deletions. " - 'If keys,\n' - ' values and items views are iterated over with no ' - 'intervening\n' - ' modifications to the dictionary, the order of items ' - 'will directly\n' - ' correspond. This allows the creation of "(value, key)" ' - 'pairs using\n' - ' "zip()": "pairs = zip(d.values(), d.keys())". Another ' - 'way to\n' - ' create the same list is "pairs = [(v, k) for (k, v) in ' - 'd.items()]".\n' - '\n' - ' Iterating views while adding or deleting entries in the ' - 'dictionary\n' - ' may raise a "RuntimeError" or fail to iterate over all ' - 'entries.\n' - '\n' - 'x in dictview\n' - '\n' - ' Return "True" if *x* is in the underlying dictionary\'s ' - 'keys, values\n' - ' or items (in the latter case, *x* should be a "(key, ' - 'value)"\n' - ' tuple).\n' - '\n' - 'Keys views are set-like since their entries are unique and ' - 'hashable.\n' - 'If all values are hashable, so that "(key, value)" pairs ' - 'are unique\n' - 'and hashable, then the items view is also set-like. ' - '(Values views are\n' - 'not treated as set-like since the entries are generally ' - 'not unique.)\n' - 'For set-like views, all of the operations defined for the ' - 'abstract\n' - 'base class "collections.abc.Set" are available (for ' - 'example, "==",\n' - '"<", or "^").\n' - '\n' - 'An example of dictionary view usage:\n' - '\n' - " >>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, " - "'spam': 500}\n" - ' >>> keys = dishes.keys()\n' - ' >>> values = dishes.values()\n' - '\n' - ' >>> # iteration\n' - ' >>> n = 0\n' - ' >>> for val in values:\n' - ' ... n += val\n' - ' >>> print(n)\n' - ' 504\n' - '\n' - ' >>> # keys and values are iterated over in the same ' - 'order\n' - ' >>> list(keys)\n' - " ['eggs', 'bacon', 'sausage', 'spam']\n" - ' >>> list(values)\n' - ' [2, 1, 1, 500]\n' - '\n' - ' >>> # view objects are dynamic and reflect dict ' - 'changes\n' - " >>> del dishes['eggs']\n" - " >>> del dishes['sausage']\n" - ' >>> list(keys)\n' - " ['spam', 'bacon']\n" - '\n' - ' >>> # set operations\n' - " >>> keys & {'eggs', 'bacon', 'salad'}\n" - " {'bacon'}\n" - " >>> keys ^ {'sausage', 'juice'}\n" - " {'juice', 'sausage', 'bacon', 'spam'}\n", - 'typesmethods': '\n' - 'Methods\n' - '*******\n' - '\n' - 'Methods are functions that are called using the attribute ' - 'notation.\n' - 'There are two flavors: built-in methods (such as ' - '"append()" on lists)\n' - 'and class instance methods. Built-in methods are ' - 'described with the\n' - 'types that support them.\n' - '\n' - 'If you access a method (a function defined in a class ' - 'namespace)\n' - 'through an instance, you get a special object: a *bound ' - 'method* (also\n' - 'called *instance method*) object. When called, it will add ' - 'the "self"\n' - 'argument to the argument list. Bound methods have two ' - 'special read-\n' - 'only attributes: "m.__self__" is the object on which the ' - 'method\n' - 'operates, and "m.__func__" is the function implementing ' - 'the method.\n' - 'Calling "m(arg-1, arg-2, ..., arg-n)" is completely ' - 'equivalent to\n' - 'calling "m.__func__(m.__self__, arg-1, arg-2, ..., ' - 'arg-n)".\n' - '\n' - 'Like function objects, bound method objects support ' - 'getting arbitrary\n' - 'attributes. However, since method attributes are actually ' - 'stored on\n' - 'the underlying function object ("meth.__func__"), setting ' - 'method\n' - 'attributes on bound methods is disallowed. Attempting to ' - 'set an\n' - 'attribute on a method results in an "AttributeError" being ' - 'raised. In\n' - 'order to set a method attribute, you need to explicitly ' - 'set it on the\n' - 'underlying function object:\n' - '\n' - ' >>> class C:\n' - ' ... def method(self):\n' - ' ... pass\n' - ' ...\n' - ' >>> c = C()\n' - " >>> c.method.whoami = 'my name is method' # can't set " - 'on the method\n' - ' Traceback (most recent call last):\n' - ' File "", line 1, in \n' - " AttributeError: 'method' object has no attribute " - "'whoami'\n" - " >>> c.method.__func__.whoami = 'my name is method'\n" - ' >>> c.method.whoami\n' - " 'my name is method'\n" - '\n' - 'See *The standard type hierarchy* for more information.\n', - 'typesmodules': '\n' - 'Modules\n' - '*******\n' - '\n' - 'The only special operation on a module is attribute ' - 'access: "m.name",\n' - 'where *m* is a module and *name* accesses a name defined ' - "in *m*'s\n" - 'symbol table. Module attributes can be assigned to. (Note ' - 'that the\n' - '"import" statement is not, strictly speaking, an operation ' - 'on a module\n' - 'object; "import foo" does not require a module object ' - 'named *foo* to\n' - 'exist, rather it requires an (external) *definition* for a ' - 'module\n' - 'named *foo* somewhere.)\n' - '\n' - 'A special attribute of every module is "__dict__". This is ' - 'the\n' - "dictionary containing the module's symbol table. Modifying " - 'this\n' - "dictionary will actually change the module's symbol table, " - 'but direct\n' - 'assignment to the "__dict__" attribute is not possible ' - '(you can write\n' - '"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", ' - "but you can't\n" - 'write "m.__dict__ = {}"). Modifying "__dict__" directly ' - 'is not\n' - 'recommended.\n' - '\n' - 'Modules built into the interpreter are written like this: ' - '"". If loaded from a file, they are ' - 'written as\n' - '"".\n', - 'typesseq': '\n' - 'Sequence Types --- "list", "tuple", "range"\n' - '*******************************************\n' - '\n' - 'There are three basic sequence types: lists, tuples, and ' - 'range\n' - 'objects. Additional sequence types tailored for processing of ' - '*binary\n' - 'data* and *text strings* are described in dedicated sections.\n' - '\n' - '\n' - 'Common Sequence Operations\n' - '==========================\n' - '\n' - 'The operations in the following table are supported by most ' - 'sequence\n' - 'types, both mutable and immutable. The ' - '"collections.abc.Sequence" ABC\n' - 'is provided to make it easier to correctly implement these ' - 'operations\n' - 'on custom sequence types.\n' - '\n' - 'This table lists the sequence operations sorted in ascending ' - 'priority.\n' - 'In the table, *s* and *t* are sequences of the same type, *n*, ' - '*i*,\n' - '*j* and *k* are integers and *x* is an arbitrary object that ' - 'meets any\n' - 'type and value restrictions imposed by *s*.\n' - '\n' - 'The "in" and "not in" operations have the same priorities as ' - 'the\n' - 'comparison operations. The "+" (concatenation) and "*" ' - '(repetition)\n' - 'operations have the same priority as the corresponding ' - 'numeric\n' - 'operations.\n' - '\n' - '+----------------------------+----------------------------------+------------+\n' - '| Operation | ' - 'Result | Notes |\n' - '+============================+==================================+============+\n' - '| "x in s" | "True" if an item of *s* ' - 'is | (1) |\n' - '| | equal to *x*, else ' - '"False" | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "x not in s" | "False" if an item of *s* ' - 'is | (1) |\n' - '| | equal to *x*, else ' - '"True" | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s + t" | the concatenation of *s* and ' - '*t* | (6)(7) |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s * n" or "n * s" | *n* shallow copies of ' - '*s* | (2)(7) |\n' - '| | ' - 'concatenated | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s[i]" | *i*th item of *s*, origin ' - '0 | (3) |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s[i:j]" | slice of *s* from *i* to ' - '*j* | (3)(4) |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s[i:j:k]" | slice of *s* from *i* to ' - '*j* | (3)(5) |\n' - '| | with step ' - '*k* | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "len(s)" | length of ' - '*s* | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "min(s)" | smallest item of ' - '*s* | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "max(s)" | largest item of ' - '*s* | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s.index(x[, i[, j]])" | index of the first occurrence ' - 'of | (8) |\n' - '| | *x* in *s* (at or after ' - 'index | |\n' - '| | *i* and before index ' - '*j*) | |\n' - '+----------------------------+----------------------------------+------------+\n' - '| "s.count(x)" | total number of occurrences ' - 'of | |\n' - '| | *x* in ' - '*s* | |\n' - '+----------------------------+----------------------------------+------------+\n' - '\n' - 'Sequences of the same type also support comparisons. In ' - 'particular,\n' - 'tuples and lists are compared lexicographically by comparing\n' - 'corresponding elements. This means that to compare equal, ' - 'every\n' - 'element must compare equal and the two sequences must be of ' - 'the same\n' - 'type and have the same length. (For full details see ' - '*Comparisons* in\n' - 'the language reference.)\n' - '\n' - 'Notes:\n' - '\n' - '1. While the "in" and "not in" operations are used only for ' - 'simple\n' - ' containment testing in the general case, some specialised ' - 'sequences\n' - ' (such as "str", "bytes" and "bytearray") also use them for\n' - ' subsequence testing:\n' - '\n' - ' >>> "gg" in "eggs"\n' - ' True\n' - '\n' - '2. Values of *n* less than "0" are treated as "0" (which ' - 'yields an\n' - ' empty sequence of the same type as *s*). Note also that ' - 'the copies\n' - ' are shallow; nested structures are not copied. This often ' - 'haunts\n' - ' new Python programmers; consider:\n' - '\n' - ' >>> lists = [[]] * 3\n' - ' >>> lists\n' - ' [[], [], []]\n' - ' >>> lists[0].append(3)\n' - ' >>> lists\n' - ' [[3], [3], [3]]\n' - '\n' - ' What has happened is that "[[]]" is a one-element list ' - 'containing\n' - ' an empty list, so all three elements of "[[]] * 3" are ' - '(pointers\n' - ' to) this single empty list. Modifying any of the elements ' - 'of\n' - ' "lists" modifies this single list. You can create a list ' - 'of\n' - ' different lists this way:\n' - '\n' - ' >>> lists = [[] for i in range(3)]\n' - ' >>> lists[0].append(3)\n' - ' >>> lists[1].append(5)\n' - ' >>> lists[2].append(7)\n' - ' >>> lists\n' - ' [[3], [5], [7]]\n' - '\n' - '3. If *i* or *j* is negative, the index is relative to the end ' - 'of\n' - ' the string: "len(s) + i" or "len(s) + j" is substituted. ' - 'But note\n' - ' that "-0" is still "0".\n' - '\n' - '4. The slice of *s* from *i* to *j* is defined as the sequence ' - 'of\n' - ' items with index *k* such that "i <= k < j". If *i* or *j* ' - 'is\n' - ' greater than "len(s)", use "len(s)". If *i* is omitted or ' - '"None",\n' - ' use "0". If *j* is omitted or "None", use "len(s)". If ' - '*i* is\n' - ' greater than or equal to *j*, the slice is empty.\n' - '\n' - '5. The slice of *s* from *i* to *j* with step *k* is defined ' - 'as the\n' - ' sequence of items with index "x = i + n*k" such that "0 <= ' - 'n <\n' - ' (j-i)/k". In other words, the indices are "i", "i+k", ' - '"i+2*k",\n' - ' "i+3*k" and so on, stopping when *j* is reached (but never\n' - ' including *j*). If *i* or *j* is greater than "len(s)", ' - 'use\n' - ' "len(s)". If *i* or *j* are omitted or "None", they become ' - '"end"\n' - ' values (which end depends on the sign of *k*). Note, *k* ' - 'cannot be\n' - ' zero. If *k* is "None", it is treated like "1".\n' - '\n' - '6. Concatenating immutable sequences always results in a new\n' - ' object. This means that building up a sequence by repeated\n' - ' concatenation will have a quadratic runtime cost in the ' - 'total\n' - ' sequence length. To get a linear runtime cost, you must ' - 'switch to\n' - ' one of the alternatives below:\n' - '\n' - ' * if concatenating "str" objects, you can build a list and ' - 'use\n' - ' "str.join()" at the end or else write to a "io.StringIO" ' - 'instance\n' - ' and retrieve its value when complete\n' - '\n' - ' * if concatenating "bytes" objects, you can similarly use\n' - ' "bytes.join()" or "io.BytesIO", or you can do in-place\n' - ' concatenation with a "bytearray" object. "bytearray" ' - 'objects are\n' - ' mutable and have an efficient overallocation mechanism\n' - '\n' - ' * if concatenating "tuple" objects, extend a "list" ' - 'instead\n' - '\n' - ' * for other types, investigate the relevant class ' - 'documentation\n' - '\n' - '7. Some sequence types (such as "range") only support item\n' - " sequences that follow specific patterns, and hence don't " - 'support\n' - ' sequence concatenation or repetition.\n' - '\n' - '8. "index" raises "ValueError" when *x* is not found in *s*. ' - 'When\n' - ' supported, the additional arguments to the index method ' - 'allow\n' - ' efficient searching of subsections of the sequence. Passing ' - 'the\n' - ' extra arguments is roughly equivalent to using ' - '"s[i:j].index(x)",\n' - ' only without copying any data and with the returned index ' - 'being\n' - ' relative to the start of the sequence rather than the start ' - 'of the\n' - ' slice.\n' - '\n' - '\n' - 'Immutable Sequence Types\n' - '========================\n' - '\n' - 'The only operation that immutable sequence types generally ' - 'implement\n' - 'that is not also implemented by mutable sequence types is ' - 'support for\n' - 'the "hash()" built-in.\n' - '\n' - 'This support allows immutable sequences, such as "tuple" ' - 'instances, to\n' - 'be used as "dict" keys and stored in "set" and "frozenset" ' - 'instances.\n' - '\n' - 'Attempting to hash an immutable sequence that contains ' - 'unhashable\n' - 'values will result in "TypeError".\n' - '\n' - '\n' - 'Mutable Sequence Types\n' - '======================\n' - '\n' - 'The operations in the following table are defined on mutable ' - 'sequence\n' - 'types. The "collections.abc.MutableSequence" ABC is provided ' - 'to make\n' - 'it easier to correctly implement these operations on custom ' - 'sequence\n' - 'types.\n' - '\n' - 'In the table *s* is an instance of a mutable sequence type, ' - '*t* is any\n' - 'iterable object and *x* is an arbitrary object that meets any ' - 'type and\n' - 'value restrictions imposed by *s* (for example, "bytearray" ' - 'only\n' - 'accepts integers that meet the value restriction "0 <= x <= ' - '255").\n' - '\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| Operation | ' - 'Result | Notes |\n' - '+================================+==================================+=======================+\n' - '| "s[i] = x" | item *i* of *s* is replaced ' - 'by | |\n' - '| | ' - '*x* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s[i:j] = t" | slice of *s* from *i* to ' - '*j* is | |\n' - '| | replaced by the contents of ' - 'the | |\n' - '| | iterable ' - '*t* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "del s[i:j]" | same as "s[i:j] = ' - '[]" | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s[i:j:k] = t" | the elements of "s[i:j:k]" ' - 'are | (1) |\n' - '| | replaced by those of ' - '*t* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "del s[i:j:k]" | removes the elements ' - 'of | |\n' - '| | "s[i:j:k]" from the ' - 'list | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.append(x)" | appends *x* to the end of ' - 'the | |\n' - '| | sequence (same ' - 'as | |\n' - '| | "s[len(s):len(s)] = ' - '[x]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.clear()" | removes all items from "s" ' - '(same | (5) |\n' - '| | as "del ' - 's[:]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.copy()" | creates a shallow copy of ' - '"s" | (5) |\n' - '| | (same as ' - '"s[:]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.extend(t)" | extends *s* with the ' - 'contents of | |\n' - '| | *t* (same as ' - '"s[len(s):len(s)] = | |\n' - '| | ' - 't") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.insert(i, x)" | inserts *x* into *s* at ' - 'the | |\n' - '| | index given by *i* (same ' - 'as | |\n' - '| | "s[i:i] = ' - '[x]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.pop([i])" | retrieves the item at *i* ' - 'and | (2) |\n' - '| | also removes it from ' - '*s* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.remove(x)" | remove the first item from ' - '*s* | (3) |\n' - '| | where "s[i] == ' - 'x" | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.reverse()" | reverses the items of *s* ' - 'in | (4) |\n' - '| | ' - 'place | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '\n' - 'Notes:\n' - '\n' - '1. *t* must have the same length as the slice it is ' - 'replacing.\n' - '\n' - '2. The optional argument *i* defaults to "-1", so that by ' - 'default\n' - ' the last item is removed and returned.\n' - '\n' - '3. "remove" raises "ValueError" when *x* is not found in *s*.\n' - '\n' - '4. The "reverse()" method modifies the sequence in place for\n' - ' economy of space when reversing a large sequence. To ' - 'remind users\n' - ' that it operates by side effect, it does not return the ' - 'reversed\n' - ' sequence.\n' - '\n' - '5. "clear()" and "copy()" are included for consistency with ' - 'the\n' - " interfaces of mutable containers that don't support " - 'slicing\n' - ' operations (such as "dict" and "set")\n' - '\n' - ' New in version 3.3: "clear()" and "copy()" methods.\n' - '\n' - '\n' - 'Lists\n' - '=====\n' - '\n' - 'Lists are mutable sequences, typically used to store ' - 'collections of\n' - 'homogeneous items (where the precise degree of similarity will ' - 'vary by\n' - 'application).\n' - '\n' - 'class class list([iterable])\n' - '\n' - ' Lists may be constructed in several ways:\n' - '\n' - ' * Using a pair of square brackets to denote the empty list: ' - '"[]"\n' - '\n' - ' * Using square brackets, separating items with commas: ' - '"[a]",\n' - ' "[a, b, c]"\n' - '\n' - ' * Using a list comprehension: "[x for x in iterable]"\n' - '\n' - ' * Using the type constructor: "list()" or "list(iterable)"\n' - '\n' - ' The constructor builds a list whose items are the same and ' - 'in the\n' - " same order as *iterable*'s items. *iterable* may be either " - 'a\n' - ' sequence, a container that supports iteration, or an ' - 'iterator\n' - ' object. If *iterable* is already a list, a copy is made ' - 'and\n' - ' returned, similar to "iterable[:]". For example, ' - '"list(\'abc\')"\n' - ' returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" ' - 'returns "[1, 2,\n' - ' 3]". If no argument is given, the constructor creates a new ' - 'empty\n' - ' list, "[]".\n' - '\n' - ' Many other operations also produce lists, including the ' - '"sorted()"\n' - ' built-in.\n' - '\n' - ' Lists implement all of the *common* and *mutable* sequence\n' - ' operations. Lists also provide the following additional ' - 'method:\n' - '\n' - ' sort(*, key=None, reverse=None)\n' - '\n' - ' This method sorts the list in place, using only "<" ' - 'comparisons\n' - ' between items. Exceptions are not suppressed - if any ' - 'comparison\n' - ' operations fail, the entire sort operation will fail ' - '(and the\n' - ' list will likely be left in a partially modified ' - 'state).\n' - '\n' - ' "sort()" accepts two arguments that can only be passed ' - 'by\n' - ' keyword (*keyword-only arguments*):\n' - '\n' - ' *key* specifies a function of one argument that is used ' - 'to\n' - ' extract a comparison key from each list element (for ' - 'example,\n' - ' "key=str.lower"). The key corresponding to each item in ' - 'the list\n' - ' is calculated once and then used for the entire sorting ' - 'process.\n' - ' The default value of "None" means that list items are ' - 'sorted\n' - ' directly without calculating a separate key value.\n' - '\n' - ' The "functools.cmp_to_key()" utility is available to ' - 'convert a\n' - ' 2.x style *cmp* function to a *key* function.\n' - '\n' - ' *reverse* is a boolean value. If set to "True", then ' - 'the list\n' - ' elements are sorted as if each comparison were ' - 'reversed.\n' - '\n' - ' This method modifies the sequence in place for economy ' - 'of space\n' - ' when sorting a large sequence. To remind users that it ' - 'operates\n' - ' by side effect, it does not return the sorted sequence ' - '(use\n' - ' "sorted()" to explicitly request a new sorted list ' - 'instance).\n' - '\n' - ' The "sort()" method is guaranteed to be stable. A sort ' - 'is\n' - ' stable if it guarantees not to change the relative order ' - 'of\n' - ' elements that compare equal --- this is helpful for ' - 'sorting in\n' - ' multiple passes (for example, sort by department, then ' - 'by salary\n' - ' grade).\n' - '\n' - ' **CPython implementation detail:** While a list is being ' - 'sorted,\n' - ' the effect of attempting to mutate, or even inspect, the ' - 'list is\n' - ' undefined. The C implementation of Python makes the ' - 'list appear\n' - ' empty for the duration, and raises "ValueError" if it ' - 'can detect\n' - ' that the list has been mutated during a sort.\n' - '\n' - '\n' - 'Tuples\n' - '======\n' - '\n' - 'Tuples are immutable sequences, typically used to store ' - 'collections of\n' - 'heterogeneous data (such as the 2-tuples produced by the ' - '"enumerate()"\n' - 'built-in). Tuples are also used for cases where an immutable ' - 'sequence\n' - 'of homogeneous data is needed (such as allowing storage in a ' - '"set" or\n' - '"dict" instance).\n' - '\n' - 'class class tuple([iterable])\n' - '\n' - ' Tuples may be constructed in a number of ways:\n' - '\n' - ' * Using a pair of parentheses to denote the empty tuple: ' - '"()"\n' - '\n' - ' * Using a trailing comma for a singleton tuple: "a," or ' - '"(a,)"\n' - '\n' - ' * Separating items with commas: "a, b, c" or "(a, b, c)"\n' - '\n' - ' * Using the "tuple()" built-in: "tuple()" or ' - '"tuple(iterable)"\n' - '\n' - ' The constructor builds a tuple whose items are the same and ' - 'in the\n' - " same order as *iterable*'s items. *iterable* may be either " - 'a\n' - ' sequence, a container that supports iteration, or an ' - 'iterator\n' - ' object. If *iterable* is already a tuple, it is returned\n' - ' unchanged. For example, "tuple(\'abc\')" returns "(\'a\', ' - '\'b\', \'c\')"\n' - ' and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no ' - 'argument is\n' - ' given, the constructor creates a new empty tuple, "()".\n' - '\n' - ' Note that it is actually the comma which makes a tuple, not ' - 'the\n' - ' parentheses. The parentheses are optional, except in the ' - 'empty\n' - ' tuple case, or when they are needed to avoid syntactic ' - 'ambiguity.\n' - ' For example, "f(a, b, c)" is a function call with three ' - 'arguments,\n' - ' while "f((a, b, c))" is a function call with a 3-tuple as ' - 'the sole\n' - ' argument.\n' - '\n' - ' Tuples implement all of the *common* sequence operations.\n' - '\n' - 'For heterogeneous collections of data where access by name is ' - 'clearer\n' - 'than access by index, "collections.namedtuple()" may be a ' - 'more\n' - 'appropriate choice than a simple tuple object.\n' - '\n' - '\n' - 'Ranges\n' - '======\n' - '\n' - 'The "range" type represents an immutable sequence of numbers ' - 'and is\n' - 'commonly used for looping a specific number of times in "for" ' - 'loops.\n' - '\n' - 'class class range(stop)\n' - 'class class range(start, stop[, step])\n' - '\n' - ' The arguments to the range constructor must be integers ' - '(either\n' - ' built-in "int" or any object that implements the ' - '"__index__"\n' - ' special method). If the *step* argument is omitted, it ' - 'defaults to\n' - ' "1". If the *start* argument is omitted, it defaults to ' - '"0". If\n' - ' *step* is zero, "ValueError" is raised.\n' - '\n' - ' For a positive *step*, the contents of a range "r" are ' - 'determined\n' - ' by the formula "r[i] = start + step*i" where "i >= 0" and ' - '"r[i] <\n' - ' stop".\n' - '\n' - ' For a negative *step*, the contents of the range are still\n' - ' determined by the formula "r[i] = start + step*i", but the\n' - ' constraints are "i >= 0" and "r[i] > stop".\n' - '\n' - ' A range object will be empty if "r[0]" does not meet the ' - 'value\n' - ' constraint. Ranges do support negative indices, but these ' - 'are\n' - ' interpreted as indexing from the end of the sequence ' - 'determined by\n' - ' the positive indices.\n' - '\n' - ' Ranges containing absolute values larger than "sys.maxsize" ' - 'are\n' - ' permitted but some features (such as "len()") may raise\n' - ' "OverflowError".\n' - '\n' - ' Range examples:\n' - '\n' - ' >>> list(range(10))\n' - ' [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n' - ' >>> list(range(1, 11))\n' - ' [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n' - ' >>> list(range(0, 30, 5))\n' - ' [0, 5, 10, 15, 20, 25]\n' - ' >>> list(range(0, 10, 3))\n' - ' [0, 3, 6, 9]\n' - ' >>> list(range(0, -10, -1))\n' - ' [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n' - ' >>> list(range(0))\n' - ' []\n' - ' >>> list(range(1, 0))\n' - ' []\n' - '\n' - ' Ranges implement all of the *common* sequence operations ' - 'except\n' - ' concatenation and repetition (due to the fact that range ' - 'objects\n' - ' can only represent sequences that follow a strict pattern ' - 'and\n' - ' repetition and concatenation will usually violate that ' - 'pattern).\n' - '\n' - 'The advantage of the "range" type over a regular "list" or ' - '"tuple" is\n' - 'that a "range" object will always take the same (small) amount ' - 'of\n' - 'memory, no matter the size of the range it represents (as it ' - 'only\n' - 'stores the "start", "stop" and "step" values, calculating ' - 'individual\n' - 'items and subranges as needed).\n' - '\n' - 'Range objects implement the "collections.abc.Sequence" ABC, ' - 'and\n' - 'provide features such as containment tests, element index ' - 'lookup,\n' - 'slicing and support for negative indices (see *Sequence Types ' - '---\n' - 'list, tuple, range*):\n' - '\n' - '>>> r = range(0, 20, 2)\n' - '>>> r\n' - 'range(0, 20, 2)\n' - '>>> 11 in r\n' - 'False\n' - '>>> 10 in r\n' - 'True\n' - '>>> r.index(10)\n' - '5\n' - '>>> r[5]\n' - '10\n' - '>>> r[:5]\n' - 'range(0, 10, 2)\n' - '>>> r[-1]\n' - '18\n' - '\n' - 'Testing range objects for equality with "==" and "!=" compares ' - 'them as\n' - 'sequences. That is, two range objects are considered equal if ' - 'they\n' - 'represent the same sequence of values. (Note that two range ' - 'objects\n' - 'that compare equal might have different "start", "stop" and ' - '"step"\n' - 'attributes, for example "range(0) == range(2, 1, 3)" or ' - '"range(0, 3,\n' - '2) == range(0, 4, 2)".)\n' - '\n' - 'Changed in version 3.2: Implement the Sequence ABC. Support ' - 'slicing\n' - 'and negative indices. Test "int" objects for membership in ' - 'constant\n' - 'time instead of iterating through all items.\n' - '\n' - "Changed in version 3.3: Define '==' and '!=' to compare range " - 'objects\n' - 'based on the sequence of values they define (instead of ' - 'comparing\n' - 'based on object identity).\n' - '\n' - 'New in version 3.3: The "start", "stop" and "step" ' - 'attributes.\n', - 'typesseq-mutable': '\n' - 'Mutable Sequence Types\n' - '**********************\n' - '\n' - 'The operations in the following table are defined on ' - 'mutable sequence\n' - 'types. The "collections.abc.MutableSequence" ABC is ' - 'provided to make\n' - 'it easier to correctly implement these operations on ' - 'custom sequence\n' - 'types.\n' - '\n' - 'In the table *s* is an instance of a mutable sequence ' - 'type, *t* is any\n' - 'iterable object and *x* is an arbitrary object that ' - 'meets any type and\n' - 'value restrictions imposed by *s* (for example, ' - '"bytearray" only\n' - 'accepts integers that meet the value restriction "0 <= ' - 'x <= 255").\n' - '\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| Operation | ' - 'Result | ' - 'Notes |\n' - '+================================+==================================+=======================+\n' - '| "s[i] = x" | item *i* of *s* is ' - 'replaced by | |\n' - '| | ' - '*x* ' - '| |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s[i:j] = t" | slice of *s* from ' - '*i* to *j* is | |\n' - '| | replaced by the ' - 'contents of the | |\n' - '| | iterable ' - '*t* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "del s[i:j]" | same as "s[i:j] = ' - '[]" | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s[i:j:k] = t" | the elements of ' - '"s[i:j:k]" are | (1) |\n' - '| | replaced by those ' - 'of *t* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "del s[i:j:k]" | removes the ' - 'elements of | |\n' - '| | "s[i:j:k]" from the ' - 'list | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.append(x)" | appends *x* to the ' - 'end of the | |\n' - '| | sequence (same ' - 'as | |\n' - '| | "s[len(s):len(s)] = ' - '[x]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.clear()" | removes all items ' - 'from "s" (same | (5) |\n' - '| | as "del ' - 's[:]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.copy()" | creates a shallow ' - 'copy of "s" | (5) |\n' - '| | (same as ' - '"s[:]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.extend(t)" | extends *s* with ' - 'the contents of | |\n' - '| | *t* (same as ' - '"s[len(s):len(s)] = | |\n' - '| | ' - 't") ' - '| |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.insert(i, x)" | inserts *x* into ' - '*s* at the | |\n' - '| | index given by *i* ' - '(same as | |\n' - '| | "s[i:i] = ' - '[x]") | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.pop([i])" | retrieves the item ' - 'at *i* and | (2) |\n' - '| | also removes it ' - 'from *s* | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.remove(x)" | remove the first ' - 'item from *s* | (3) |\n' - '| | where "s[i] == ' - 'x" | |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '| "s.reverse()" | reverses the items ' - 'of *s* in | (4) |\n' - '| | ' - 'place ' - '| |\n' - '+--------------------------------+----------------------------------+-----------------------+\n' - '\n' - 'Notes:\n' - '\n' - '1. *t* must have the same length as the slice it is ' - 'replacing.\n' - '\n' - '2. The optional argument *i* defaults to "-1", so that ' - 'by default\n' - ' the last item is removed and returned.\n' - '\n' - '3. "remove" raises "ValueError" when *x* is not found ' - 'in *s*.\n' - '\n' - '4. The "reverse()" method modifies the sequence in ' - 'place for\n' - ' economy of space when reversing a large sequence. ' - 'To remind users\n' - ' that it operates by side effect, it does not return ' - 'the reversed\n' - ' sequence.\n' - '\n' - '5. "clear()" and "copy()" are included for consistency ' - 'with the\n' - " interfaces of mutable containers that don't support " - 'slicing\n' - ' operations (such as "dict" and "set")\n' - '\n' - ' New in version 3.3: "clear()" and "copy()" ' - 'methods.\n', - 'unary': '\n' - 'Unary arithmetic and bitwise operations\n' - '***************************************\n' - '\n' - 'All unary arithmetic and bitwise operations have the same ' - 'priority:\n' - '\n' - ' u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n' - '\n' - 'The unary "-" (minus) operator yields the negation of its ' - 'numeric\n' - 'argument.\n' - '\n' - 'The unary "+" (plus) operator yields its numeric argument ' - 'unchanged.\n' - '\n' - 'The unary "~" (invert) operator yields the bitwise inversion of ' - 'its\n' - 'integer argument. The bitwise inversion of "x" is defined as\n' - '"-(x+1)". It only applies to integral numbers.\n' - '\n' - 'In all three cases, if the argument does not have the proper ' - 'type, a\n' - '"TypeError" exception is raised.\n', - 'while': '\n' - 'The "while" statement\n' - '*********************\n' - '\n' - 'The "while" statement is used for repeated execution as long as ' - 'an\n' - 'expression is true:\n' - '\n' - ' while_stmt ::= "while" expression ":" suite\n' - ' ["else" ":" suite]\n' - '\n' - 'This repeatedly tests the expression and, if it is true, executes ' - 'the\n' - 'first suite; if the expression is false (which may be the first ' - 'time\n' - 'it is tested) the suite of the "else" clause, if present, is ' - 'executed\n' - 'and the loop terminates.\n' - '\n' - 'A "break" statement executed in the first suite terminates the ' - 'loop\n' - 'without executing the "else" clause\'s suite. A "continue" ' - 'statement\n' - 'executed in the first suite skips the rest of the suite and goes ' - 'back\n' - 'to testing the expression.\n', - 'with': '\n' - 'The "with" statement\n' - '********************\n' - '\n' - 'The "with" statement is used to wrap the execution of a block ' - 'with\n' - 'methods defined by a context manager (see section *With Statement\n' - 'Context Managers*). This allows common ' - '"try"..."except"..."finally"\n' - 'usage patterns to be encapsulated for convenient reuse.\n' - '\n' - ' with_stmt ::= "with" with_item ("," with_item)* ":" suite\n' - ' with_item ::= expression ["as" target]\n' - '\n' - 'The execution of the "with" statement with one "item" proceeds as\n' - 'follows:\n' - '\n' - '1. The context expression (the expression given in the ' - '"with_item")\n' - ' is evaluated to obtain a context manager.\n' - '\n' - '2. The context manager\'s "__exit__()" is loaded for later use.\n' - '\n' - '3. The context manager\'s "__enter__()" method is invoked.\n' - '\n' - '4. If a target was included in the "with" statement, the return\n' - ' value from "__enter__()" is assigned to it.\n' - '\n' - ' Note: The "with" statement guarantees that if the ' - '"__enter__()"\n' - ' method returns without an error, then "__exit__()" will ' - 'always be\n' - ' called. Thus, if an error occurs during the assignment to ' - 'the\n' - ' target list, it will be treated the same as an error ' - 'occurring\n' - ' within the suite would be. See step 6 below.\n' - '\n' - '5. The suite is executed.\n' - '\n' - '6. The context manager\'s "__exit__()" method is invoked. If an\n' - ' exception caused the suite to be exited, its type, value, and\n' - ' traceback are passed as arguments to "__exit__()". Otherwise, ' - 'three\n' - ' "None" arguments are supplied.\n' - '\n' - ' If the suite was exited due to an exception, and the return ' - 'value\n' - ' from the "__exit__()" method was false, the exception is ' - 'reraised.\n' - ' If the return value was true, the exception is suppressed, and\n' - ' execution continues with the statement following the "with"\n' - ' statement.\n' - '\n' - ' If the suite was exited for any reason other than an exception, ' - 'the\n' - ' return value from "__exit__()" is ignored, and execution ' - 'proceeds\n' - ' at the normal location for the kind of exit that was taken.\n' - '\n' - 'With more than one item, the context managers are processed as if\n' - 'multiple "with" statements were nested:\n' - '\n' - ' with A() as a, B() as b:\n' - ' suite\n' - '\n' - 'is equivalent to\n' - '\n' - ' with A() as a:\n' - ' with B() as b:\n' - ' suite\n' - '\n' - 'Changed in version 3.1: Support for multiple context expressions.\n' - '\n' - 'See also: **PEP 0343** - The "with" statement\n' - '\n' - ' The specification, background, and examples for the Python ' - '"with"\n' - ' statement.\n', - 'yield': '\n' - 'The "yield" statement\n' - '*********************\n' - '\n' - ' yield_stmt ::= yield_expression\n' - '\n' - 'A "yield" statement is semantically equivalent to a *yield\n' - 'expression*. The yield statement can be used to omit the ' - 'parentheses\n' - 'that would otherwise be required in the equivalent yield ' - 'expression\n' - 'statement. For example, the yield statements\n' - '\n' - ' yield \n' - ' yield from \n' - '\n' - 'are equivalent to the yield expression statements\n' - '\n' - ' (yield )\n' - ' (yield from )\n' - '\n' - 'Yield expressions and statements are only used when defining a\n' - '*generator* function, and are only used in the body of the ' - 'generator\n' - 'function. Using yield in a function definition is sufficient to ' - 'cause\n' - 'that definition to create a generator function instead of a ' - 'normal\n' - 'function.\n' - '\n' - 'For full details of "yield" semantics, refer to the *Yield\n' - 'expressions* section.\n'} +# Autogenerated by Sphinx on Sat Nov 21 23:47:52 2015 +topics = {'assert': u'\nThe "assert" statement\n**********************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, "assert expression", is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, "assert expression1, expression2", is equivalent to\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that "__debug__" and "AssertionError" refer\nto the built-in variables with those names. In the current\nimplementation, the built-in variable "__debug__" is "True" under\nnormal circumstances, "False" when optimization is requested (command\nline option -O). The current code generator emits no code for an\nassert statement when optimization is requested at compile time. Note\nthat it is unnecessary to include the source code for the expression\nthat failed in the error message; it will be displayed as part of the\nstack trace.\n\nAssignments to "__debug__" are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n', + 'assignment': u'\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for\n*attributeref*, *subscription*, and *slicing*.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The\n object must be an iterable with the same number of items as there\n are targets in the target list, and the items are assigned, from\n left to right, to the corresponding targets.\n\n * If the target list contains one target prefixed with an\n asterisk, called a "starred" target: The object must be a sequence\n with at least as many items as there are targets in the target\n list, minus one. The first items of the sequence are assigned,\n from left to right, to the targets before the starred target. The\n final items of the sequence are assigned to the targets after the\n starred target. A list of the remaining items in the sequence is\n then assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of\n items as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a "global" or "nonlocal" statement\n in the current code block: the name is bound to the object in the\n current local namespace.\n\n * Otherwise: the name is bound to the object in the global\n namespace or the outer namespace determined by "nonlocal",\n respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in\n square brackets: The object must be an iterable with the same number\n of items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, "TypeError" is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily "AttributeError").\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n "a.x" can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target "a.x" is always\n set as an instance attribute, creating it if necessary. Thus, the\n two occurrences of "a.x" do not necessarily refer to the same\n attribute: if the RHS expression refers to a class attribute, the\n LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with "property()".\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, "IndexError" is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the "__setitem__()" method is called with\n appropriate arguments.\n\n* If the target is a slicing: The primary expression in the\n reference is evaluated. It should yield a mutable sequence object\n (such as a list). The assigned object should be a sequence object\n of the same type. Next, the lower and upper bound expressions are\n evaluated, insofar they are present; defaults are zero and the\n sequence\'s length. The bounds should evaluate to integers. If\n either bound is negative, the sequence\'s length is added to it. The\n resulting bounds are clipped to lie between zero and the sequence\'s\n length, inclusive. Finally, the sequence object is asked to replace\n the slice with the items of the assigned sequence. The length of\n the slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the target\n sequence allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nAlthough the definition of assignment implies that overlaps between\nthe left-hand side and the right-hand side are \'simultanenous\' (for\nexample "a, b = b, a" swaps two variables), overlaps *within* the\ncollection of assigned-to variables occur left-to-right, sometimes\nresulting in confusion. For instance, the following program prints\n"[0, 2]":\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2 # i is updated, then x[i] is updated\n print(x)\n\nSee also: **PEP 3132** - Extended Iterable Unpacking\n\n The specification for the "*target" feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'atom-identifiers': u'\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a "NameError" exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name, with leading underscores removed and a single underscore\ninserted, in front of the name. For example, the identifier "__spam"\noccurring in a class named "Ham" will be transformed to "_Ham__spam".\nThis transformation is independent of the syntactical context in which\nthe identifier is used. If the transformed name is extremely long\n(longer than 255 characters), implementation defined truncation may\nhappen. If the class name consists only of underscores, no\ntransformation is done.\n', + 'atom-literals': u"\nLiterals\n********\n\nPython supports string and bytes literals and various numeric\nliterals:\n\n literal ::= stringliteral | bytesliteral\n | integer | floatnumber | imagnumber\n\nEvaluation of a literal yields an object of the given type (string,\nbytes, integer, floating point number, complex number) with the given\nvalue. The value may be approximated in the case of floating point\nand imaginary (complex) literals. See section *Literals* for details.\n\nAll literals correspond to immutable data types, and hence the\nobject's identity is less important than its value. Multiple\nevaluations of literals with the same value (either the same\noccurrence in the program text or a different occurrence) may obtain\nthe same object or a different object with the same value.\n", + 'attribute-access': u'\nCustomizing attribute access\n****************************\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n========================\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n====================\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n=========\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n--------------------------\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n', + 'attribute-references': u'\nAttribute references\n********************\n\nAn attribute reference is a primary followed by a period and a name:\n\n attributeref ::= primary "." identifier\n\nThe primary must evaluate to an object of a type that supports\nattribute references, which most objects do. This object is then\nasked to produce the attribute whose name is the identifier. This\nproduction can be customized by overriding the "__getattr__()" method.\nIf this attribute is not available, the exception "AttributeError" is\nraised. Otherwise, the type and value of the object produced is\ndetermined by the object. Multiple evaluations of the same attribute\nreference may yield different objects.\n', + 'augassign': u'\nAugmented assignment statements\n*******************************\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "@=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions of the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like "x += 1" can be rewritten as\n"x = x + 1" to achieve a similar, but not exactly equal effect. In the\naugmented version, "x" is only evaluated once. Also, when possible,\nthe actual operation is performed *in-place*, meaning that rather than\ncreating a new object and assigning that to the target, the old object\nis modified instead.\n\nUnlike normal assignments, augmented assignments evaluate the left-\nhand side *before* evaluating the right-hand side. For example, "a[i]\n+= f(x)" first looks-up "a[i]", then it evaluates "f(x)" and performs\nthe addition, and lastly, it writes the result back to "a[i]".\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n', + 'binary': u'\nBinary arithmetic operations\n****************************\n\nThe binary arithmetic operations have the conventional priority\nlevels. Note that some of these operations also apply to certain non-\nnumeric types. Apart from the power operator, there are only two\nlevels, one for multiplicative operators and one for additive\noperators:\n\n m_expr ::= u_expr | m_expr "*" u_expr | m_expr "@" m_expr |\n m_expr "//" u_expr| m_expr "/" u_expr |\n m_expr "%" u_expr\n a_expr ::= m_expr | a_expr "+" m_expr | a_expr "-" m_expr\n\nThe "*" (multiplication) operator yields the product of its arguments.\nThe arguments must either both be numbers, or one argument must be an\ninteger and the other must be a sequence. In the former case, the\nnumbers are converted to a common type and then multiplied together.\nIn the latter case, sequence repetition is performed; a negative\nrepetition factor yields an empty sequence.\n\nThe "@" (at) operator is intended to be used for matrix\nmultiplication. No builtin Python types implement this operator.\n\nNew in version 3.5.\n\nThe "/" (division) and "//" (floor division) operators yield the\nquotient of their arguments. The numeric arguments are first\nconverted to a common type. Division of integers yields a float, while\nfloor division of integers results in an integer; the result is that\nof mathematical division with the \'floor\' function applied to the\nresult. Division by zero raises the "ZeroDivisionError" exception.\n\nThe "%" (modulo) operator yields the remainder from the division of\nthe first argument by the second. The numeric arguments are first\nconverted to a common type. A zero right argument raises the\n"ZeroDivisionError" exception. The arguments may be floating point\nnumbers, e.g., "3.14%0.7" equals "0.34" (since "3.14" equals "4*0.7 +\n0.34".) The modulo operator always yields a result with the same sign\nas its second operand (or zero); the absolute value of the result is\nstrictly smaller than the absolute value of the second operand [1].\n\nThe floor division and modulo operators are connected by the following\nidentity: "x == (x//y)*y + (x%y)". Floor division and modulo are also\nconnected with the built-in function "divmod()": "divmod(x, y) ==\n(x//y, x%y)". [2].\n\nIn addition to performing the modulo operation on numbers, the "%"\noperator is also overloaded by string objects to perform old-style\nstring formatting (also known as interpolation). The syntax for\nstring formatting is described in the Python Library Reference,\nsection *printf-style String Formatting*.\n\nThe floor division operator, the modulo operator, and the "divmod()"\nfunction are not defined for complex numbers. Instead, convert to a\nfloating point number using the "abs()" function if appropriate.\n\nThe "+" (addition) operator yields the sum of its arguments. The\narguments must either both be numbers or both be sequences of the same\ntype. In the former case, the numbers are converted to a common type\nand then added together. In the latter case, the sequences are\nconcatenated.\n\nThe "-" (subtraction) operator yields the difference of its arguments.\nThe numeric arguments are first converted to a common type.\n', + 'bitwise': u'\nBinary bitwise operations\n*************************\n\nEach of the three bitwise operations has a different priority level:\n\n and_expr ::= shift_expr | and_expr "&" shift_expr\n xor_expr ::= and_expr | xor_expr "^" and_expr\n or_expr ::= xor_expr | or_expr "|" xor_expr\n\nThe "&" operator yields the bitwise AND of its arguments, which must\nbe integers.\n\nThe "^" operator yields the bitwise XOR (exclusive OR) of its\narguments, which must be integers.\n\nThe "|" operator yields the bitwise (inclusive) OR of its arguments,\nwhich must be integers.\n', + 'bltin-code-objects': u'\nCode Objects\n************\n\nCode objects are used by the implementation to represent "pseudo-\ncompiled" executable Python code such as a function body. They differ\nfrom function objects because they don\'t contain a reference to their\nglobal execution environment. Code objects are returned by the built-\nin "compile()" function and can be extracted from function objects\nthrough their "__code__" attribute. See also the "code" module.\n\nA code object can be executed or evaluated by passing it (instead of a\nsource string) to the "exec()" or "eval()" built-in functions.\n\nSee *The standard type hierarchy* for more information.\n', + 'bltin-ellipsis-object': u'\nThe Ellipsis Object\n*******************\n\nThis object is commonly used by slicing (see *Slicings*). It supports\nno special operations. There is exactly one ellipsis object, named\n"Ellipsis" (a built-in name). "type(Ellipsis)()" produces the\n"Ellipsis" singleton.\n\nIt is written as "Ellipsis" or "...".\n', + 'bltin-null-object': u'\nThe Null Object\n***************\n\nThis object is returned by functions that don\'t explicitly return a\nvalue. It supports no special operations. There is exactly one null\nobject, named "None" (a built-in name). "type(None)()" produces the\nsame singleton.\n\nIt is written as "None".\n', + 'bltin-type-objects': u'\nType Objects\n************\n\nType objects represent the various object types. An object\'s type is\naccessed by the built-in function "type()". There are no special\noperations on types. The standard module "types" defines names for\nall standard built-in types.\n\nTypes are written like this: "".\n', + 'booleans': u'\nBoolean operations\n******************\n\n or_test ::= and_test | or_test "or" and_test\n and_test ::= not_test | and_test "and" not_test\n not_test ::= comparison | "not" not_test\n\nIn the context of Boolean operations, and also when expressions are\nused by control flow statements, the following values are interpreted\nas false: "False", "None", numeric zero of all types, and empty\nstrings and containers (including strings, tuples, lists,\ndictionaries, sets and frozensets). All other values are interpreted\nas true. User-defined objects can customize their truth value by\nproviding a "__bool__()" method.\n\nThe operator "not" yields "True" if its argument is false, "False"\notherwise.\n\nThe expression "x and y" first evaluates *x*; if *x* is false, its\nvalue is returned; otherwise, *y* is evaluated and the resulting value\nis returned.\n\nThe expression "x or y" first evaluates *x*; if *x* is true, its value\nis returned; otherwise, *y* is evaluated and the resulting value is\nreturned.\n\n(Note that neither "and" nor "or" restrict the value and type they\nreturn to "False" and "True", but rather return the last evaluated\nargument. This is sometimes useful, e.g., if "s" is a string that\nshould be replaced by a default value if it is empty, the expression\n"s or \'foo\'" yields the desired value. Because "not" has to create a\nnew value, it returns a boolean value regardless of the type of its\nargument (for example, "not \'foo\'" produces "False" rather than "\'\'".)\n', + 'break': u'\nThe "break" statement\n*********************\n\n break_stmt ::= "break"\n\n"break" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition within that\nloop.\n\nIt terminates the nearest enclosing loop, skipping the optional "else"\nclause if the loop has one.\n\nIf a "for" loop is terminated by "break", the loop control target\nkeeps its current value.\n\nWhen "break" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nloop.\n', + 'callable-types': u'\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n', + 'calls': u'\nCalls\n*****\n\nA call calls a callable object (e.g., a *function*) with a possibly\nempty series of *arguments*:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nAn optional trailing comma may be present after the positional and\nkeyword arguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n"__call__()" method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal *parameter* lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a "TypeError" exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is "None", it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a "TypeError"\nexception is raised. Otherwise, the list of filled slots is used as\nthe argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use "PyArg_ParseTuple()" to parse\ntheir arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "*identifier" is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a "TypeError" exception is raised, unless a formal parameter\nusing the syntax "**identifier" is present; in this case, that formal\nparameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax "*expression" appears in the function call, "expression"\nmust evaluate to an iterable. Elements from this iterable are treated\nas if they were additional positional arguments; if there are\npositional arguments *x1*, ..., *xN*, and "expression" evaluates to a\nsequence *y1*, ..., *yM*, this is equivalent to a call with M+N\npositional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the "*expression" syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the "**expression" argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the "*expression" syntax\nto be used in the same call, so in practice this confusion does not\narise.\n\nIf the syntax "**expression" appears in the function call,\n"expression" must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both "expression" and as an explicit keyword argument, a\n"TypeError" exception is raised.\n\nFormal parameters using the syntax "*identifier" or "**identifier"\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly "None", unless it raises an\nexception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a "return"\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a "__call__()" method; the effect is then the\n same as if that method was called.\n', + 'class': u'\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n', + 'comparisons': u'\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like "a < b < c" have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: "True" or "False".\n\nComparisons can be chained arbitrarily, e.g., "x < y <= z" is\nequivalent to "x < y and y <= z", except that "y" is evaluated only\nonce (but in both cases "z" is not evaluated at all when "x < y" is\nfound to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then "a op1 b op2 c ... y\nopN z" is equivalent to "a op1 b and b op2 c and ... y opN z", except\nthat each expression is evaluated at most once.\n\nNote that "a op1 b op2 c" doesn\'t imply any kind of comparison between\n*a* and *c*, so that, e.g., "x < y > z" is perfectly legal (though\nperhaps not pretty).\n\n\nValue comparisons\n=================\n\nThe operators "<", ">", "==", ">=", "<=", and "!=" compare the values\nof two objects. The objects do not need to have the same type.\n\nChapter *Objects, values and types* states that objects have a value\n(in addition to type and identity). The value of an object is a\nrather abstract notion in Python: For example, there is no canonical\naccess method for an object\'s value. Also, there is no requirement\nthat the value of an object should be constructed in a particular way,\ne.g. comprised of all its data attributes. Comparison operators\nimplement a particular notion of what the value of an object is. One\ncan think of them as defining the value of an object indirectly, by\nmeans of their comparison implementation.\n\nBecause all types are (direct or indirect) subtypes of "object", they\ninherit the default comparison behavior from "object". Types can\ncustomize their comparison behavior by implementing *rich comparison\nmethods* like "__lt__()", described in *Basic customization*.\n\nThe default behavior for equality comparison ("==" and "!=") is based\non the identity of the objects. Hence, equality comparison of\ninstances with the same identity results in equality, and equality\ncomparison of instances with different identities results in\ninequality. A motivation for this default behavior is the desire that\nall objects should be reflexive (i.e. "x is y" implies "x == y").\n\nA default order comparison ("<", ">", "<=", and ">=") is not provided;\nan attempt raises "TypeError". A motivation for this default behavior\nis the lack of a similar invariant as for equality.\n\nThe behavior of the default equality comparison, that instances with\ndifferent identities are always unequal, may be in contrast to what\ntypes will need that have a sensible definition of object value and\nvalue-based equality. Such types will need to customize their\ncomparison behavior, and in fact, a number of built-in types have done\nthat.\n\nThe following list describes the comparison behavior of the most\nimportant built-in types.\n\n* Numbers of built-in numeric types (*Numeric Types --- int, float,\n complex*) and of the standard library types "fractions.Fraction" and\n "decimal.Decimal" can be compared within and across their types,\n with the restriction that complex numbers do not support order\n comparison. Within the limits of the types involved, they compare\n mathematically (algorithmically) correct without loss of precision.\n\n The not-a-number values "float(\'NaN\')" and "Decimal(\'NaN\')" are\n special. They are identical to themselves ("x is x" is true) but\n are not equal to themselves ("x == x" is false). Additionally,\n comparing any number to a not-a-number value will return "False".\n For example, both "3 < float(\'NaN\')" and "float(\'NaN\') < 3" will\n return "False".\n\n* Binary sequences (instances of "bytes" or "bytearray") can be\n compared within and across their types. They compare\n lexicographically using the numeric values of their elements.\n\n* Strings (instances of "str") compare lexicographically using the\n numerical Unicode code points (the result of the built-in function\n "ord()") of their characters. [3]\n\n Strings and binary sequences cannot be directly compared.\n\n* Sequences (instances of "tuple", "list", or "range") can be\n compared only within each of their types, with the restriction that\n ranges do not support order comparison. Equality comparison across\n these types results in unequality, and ordering comparison across\n these types raises "TypeError".\n\n Sequences compare lexicographically using comparison of\n corresponding elements, whereby reflexivity of the elements is\n enforced.\n\n In enforcing reflexivity of elements, the comparison of collections\n assumes that for a collection element "x", "x == x" is always true.\n Based on that assumption, element identity is compared first, and\n element comparison is performed only for distinct elements. This\n approach yields the same result as a strict element comparison\n would, if the compared elements are reflexive. For non-reflexive\n elements, the result is different than for strict element\n comparison, and may be surprising: The non-reflexive not-a-number\n values for example result in the following comparison behavior when\n used in a list:\n\n >>> nan = float(\'NaN\')\n >>> nan is nan\n True\n >>> nan == nan\n False <-- the defined non-reflexive behavior of NaN\n >>> [nan] == [nan]\n True <-- list enforces reflexivity and tests identity first\n\n Lexicographical comparison between built-in collections works as\n follows:\n\n * For two collections to compare equal, they must be of the same\n type, have the same length, and each pair of corresponding\n elements must compare equal (for example, "[1,2] == (1,2)" is\n false because the type is not the same).\n\n * Collections that support order comparison are ordered the same\n as their first unequal elements (for example, "[1,2,x] <= [1,2,y]"\n has the same value as "x <= y"). If a corresponding element does\n not exist, the shorter collection is ordered first (for example,\n "[1,2] < [1,2,3]" is true).\n\n* Mappings (instances of "dict") compare equal if and only if they\n have equal *(key, value)* pairs. Equality comparison of the keys and\n elements enforces reflexivity.\n\n Order comparisons ("<", ">", "<=", and ">=") raise "TypeError".\n\n* Sets (instances of "set" or "frozenset") can be compared within\n and across their types.\n\n They define order comparison operators to mean subset and superset\n tests. Those relations do not define total orderings (for example,\n the two sets "{1,2}" and "{2,3}" are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering\n (for example, "min()", "max()", and "sorted()" produce undefined\n results given a list of sets as inputs).\n\n Comparison of sets enforces reflexivity of its elements.\n\n* Most other built-in types have no comparison methods implemented,\n so they inherit the default comparison behavior.\n\nUser-defined classes that customize their comparison behavior should\nfollow some consistency rules, if possible:\n\n* Equality comparison should be reflexive. In other words, identical\n objects should compare equal:\n\n "x is y" implies "x == y"\n\n* Comparison should be symmetric. In other words, the following\n expressions should have the same result:\n\n "x == y" and "y == x"\n\n "x != y" and "y != x"\n\n "x < y" and "y > x"\n\n "x <= y" and "y >= x"\n\n* Comparison should be transitive. The following (non-exhaustive)\n examples illustrate that:\n\n "x > y and y > z" implies "x > z"\n\n "x < y and y <= z" implies "x < z"\n\n* Inverse comparison should result in the boolean negation. In other\n words, the following expressions should have the same result:\n\n "x == y" and "not x != y"\n\n "x < y" and "not x >= y" (for total ordering)\n\n "x > y" and "not x <= y" (for total ordering)\n\n The last two expressions apply to totally ordered collections (e.g.\n to sequences, but not to sets or mappings). See also the\n "total_ordering()" decorator.\n\nPython does not enforce these consistency rules. In fact, the\nnot-a-number values are an example for not following these rules.\n\n\nMembership test operations\n==========================\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n\n\nIdentity comparisons\n====================\n\nThe operators "is" and "is not" test for object identity: "x is y" is\ntrue if and only if *x* and *y* are the same object. "x is not y"\nyields the inverse truth value. [4]\n', + 'compound': u'\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe "if", "while" and "for" statements implement traditional control\nflow constructs. "try" specifies exception handlers and/or cleanup\ncode for a group of statements, while the "with" statement allows the\nexecution of initialization and finalization code around a block of\ncode. Function and class definitions are also syntactically compound\nstatements.\n\nA compound statement consists of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of a suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which "if" clause a following "else" clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n"print()" calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n | async_with_stmt\n | async_for_stmt\n | async_funcdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a "NEWLINE" possibly followed by a\n"DEDENT". Also note that optional continuation clauses always begin\nwith a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling "else"\' problem is solved in Python by\nrequiring nested "if" statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe "if" statement\n==================\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n\n\nThe "while" statement\n=====================\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n\n\nThe "for" statement\n===================\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe "try" statement\n===================\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe "with" statement\n====================\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [parameter_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing. Classes without an inheritance\nlist inherit, by default, from the base class "object"; hence,\n\n class Foo:\n pass\n\nis equivalent to\n\n class Foo(object):\n pass\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated: just like when decorating functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\nThe evaluation rules for the decorator expressions are the same as for\nfunction decorators. The result must be a class object, which is then\nbound to the class name.\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with "self.name = value". Both class and\ninstance attributes are accessible through the notation ""self.name"",\nand an instance attribute hides a class attribute with the same name\nwhen accessed in this way. Class attributes can be used as defaults\nfor instance attributes, but using mutable values there can lead to\nunexpected results. *Descriptors* can be used to create instance\nvariables with different implementation details.\n\nSee also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n Class Decorators\n\n\nCoroutines\n==========\n\nNew in version 3.5.\n\n\nCoroutine function definition\n-----------------------------\n\n async_funcdef ::= [decorators] "async" "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n\nExecution of Python coroutines can be suspended and resumed at many\npoints (see *coroutine*). In the body of a coroutine, any "await" and\n"async" identifiers become reserved keywords; "await" expressions,\n"async for" and "async with" can only be used in coroutine bodies.\n\nFunctions defined with "async def" syntax are always coroutine\nfunctions, even if they do not contain "await" or "async" keywords.\n\nIt is a "SyntaxError" to use "yield" expressions in "async def"\ncoroutines.\n\nAn example of a coroutine function:\n\n async def func(param1, param2):\n do_stuff()\n await some_coroutine()\n\n\nThe "async for" statement\n-------------------------\n\n async_for_stmt ::= "async" for_stmt\n\nAn *asynchronous iterable* is able to call asynchronous code in its\n*iter* implementation, and *asynchronous iterator* can call\nasynchronous code in its *next* method.\n\nThe "async for" statement allows convenient iteration over\nasynchronous iterators.\n\nThe following code:\n\n async for TARGET in ITER:\n BLOCK\n else:\n BLOCK2\n\nIs semantically equivalent to:\n\n iter = (ITER)\n iter = await type(iter).__aiter__(iter)\n running = True\n while running:\n try:\n TARGET = await type(iter).__anext__(iter)\n except StopAsyncIteration:\n running = False\n else:\n BLOCK\n else:\n BLOCK2\n\nSee also "__aiter__()" and "__anext__()" for details.\n\nIt is a "SyntaxError" to use "async for" statement outside of an\n"async def" function.\n\n\nThe "async with" statement\n--------------------------\n\n async_with_stmt ::= "async" with_stmt\n\nAn *asynchronous context manager* is a *context manager* that is able\nto suspend execution in its *enter* and *exit* methods.\n\nThe following code:\n\n async with EXPR as VAR:\n BLOCK\n\nIs semantically equivalent to:\n\n mgr = (EXPR)\n aexit = type(mgr).__aexit__\n aenter = type(mgr).__aenter__(mgr)\n exc = True\n\n VAR = await aenter\n try:\n BLOCK\n except:\n if not await aexit(mgr, *sys.exc_info()):\n raise\n else:\n await aexit(mgr, None, None, None)\n\nSee also "__aenter__()" and "__aexit__()" for details.\n\nIt is a "SyntaxError" to use "async with" statement outside of an\n"async def" function.\n\nSee also: **PEP 492** - Coroutines with async and await syntax\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack unless\n there is a "finally" clause which happens to raise another\n exception. That new exception causes the old one to be lost.\n\n[2] Currently, control "flows off the end" except in the case of\n an exception or the execution of a "return", "continue", or\n "break" statement.\n\n[3] A string literal appearing as the first statement in the\n function body is transformed into the function\'s "__doc__"\n attribute and therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s "__doc__" item and\n therefore the class\'s *docstring*.\n', + 'context-managers': u'\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'continue': u'\nThe "continue" statement\n************************\n\n continue_stmt ::= "continue"\n\n"continue" may only occur syntactically nested in a "for" or "while"\nloop, but not nested in a function or class definition or "finally"\nclause within that loop. It continues with the next cycle of the\nnearest enclosing loop.\n\nWhen "continue" passes control out of a "try" statement with a\n"finally" clause, that "finally" clause is executed before really\nstarting the next loop cycle.\n', + 'conversions': u'\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works as follows:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the\n other is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string as a\nleft argument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n', + 'customization': u'\nBasic customization\n*******************\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "xy" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n By default, "__ne__()" delegates to "__eq__()" and inverts the\n result unless it is "NotImplemented". There are no other implied\n relationships among the comparison operators, for example, the\n truth of "(x.__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n', + 'debugger': u'\n"pdb" --- The Python Debugger\n*****************************\n\n**Source code:** Lib/pdb.py\n\n======================================================================\n\nThe module "pdb" defines an interactive source code debugger for\nPython programs. It supports setting (conditional) breakpoints and\nsingle stepping at the source line level, inspection of stack frames,\nsource code listing, and evaluation of arbitrary Python code in the\ncontext of any stack frame. It also supports post-mortem debugging\nand can be called under program control.\n\nThe debugger is extensible -- it is actually defined as the class\n"Pdb". This is currently undocumented but easily understood by reading\nthe source. The extension interface uses the modules "bdb" and "cmd".\n\nThe debugger\'s prompt is "(Pdb)". Typical usage to run a program under\ncontrol of the debugger is:\n\n >>> import pdb\n >>> import mymodule\n >>> pdb.run(\'mymodule.test()\')\n > (0)?()\n (Pdb) continue\n > (1)?()\n (Pdb) continue\n NameError: \'spam\'\n > (1)?()\n (Pdb)\n\nChanged in version 3.3: Tab-completion via the "readline" module is\navailable for commands and command arguments, e.g. the current global\nand local names are offered as arguments of the "p" command.\n\n"pdb.py" can also be invoked as a script to debug other scripts. For\nexample:\n\n python3 -m pdb myscript.py\n\nWhen invoked as a script, pdb will automatically enter post-mortem\ndebugging if the program being debugged exits abnormally. After post-\nmortem debugging (or after normal exit of the program), pdb will\nrestart the program. Automatic restarting preserves pdb\'s state (such\nas breakpoints) and in most cases is more useful than quitting the\ndebugger upon program\'s exit.\n\nNew in version 3.2: "pdb.py" now accepts a "-c" option that executes\ncommands as if given in a ".pdbrc" file, see *Debugger Commands*.\n\nThe typical usage to break into the debugger from a running program is\nto insert\n\n import pdb; pdb.set_trace()\n\nat the location you want to break into the debugger. You can then\nstep through the code following this statement, and continue running\nwithout the debugger using the "continue" command.\n\nThe typical usage to inspect a crashed program is:\n\n >>> import pdb\n >>> import mymodule\n >>> mymodule.test()\n Traceback (most recent call last):\n File "", line 1, in ?\n File "./mymodule.py", line 4, in test\n test2()\n File "./mymodule.py", line 3, in test2\n print(spam)\n NameError: spam\n >>> pdb.pm()\n > ./mymodule.py(3)test2()\n -> print(spam)\n (Pdb)\n\nThe module defines the following functions; each enters the debugger\nin a slightly different way:\n\npdb.run(statement, globals=None, locals=None)\n\n Execute the *statement* (given as a string or a code object) under\n debugger control. The debugger prompt appears before any code is\n executed; you can set breakpoints and type "continue", or you can\n step through the statement using "step" or "next" (all these\n commands are explained below). The optional *globals* and *locals*\n arguments specify the environment in which the code is executed; by\n default the dictionary of the module "__main__" is used. (See the\n explanation of the built-in "exec()" or "eval()" functions.)\n\npdb.runeval(expression, globals=None, locals=None)\n\n Evaluate the *expression* (given as a string or a code object)\n under debugger control. When "runeval()" returns, it returns the\n value of the expression. Otherwise this function is similar to\n "run()".\n\npdb.runcall(function, *args, **kwds)\n\n Call the *function* (a function or method object, not a string)\n with the given arguments. When "runcall()" returns, it returns\n whatever the function call returned. The debugger prompt appears\n as soon as the function is entered.\n\npdb.set_trace()\n\n Enter the debugger at the calling stack frame. This is useful to\n hard-code a breakpoint at a given point in a program, even if the\n code is not otherwise being debugged (e.g. when an assertion\n fails).\n\npdb.post_mortem(traceback=None)\n\n Enter post-mortem debugging of the given *traceback* object. If no\n *traceback* is given, it uses the one of the exception that is\n currently being handled (an exception must be being handled if the\n default is to be used).\n\npdb.pm()\n\n Enter post-mortem debugging of the traceback found in\n "sys.last_traceback".\n\nThe "run*" functions and "set_trace()" are aliases for instantiating\nthe "Pdb" class and calling the method of the same name. If you want\nto access further features, you have to do this yourself:\n\nclass class pdb.Pdb(completekey=\'tab\', stdin=None, stdout=None, skip=None, nosigint=False)\n\n "Pdb" is the debugger class.\n\n The *completekey*, *stdin* and *stdout* arguments are passed to the\n underlying "cmd.Cmd" class; see the description there.\n\n The *skip* argument, if given, must be an iterable of glob-style\n module name patterns. The debugger will not step into frames that\n originate in a module that matches one of these patterns. [1]\n\n By default, Pdb sets a handler for the SIGINT signal (which is sent\n when the user presses "Ctrl-C" on the console) when you give a\n "continue" command. This allows you to break into the debugger\n again by pressing "Ctrl-C". If you want Pdb not to touch the\n SIGINT handler, set *nosigint* tot true.\n\n Example call to enable tracing with *skip*:\n\n import pdb; pdb.Pdb(skip=[\'django.*\']).set_trace()\n\n New in version 3.1: The *skip* argument.\n\n New in version 3.2: The *nosigint* argument. Previously, a SIGINT\n handler was never set by Pdb.\n\n run(statement, globals=None, locals=None)\n runeval(expression, globals=None, locals=None)\n runcall(function, *args, **kwds)\n set_trace()\n\n See the documentation for the functions explained above.\n\n\nDebugger Commands\n=================\n\nThe commands recognized by the debugger are listed below. Most\ncommands can be abbreviated to one or two letters as indicated; e.g.\n"h(elp)" means that either "h" or "help" can be used to enter the help\ncommand (but not "he" or "hel", nor "H" or "Help" or "HELP").\nArguments to commands must be separated by whitespace (spaces or\ntabs). Optional arguments are enclosed in square brackets ("[]") in\nthe command syntax; the square brackets must not be typed.\nAlternatives in the command syntax are separated by a vertical bar\n("|").\n\nEntering a blank line repeats the last command entered. Exception: if\nthe last command was a "list" command, the next 11 lines are listed.\n\nCommands that the debugger doesn\'t recognize are assumed to be Python\nstatements and are executed in the context of the program being\ndebugged. Python statements can also be prefixed with an exclamation\npoint ("!"). This is a powerful way to inspect the program being\ndebugged; it is even possible to change a variable or call a function.\nWhen an exception occurs in such a statement, the exception name is\nprinted but the debugger\'s state is not changed.\n\nThe debugger supports *aliases*. Aliases can have parameters which\nallows one a certain level of adaptability to the context under\nexamination.\n\nMultiple commands may be entered on a single line, separated by ";;".\n(A single ";" is not used as it is the separator for multiple commands\nin a line that is passed to the Python parser.) No intelligence is\napplied to separating the commands; the input is split at the first\n";;" pair, even if it is in the middle of a quoted string.\n\nIf a file ".pdbrc" exists in the user\'s home directory or in the\ncurrent directory, it is read in and executed as if it had been typed\nat the debugger prompt. This is particularly useful for aliases. If\nboth files exist, the one in the home directory is read first and\naliases defined there can be overridden by the local file.\n\nChanged in version 3.2: ".pdbrc" can now contain commands that\ncontinue debugging, such as "continue" or "next". Previously, these\ncommands had no effect.\n\nh(elp) [command]\n\n Without argument, print the list of available commands. With a\n *command* as argument, print help about that command. "help pdb"\n displays the full documentation (the docstring of the "pdb"\n module). Since the *command* argument must be an identifier, "help\n exec" must be entered to get help on the "!" command.\n\nw(here)\n\n Print a stack trace, with the most recent frame at the bottom. An\n arrow indicates the current frame, which determines the context of\n most commands.\n\nd(own) [count]\n\n Move the current frame *count* (default one) levels down in the\n stack trace (to a newer frame).\n\nu(p) [count]\n\n Move the current frame *count* (default one) levels up in the stack\n trace (to an older frame).\n\nb(reak) [([filename:]lineno | function) [, condition]]\n\n With a *lineno* argument, set a break there in the current file.\n With a *function* argument, set a break at the first executable\n statement within that function. The line number may be prefixed\n with a filename and a colon, to specify a breakpoint in another\n file (probably one that hasn\'t been loaded yet). The file is\n searched on "sys.path". Note that each breakpoint is assigned a\n number to which all the other breakpoint commands refer.\n\n If a second argument is present, it is an expression which must\n evaluate to true before the breakpoint is honored.\n\n Without argument, list all breaks, including for each breakpoint,\n the number of times that breakpoint has been hit, the current\n ignore count, and the associated condition if any.\n\ntbreak [([filename:]lineno | function) [, condition]]\n\n Temporary breakpoint, which is removed automatically when it is\n first hit. The arguments are the same as for "break".\n\ncl(ear) [filename:lineno | bpnumber [bpnumber ...]]\n\n With a *filename:lineno* argument, clear all the breakpoints at\n this line. With a space separated list of breakpoint numbers, clear\n those breakpoints. Without argument, clear all breaks (but first\n ask confirmation).\n\ndisable [bpnumber [bpnumber ...]]\n\n Disable the breakpoints given as a space separated list of\n breakpoint numbers. Disabling a breakpoint means it cannot cause\n the program to stop execution, but unlike clearing a breakpoint, it\n remains in the list of breakpoints and can be (re-)enabled.\n\nenable [bpnumber [bpnumber ...]]\n\n Enable the breakpoints specified.\n\nignore bpnumber [count]\n\n Set the ignore count for the given breakpoint number. If count is\n omitted, the ignore count is set to 0. A breakpoint becomes active\n when the ignore count is zero. When non-zero, the count is\n decremented each time the breakpoint is reached and the breakpoint\n is not disabled and any associated condition evaluates to true.\n\ncondition bpnumber [condition]\n\n Set a new *condition* for the breakpoint, an expression which must\n evaluate to true before the breakpoint is honored. If *condition*\n is absent, any existing condition is removed; i.e., the breakpoint\n is made unconditional.\n\ncommands [bpnumber]\n\n Specify a list of commands for breakpoint number *bpnumber*. The\n commands themselves appear on the following lines. Type a line\n containing just "end" to terminate the commands. An example:\n\n (Pdb) commands 1\n (com) p some_variable\n (com) end\n (Pdb)\n\n To remove all commands from a breakpoint, type commands and follow\n it immediately with "end"; that is, give no commands.\n\n With no *bpnumber* argument, commands refers to the last breakpoint\n set.\n\n You can use breakpoint commands to start your program up again.\n Simply use the continue command, or step, or any other command that\n resumes execution.\n\n Specifying any command resuming execution (currently continue,\n step, next, return, jump, quit and their abbreviations) terminates\n the command list (as if that command was immediately followed by\n end). This is because any time you resume execution (even with a\n simple next or step), you may encounter another breakpoint--which\n could have its own command list, leading to ambiguities about which\n list to execute.\n\n If you use the \'silent\' command in the command list, the usual\n message about stopping at a breakpoint is not printed. This may be\n desirable for breakpoints that are to print a specific message and\n then continue. If none of the other commands print anything, you\n see no sign that the breakpoint was reached.\n\ns(tep)\n\n Execute the current line, stop at the first possible occasion\n (either in a function that is called or on the next line in the\n current function).\n\nn(ext)\n\n Continue execution until the next line in the current function is\n reached or it returns. (The difference between "next" and "step"\n is that "step" stops inside a called function, while "next"\n executes called functions at (nearly) full speed, only stopping at\n the next line in the current function.)\n\nunt(il) [lineno]\n\n Without argument, continue execution until the line with a number\n greater than the current one is reached.\n\n With a line number, continue execution until a line with a number\n greater or equal to that is reached. In both cases, also stop when\n the current frame returns.\n\n Changed in version 3.2: Allow giving an explicit line number.\n\nr(eturn)\n\n Continue execution until the current function returns.\n\nc(ont(inue))\n\n Continue execution, only stop when a breakpoint is encountered.\n\nj(ump) lineno\n\n Set the next line that will be executed. Only available in the\n bottom-most frame. This lets you jump back and execute code again,\n or jump forward to skip code that you don\'t want to run.\n\n It should be noted that not all jumps are allowed -- for instance\n it is not possible to jump into the middle of a "for" loop or out\n of a "finally" clause.\n\nl(ist) [first[, last]]\n\n List source code for the current file. Without arguments, list 11\n lines around the current line or continue the previous listing.\n With "." as argument, list 11 lines around the current line. With\n one argument, list 11 lines around at that line. With two\n arguments, list the given range; if the second argument is less\n than the first, it is interpreted as a count.\n\n The current line in the current frame is indicated by "->". If an\n exception is being debugged, the line where the exception was\n originally raised or propagated is indicated by ">>", if it differs\n from the current line.\n\n New in version 3.2: The ">>" marker.\n\nll | longlist\n\n List all source code for the current function or frame.\n Interesting lines are marked as for "list".\n\n New in version 3.2.\n\na(rgs)\n\n Print the argument list of the current function.\n\np expression\n\n Evaluate the *expression* in the current context and print its\n value.\n\n Note: "print()" can also be used, but is not a debugger command\n --- this executes the Python "print()" function.\n\npp expression\n\n Like the "p" command, except the value of the expression is pretty-\n printed using the "pprint" module.\n\nwhatis expression\n\n Print the type of the *expression*.\n\nsource expression\n\n Try to get source code for the given object and display it.\n\n New in version 3.2.\n\ndisplay [expression]\n\n Display the value of the expression if it changed, each time\n execution stops in the current frame.\n\n Without expression, list all display expressions for the current\n frame.\n\n New in version 3.2.\n\nundisplay [expression]\n\n Do not display the expression any more in the current frame.\n Without expression, clear all display expressions for the current\n frame.\n\n New in version 3.2.\n\ninteract\n\n Start an interative interpreter (using the "code" module) whose\n global namespace contains all the (global and local) names found in\n the current scope.\n\n New in version 3.2.\n\nalias [name [command]]\n\n Create an alias called *name* that executes *command*. The command\n must *not* be enclosed in quotes. Replaceable parameters can be\n indicated by "%1", "%2", and so on, while "%*" is replaced by all\n the parameters. If no command is given, the current alias for\n *name* is shown. If no arguments are given, all aliases are listed.\n\n Aliases may be nested and can contain anything that can be legally\n typed at the pdb prompt. Note that internal pdb commands *can* be\n overridden by aliases. Such a command is then hidden until the\n alias is removed. Aliasing is recursively applied to the first\n word of the command line; all other words in the line are left\n alone.\n\n As an example, here are two useful aliases (especially when placed\n in the ".pdbrc" file):\n\n # Print instance variables (usage "pi classInst")\n alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])\n # Print instance variables in self\n alias ps pi self\n\nunalias name\n\n Delete the specified alias.\n\n! statement\n\n Execute the (one-line) *statement* in the context of the current\n stack frame. The exclamation point can be omitted unless the first\n word of the statement resembles a debugger command. To set a\n global variable, you can prefix the assignment command with a\n "global" statement on the same line, e.g.:\n\n (Pdb) global list_options; list_options = [\'-l\']\n (Pdb)\n\nrun [args ...]\nrestart [args ...]\n\n Restart the debugged Python program. If an argument is supplied,\n it is split with "shlex" and the result is used as the new\n "sys.argv". History, breakpoints, actions and debugger options are\n preserved. "restart" is an alias for "run".\n\nq(uit)\n\n Quit from the debugger. The program being executed is aborted.\n\n-[ Footnotes ]-\n\n[1] Whether a frame is considered to originate in a certain module\n is determined by the "__name__" in the frame globals.\n', + 'del': u'\nThe "del" statement\n*******************\n\n del_stmt ::= "del" target_list\n\nDeletion is recursively defined very similar to the way assignment is\ndefined. Rather than spelling it out in full details, here are some\nhints.\n\nDeletion of a target list recursively deletes each target, from left\nto right.\n\nDeletion of a name removes the binding of that name from the local or\nglobal namespace, depending on whether the name occurs in a "global"\nstatement in the same code block. If the name is unbound, a\n"NameError" exception will be raised.\n\nDeletion of attribute references, subscriptions and slicings is passed\nto the primary object involved; deletion of a slicing is in general\nequivalent to assignment of an empty slice of the right type (but even\nthis is determined by the sliced object).\n\nChanged in version 3.2: Previously it was illegal to delete a name\nfrom the local namespace if it occurs as a free variable in a nested\nblock.\n', + 'dict': u'\nDictionary displays\n*******************\n\nA dictionary display is a possibly empty series of key/datum pairs\nenclosed in curly braces:\n\n dict_display ::= "{" [key_datum_list | dict_comprehension] "}"\n key_datum_list ::= key_datum ("," key_datum)* [","]\n key_datum ::= expression ":" expression\n dict_comprehension ::= expression ":" expression comp_for\n\nA dictionary display yields a new dictionary object.\n\nIf a comma-separated sequence of key/datum pairs is given, they are\nevaluated from left to right to define the entries of the dictionary:\neach key object is used as a key into the dictionary to store the\ncorresponding datum. This means that you can specify the same key\nmultiple times in the key/datum list, and the final dictionary\'s value\nfor that key will be the last one given.\n\nA dict comprehension, in contrast to list and set comprehensions,\nneeds two expressions separated with a colon followed by the usual\n"for" and "if" clauses. When the comprehension is run, the resulting\nkey and value elements are inserted in the new dictionary in the order\nthey are produced.\n\nRestrictions on the types of the key values are listed earlier in\nsection *The standard type hierarchy*. (To summarize, the key type\nshould be *hashable*, which excludes all mutable objects.) Clashes\nbetween duplicate keys are not detected; the last datum (textually\nrightmost in the display) stored for a given key value prevails.\n', + 'dynamic-features': u'\nInteraction with dynamic features\n*********************************\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n i = 10\n def f():\n print(i)\n i = 42\n f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'else': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'exceptions': u'\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'execmodel': u'\nExecution model\n***************\n\n\nStructure of a program\n======================\n\nA Python program is constructed from code blocks. A *block* is a piece\nof Python program text that is executed as a unit. The following are\nblocks: a module, a function body, and a class definition. Each\ncommand typed interactively is a block. A script file (a file given\nas standard input to the interpreter or specified as a command line\nargument to the interpreter) is a code block. A script command (a\ncommand specified on the interpreter command line with the \'**-c**\'\noption) is a code block. The string argument passed to the built-in\nfunctions "eval()" and "exec()" is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\n\nNaming and binding\n==================\n\n\nBinding of names\n----------------\n\n*Names* refer to objects. Names are introduced by name binding\noperations.\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal" or "global". If a name is bound at the\nmodule level, it is a global variable. (The variables of the module\ncode block are local and global.) If a variable is used in a code\nblock but not defined there, it is a *free variable*.\n\nEach occurrence of a name in the program text refers to the *binding*\nof that name established by the following name resolution rules.\n\n\nResolution of names\n-------------------\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name.\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nWhen a name is not found at all, a "NameError" exception is raised. If\nthe current scope is a function scope, and the name refers to a local\nvariable that has not yet been bound to a value at the point where the\nname is used, an "UnboundLocalError" exception is raised.\n"UnboundLocalError" is a subclass of "NameError".\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nThe "nonlocal" statement causes corresponding names to refer to\npreviously bound variables in the nearest enclosing function scope.\n"SyntaxError" is raised at compile time if the given name does not\nexist in any enclosing function scope.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nClass definition blocks and arguments to "exec()" and "eval()" are\nspecial in the context of name resolution. A class definition is an\nexecutable statement that may use and define names. These references\nfollow the normal rules for name resolution with an exception that\nunbound local variables are looked up in the global namespace. The\nnamespace of the class definition becomes the attribute dictionary of\nthe class. The scope of names defined in a class block is limited to\nthe class block; it does not extend to the code blocks of methods --\nthis includes comprehensions and generator expressions since they are\nimplemented using a function scope. This means that the following\nwill fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\n\nBuiltins and restricted execution\n---------------------------------\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\n\nInteraction with dynamic features\n---------------------------------\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n i = 10\n def f():\n print(i)\n i = 42\n f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the "raise" statement. Exception\nhandlers are specified with the "try" ... "except" statement. The\n"finally" clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n"SystemExit".\n\nExceptions are identified by class instances. The "except" clause is\nselected depending on the class of the instance: it must reference the\nclass of the instance or a base class thereof. The instance can be\nreceived by the handler and can carry additional information about the\nexceptional condition.\n\nNote: Exception messages are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the "try" statement in section *The try\nstatement* and "raise" statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by\n these operations is not available at the time the module is\n compiled.\n', + 'exprlists': u'\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: "()".)\n', + 'floating': u'\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts are always interpreted using\nradix 10. For example, "077e010" is legal, and denotes the same number\nas "77e10". The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator "-" and the\nliteral "1".\n', + 'for': u'\nThe "for" statement\n*******************\n\nThe "for" statement is used to iterate over the elements of a sequence\n(such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n"expression_list". The suite is then executed once for each item\nprovided by the iterator, in the order returned by the iterator. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a "StopIteration" exception),\nthe suite in the "else" clause, if present, is executed, and the loop\nterminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and continues\nwith the next item, or with the "else" clause if there is no next\nitem.\n\nThe for-loop makes assignments to the variables(s) in the target list.\nThis overwrites all previous assignments to those variables including\nthose made in the suite of the for-loop:\n\n for i in range(10):\n print(i)\n i = 5 # this will not affect the for-loop\n # because i will be overwritten with the next\n # index in the range\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, they will not have been assigned to at\nall by the loop. Hint: the built-in function "range()" returns an\niterator of integers suitable to emulate the effect of Pascal\'s "for i\n:= a to b do"; e.g., "list(range(3))" returns the list "[0, 1, 2]".\n\nNote: There is a subtlety when the sequence is being modified by the\n loop (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', + 'formatstrings': u'\nFormat String Syntax\n********************\n\nThe "str.format()" method and the "Formatter" class share the same\nsyntax for format strings (although in the case of "Formatter",\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n"{}". Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n"{{" and "}}".\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point "\'!\'", and a *format_spec*, which is\npreceded by a colon "\':\'". These specify a non-default format for the\nreplacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings "\'10\'" or\n"\':-]\'") within a format string. The *arg_name* can be followed by any\nnumber of index or attribute expressions. An expression of the form\n"\'.name\'" selects the named attribute using "getattr()", while an\nexpression of the form "\'[index]\'" does an index lookup using\n"__getitem__()".\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so "\'{} {}\'" is equivalent to "\'{0} {1}\'".\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the "__format__()"\nmethod of the value itself. However, in some cases it is desirable to\nforce a type to be formatted as a string, overriding its own\ndefinition of formatting. By converting the value to a string before\ncalling "__format__()", the normal formatting logic is bypassed.\n\nThree conversion flags are currently supported: "\'!s\'" which calls\n"str()" on the value, "\'!r\'" which calls "repr()" and "\'!a\'" which\ncalls "ascii()".\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in "format()" function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string ("""") produces\nthe same result as if you had called "str()" on the value. A non-empty\nformat string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use "{" and "}" as *fill*\nchar while using the "str.format()" method; this limitation however\ndoesn\'t affect the "format()" function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'<\'" | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | "\'>\'" | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | "\'=\'" | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | "\'^\'" | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | "\'+\'" | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | "\'-\'" | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe "\'#\'" option causes the "alternate form" to be used for the\nconversion. The alternate form is defined differently for different\ntypes. This option is only valid for integer, float, complex and\nDecimal types. For integers, when binary, octal, or hexadecimal output\nis used, this option adds the prefix respective "\'0b\'", "\'0o\'", or\n"\'0x\'" to the output value. For floats, complex and Decimal the\nalternate form causes the result of the conversion to always contain a\ndecimal-point character, even if no digits follow it. Normally, a\ndecimal-point character appears in the result of these conversions\nonly if a digit follows it. In addition, for "\'g\'" and "\'G\'"\nconversions, trailing zeros are not removed from the result.\n\nThe "\',\'" option signals the use of a comma for a thousands separator.\nFor a locale aware separator, use the "\'n\'" integer presentation type\ninstead.\n\nChanged in version 3.1: Added the "\',\'" option (see also **PEP 378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero ("\'0\'") character enables sign-\naware zero-padding for numeric types. This is equivalent to a *fill*\ncharacter of "\'0\'" with an *alignment* type of "\'=\'".\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with "\'f\'" and "\'F\'", or before and after the decimal point\nfor a floating point value formatted with "\'g\'" or "\'G\'". For non-\nnumber types the field indicates the maximum field size - in other\nwords, how many characters will be used from the field content. The\n*precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'s\'" | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'s\'". |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'b\'" | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | "\'c\'" | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | "\'d\'" | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | "\'o\'" | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | "\'x\'" | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'X\'" | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'d\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as "\'d\'". |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except "\'n\'"\nand None). When doing so, "float()" is used to convert the integer to\na floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | "\'e\'" | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'E\'" | Exponent notation. Same as "\'e\'" except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | "\'f\'" | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'F\'" | Fixed point. Same as "\'f\'", but converts "nan" to "NAN" |\n | | and "inf" to "INF". |\n +-----------+------------------------------------------------------------+\n | "\'g\'" | General format. For a given precision "p >= 1", this |\n | | rounds the number to "p" significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type "\'e\'" and precision "p-1" |\n | | would have exponent "exp". Then if "-4 <= exp < p", the |\n | | number is formatted with presentation type "\'f\'" and |\n | | precision "p-1-exp". Otherwise, the number is formatted |\n | | with presentation type "\'e\'" and precision "p-1". In both |\n | | cases insignificant trailing zeros are removed from the |\n | | significand, and the decimal point is also removed if |\n | | there are no remaining digits following it. Positive and |\n | | negative infinity, positive and negative zero, and nans, |\n | | are formatted as "inf", "-inf", "0", "-0" and "nan" |\n | | respectively, regardless of the precision. A precision of |\n | | "0" is treated as equivalent to a precision of "1". The |\n | | default precision is "6". |\n +-----------+------------------------------------------------------------+\n | "\'G\'" | General format. Same as "\'g\'" except switches to "\'E\'" if |\n | | the number gets too large. The representations of infinity |\n | | and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | "\'n\'" | Number. This is the same as "\'g\'", except that it uses the |\n | | current locale setting to insert the appropriate number |\n | | separator characters. |\n +-----------+------------------------------------------------------------+\n | "\'%\'" | Percentage. Multiplies the number by 100 and displays in |\n | | fixed ("\'f\'") format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to "\'g\'", except that fixed-point notation, when |\n | | used, has at least one digit past the decimal point. The |\n | | default precision is as high as needed to represent the |\n | | particular value. The overall effect is to match the |\n | | output of "str()" as altered by the other format |\n | | modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old "%"-formatting.\n\nIn most of the cases the syntax is similar to the old "%"-formatting,\nwith the addition of the "{}" and with ":" used instead of "%". For\nexample, "\'%03.2f\'" can be translated to "\'{:03.2f}\'".\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing "%s" and "%r":\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing "%+f", "%-f", and "% f" and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing "%x" and "%o" and converting the value to different bases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12): #doctest: +NORMALIZE_WHITESPACE\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'function': u'\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [parameter_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n | "*" [parameter] ("," defparameter)* ["," "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more *parameters* have the form *parameter* "="\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding *argument* may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the ""*"" must also have a default value --- this\nis a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated from left to right when the\nfunction definition is executed.** This means that the expression is\nevaluated once, when the function is defined, and that the same "pre-\ncomputed" value is used for each call. This is especially important\nto understand when a default parameter is a mutable object, such as a\nlist or a dictionary: if the function modifies the object (e.g. by\nappending an item to a list), the default value is in effect modified.\nThis is generally not what was intended. A way around this is to use\n"None" as the default, and explicitly test for it in the body of the\nfunction, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n""*identifier"" is present, it is initialized to a tuple receiving any\nexcess positional parameters, defaulting to the empty tuple. If the\nform ""**identifier"" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after ""*"" or ""*identifier"" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "": expression"" following\nthe parameter name. Any parameter may have an annotation even those\nof the form "*identifier" or "**identifier". Functions may have\n"return" annotation of the form ""-> expression"" after the parameter\nlist. These annotations can be any valid Python expression and are\nevaluated when the function definition is executed. Annotations may\nbe evaluated in a different order than they appear in the source code.\nThe presence of annotations does not change the semantics of a\nfunction. The annotation values are available as values of a\ndictionary keyed by the parameters\' names in the "__annotations__"\nattribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda\nexpressions, described in section *Lambdas*. Note that the lambda\nexpression is merely a shorthand for a simplified function definition;\na function defined in a ""def"" statement can be passed around or\nassigned to another name just like a function defined by a lambda\nexpression. The ""def"" form is actually more powerful since it\nallows the execution of multiple statements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A ""def""\nstatement executed inside a function definition defines a local\nfunction that can be returned or passed around. Free variables used\nin the nested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\nSee also: **PEP 3107** - Function Annotations\n\n The original specification for function annotations.\n', + 'global': u'\nThe "global" statement\n**********************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe "global" statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without "global", although free variables may refer to\nglobals without being declared global.\n\nNames listed in a "global" statement must not be used in the same code\nblock textually preceding that "global" statement.\n\nNames listed in a "global" statement must not be defined as formal\nparameters or in a "for" loop control target, "class" definition,\nfunction definition, or "import" statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the two restrictions, but programs should not abuse this\nfreedom, as future implementations may enforce them or silently change\nthe meaning of the program.\n\n**Programmer\'s note:** the "global" is a directive to the parser. It\napplies only to code parsed at the same time as the "global"\nstatement. In particular, a "global" statement contained in a string\nor code object supplied to the built-in "exec()" function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by "global" statements in the\ncode containing the function call. The same applies to the "eval()"\nand "compile()" functions.\n', + 'id-classes': u'\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'identifiers': u'\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters "A" through "Z", the underscore "_" and, except for the first\ncharacter, the digits "0" through "9".\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n"unicodedata" module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= xid_start xid_continue*\n id_start ::= \n id_continue ::= \n xid_start ::= \n xid_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\n* *Other_ID_Start* - explicit list of characters in PropList.txt to\n support backwards compatibility\n\n* *Other_ID_Continue* - likewise\n\nAll identifiers are converted into the normal form NFKC while parsing;\ncomparison of identifiers is based on NFKC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n"_*"\n Not imported by "from module import *". The special identifier "_"\n is used in the interactive interpreter to store the result of the\n last evaluation; it is stored in the "builtins" module. When not\n in interactive mode, "_" has no special meaning and is not defined.\n See section *The import statement*.\n\n Note: The name "_" is often used in conjunction with\n internationalization; refer to the documentation for the\n "gettext" module for more information on this convention.\n\n"__*__"\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of "__*__" names, in any context, that does not\n follow explicitly documented use, is subject to breakage without\n warning.\n\n"__*"\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', + 'if': u'\nThe "if" statement\n******************\n\nThe "if" statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the "if" statement is executed or evaluated).\nIf all expressions are false, the suite of the "else" clause, if\npresent, is executed.\n', + 'imaginary': u'\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., "(3+4j)". Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n', + 'import': u'\nThe "import" statement\n**********************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nThe basic import statement (no "from" clause) is executed in two\nsteps:\n\n1. find a module, loading and initializing it if necessary\n\n2. define a name or names in the local namespace for the scope\n where the "import" statement occurs.\n\nWhen the statement contains multiple clauses (separated by commas) the\ntwo steps are carried out separately for each clause, just as though\nthe clauses had been separated out into individiual import statements.\n\nThe details of the first step, finding and loading modules are\ndescribed in greater detail in the section on the *import system*,\nwhich also describes the various types of packages and modules that\ncan be imported, as well as all the hooks that can be used to\ncustomize the import system. Note that failures in this step may\nindicate either that the module could not be located, *or* that an\nerror occurred while initializing the module, which includes execution\nof the module\'s code.\n\nIf the requested module is retrieved successfully, it will be made\navailable in the local namespace in one of three ways:\n\n* If the module name is followed by "as", then the name following\n "as" is bound directly to the imported module.\n\n* If no other name is specified, and the module being imported is a\n top level module, the module\'s name is bound in the local namespace\n as a reference to the imported module\n\n* If the module being imported is *not* a top level module, then the\n name of the top level package that contains the module is bound in\n the local namespace as a reference to the top level package. The\n imported module must be accessed using its full qualified name\n rather than directly\n\nThe "from" form uses a slightly more complex process:\n\n1. find the module specified in the "from" clause, loading and\n initializing it if necessary;\n\n2. for each of the identifiers specified in the "import" clauses:\n\n 1. check if the imported module has an attribute by that name\n\n 2. if not, attempt to import a submodule with that name and then\n check the imported module again for that attribute\n\n 3. if the attribute is not found, "ImportError" is raised.\n\n 4. otherwise, a reference to that value is stored in the local\n namespace, using the name in the "as" clause if it is present,\n otherwise using the attribute name\n\nExamples:\n\n import foo # foo imported and bound locally\n import foo.bar.baz # foo.bar.baz imported, foo bound locally\n import foo.bar.baz as fbb # foo.bar.baz imported and bound as fbb\n from foo.bar import baz # foo.bar.baz imported and bound as baz\n from foo import attr # foo imported and foo.attr bound as attr\n\nIf the list of identifiers is replaced by a star ("\'*\'"), all public\nnames defined in the module are bound in the local namespace for the\nscope where the "import" statement occurs.\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named "__all__"; if defined, it must\nbe a sequence of strings which are names defined or imported by that\nmodule. The names given in "__all__" are all considered public and\nare required to exist. If "__all__" is not defined, the set of public\nnames includes all names found in the module\'s namespace which do not\nbegin with an underscore character ("\'_\'"). "__all__" should contain\nthe entire public API. It is intended to avoid accidentally exporting\nitems that are not part of the API (such as library modules which were\nimported and used within the module).\n\nThe wild card form of import --- "from module import *" --- is only\nallowed at the module level. Attempting to use it in class or\nfunction definitions will raise a "SyntaxError".\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after "from" you\ncan specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n"from . import mod" from a module in the "pkg" package then you will\nend up importing "pkg.mod". If you execute "from ..subpkg2 import mod"\nfrom within "pkg.subpkg1" you will import "pkg.subpkg2.mod". The\nspecification for relative imports is contained within **PEP 328**.\n\n"importlib.import_module()" is provided to support applications that\ndetermine dynamically the modules to be loaded.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python where the feature\nbecomes standard.\n\nThe future statement is intended to ease migration to future versions\nof Python that introduce incompatible changes to the language. It\nallows use of the new features on a per-module basis before the\nrelease in which the feature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are "absolute_import",\n"division", "generators", "unicode_literals", "print_function",\n"nested_scopes" and "with_statement". They are all redundant because\nthey are always enabled, and only kept for backwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module "__future__", described later, and it will\nbe imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions "exec()" and\n"compile()" that occur in a module "M" containing a future statement\nwill, by default, use the new syntax or semantics associated with the\nfuture statement. This can be controlled by optional arguments to\n"compile()" --- see the documentation of that function for details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also: **PEP 236** - Back to the __future__\n\n The original proposal for the __future__ mechanism.\n', + 'in': u'\nMembership test operations\n**************************\n\nThe operators "in" and "not in" test for membership. "x in s"\nevaluates to true if *x* is a member of *s*, and false otherwise. "x\nnot in s" returns the negation of "x in s". All built-in sequences\nand set types support this as well as dictionary, for which "in" tests\nwhether the dictionary has a given key. For container types such as\nlist, tuple, set, frozenset, dict, or collections.deque, the\nexpression "x in y" is equivalent to "any(x is e or x == e for e in\ny)".\n\nFor the string and bytes types, "x in y" is true if and only if *x* is\na substring of *y*. An equivalent test is "y.find(x) != -1". Empty\nstrings are always considered to be a substring of any other string,\nso """ in "abc"" will return "True".\n\nFor user-defined classes which define the "__contains__()" method, "x\nin y" is true if and only if "y.__contains__(x)" is true.\n\nFor user-defined classes which do not define "__contains__()" but do\ndefine "__iter__()", "x in y" is true if some value "z" with "x == z"\nis produced while iterating over "y". If an exception is raised\nduring the iteration, it is as if "in" raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n"__getitem__()", "x in y" is true if and only if there is a non-\nnegative integer index *i* such that "x == y[i]", and all lower\ninteger indices do not raise "IndexError" exception. (If any other\nexception is raised, it is as if "in" raised that exception).\n\nThe operator "not in" is defined to have the inverse true value of\n"in".\n', + 'integers': u'\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0xdeadbeef\n', + 'lambda': u'\nLambdas\n*******\n\n lambda_expr ::= "lambda" [parameter_list]: expression\n lambda_expr_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda expressions (sometimes called lambda forms) are used to create\nanonymous functions. The expression "lambda arguments: expression"\nyields a function object. The unnamed object behaves like a function\nobject defined with\n\n def (arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda expressions cannot contain\nstatements or annotations.\n', + 'lists': u'\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n', + 'naming': u'\nNaming and binding\n******************\n\n\nBinding of names\n================\n\n*Names* refer to objects. Names are introduced by name binding\noperations.\n\nThe following constructs bind names: formal parameters to functions,\n"import" statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, "for" loop header, or after\n"as" in a "with" statement or "except" clause. The "import" statement\nof the form "from ... import *" binds all names defined in the\nimported module, except those beginning with an underscore. This form\nmay only be used at the module level.\n\nA target occurring in a "del" statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name).\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as "nonlocal" or "global". If a name is bound at the\nmodule level, it is a global variable. (The variables of the module\ncode block are local and global.) If a variable is used in a code\nblock but not defined there, it is a *free variable*.\n\nEach occurrence of a name in the program text refers to the *binding*\nof that name established by the following name resolution rules.\n\n\nResolution of names\n===================\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name.\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nWhen a name is not found at all, a "NameError" exception is raised. If\nthe current scope is a function scope, and the name refers to a local\nvariable that has not yet been bound to a value at the point where the\nname is used, an "UnboundLocalError" exception is raised.\n"UnboundLocalError" is a subclass of "NameError".\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the "global" statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module "builtins". The global namespace is searched first. If\nthe name is not found there, the builtins namespace is searched. The\n"global" statement must precede all uses of the name.\n\nThe "global" statement has the same scope as a name binding operation\nin the same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nThe "nonlocal" statement causes corresponding names to refer to\npreviously bound variables in the nearest enclosing function scope.\n"SyntaxError" is raised at compile time if the given name does not\nexist in any enclosing function scope.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n"__main__".\n\nClass definition blocks and arguments to "exec()" and "eval()" are\nspecial in the context of name resolution. A class definition is an\nexecutable statement that may use and define names. These references\nfollow the normal rules for name resolution with an exception that\nunbound local variables are looked up in the global namespace. The\nnamespace of the class definition becomes the attribute dictionary of\nthe class. The scope of names defined in a class block is limited to\nthe class block; it does not extend to the code blocks of methods --\nthis includes comprehensions and generator expressions since they are\nimplemented using a function scope. This means that the following\nwill fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\n\nBuiltins and restricted execution\n=================================\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name "__builtins__" in its global\nnamespace; this should be a dictionary or a module (in the latter case\nthe module\'s dictionary is used). By default, when in the "__main__"\nmodule, "__builtins__" is the built-in module "builtins"; when in any\nother module, "__builtins__" is an alias for the dictionary of the\n"builtins" module itself. "__builtins__" can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n"__builtins__"; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should "import"\nthe "builtins" module and modify its attributes appropriately.\n\n\nInteraction with dynamic features\n=================================\n\nName resolution of free variables occurs at runtime, not at compile\ntime. This means that the following code will print 42:\n\n i = 10\n def f():\n print(i)\n i = 42\n f()\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nThe "eval()" and "exec()" functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe "exec()" and "eval()" functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n', + 'nonlocal': u'\nThe "nonlocal" statement\n************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe "nonlocal" statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope excluding\nglobals. This is important because the default behavior for binding is\nto search the local namespace first. The statement allows\nencapsulated code to rebind variables outside of the local scope\nbesides the global (module) scope.\n\nNames listed in a "nonlocal" statement, unlike those listed in a\n"global" statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a "nonlocal" statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also: **PEP 3104** - Access to Names in Outer Scopes\n\n The specification for the "nonlocal" statement.\n', + 'numbers': u'\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like "-1"\nis actually an expression composed of the unary operator \'"-"\' and the\nliteral "1".\n', + 'numeric-types': u'\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n', + 'objects': u'\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'"is"\' operator compares the\nidentity of two objects; the "id()" function returns an integer\nrepresenting its identity.\n\n**CPython implementation detail:** For CPython, "id(x)" is the memory\naddress where "x" is stored.\n\nAn object\'s type determines the operations that the object supports\n(e.g., "does it have a length?") and also defines the possible values\nfor objects of that type. The "type()" function returns an object\'s\ntype (which is an object itself). Like its identity, an object\'s\n*type* is also unchangeable. [1]\n\nThe *value* of some objects can change. Objects whose value can\nchange are said to be *mutable*; objects whose value is unchangeable\nonce they are created are called *immutable*. (The value of an\nimmutable container object that contains a reference to a mutable\nobject can change when the latter\'s value is changed; however the\ncontainer is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the "gc" module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change. Do not depend\non immediate finalization of objects when they become unreachable (so\nyou should always close files explicitly).\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'"try"..."except"\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a "close()" method. Programs\nare strongly recommended to explicitly close such objects. The\n\'"try"..."finally"\' statement and the \'"with"\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after "a = 1; b = 1",\n"a" and "b" may or may not refer to the same object with the value\none, depending on the implementation, but after "c = []; d = []", "c"\nand "d" are guaranteed to refer to two different, unique, newly\ncreated empty lists. (Note that "c = d = []" assigns the same object\nto both "c" and "d".)\n', + 'operator-summary': u'\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedence in Python, from\nlowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for exponentiation, which\ngroups from right to left).\n\nNote that comparisons, membership tests, and identity tests, all have\nthe same precedence and have a left-to-right chaining feature as\ndescribed in the *Comparisons* section.\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| "lambda" | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| "if" -- "else" | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| "or" | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| "and" | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| "not" "x" | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| "in", "not in", "is", "is not", "<", "<=", ">", | Comparisons, including membership |\n| ">=", "!=", "==" | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| "|" | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| "^" | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| "&" | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| "<<", ">>" | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| "+", "-" | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| "*", "@", "/", "//", "%" | Multiplication, matrix multiplication |\n| | division, remainder [5] |\n+-------------------------------------------------+---------------------------------------+\n| "+x", "-x", "~x" | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| "**" | Exponentiation [6] |\n+-------------------------------------------------+---------------------------------------+\n| "await" "x" | Await expression |\n+-------------------------------------------------+---------------------------------------+\n| "x[index]", "x[index:index]", | Subscription, slicing, call, |\n| "x(arguments...)", "x.attribute" | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| "(expressions...)", "[expressions...]", "{key: | Binding or tuple display, list |\n| value...}", "{expressions...}" | display, dictionary display, set |\n| | display |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] While "abs(x%y) < abs(y)" is true mathematically, for floats\n it may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that "-1e-100 % 1e100" have the same\n sign as "1e100", the computed result is "-1e-100 + 1e100", which\n is numerically exactly equal to "1e100". The function\n "math.fmod()" returns a result whose sign matches the sign of the\n first argument instead, and so returns "-1e-100" in this case.\n Which approach is more appropriate depends on the application.\n\n[2] If x is very close to an exact integer multiple of y, it\'s\n possible for "x//y" to be one larger than "(x-x%y)//y" due to\n rounding. In such cases, Python returns the latter result, in\n order to preserve that "divmod(x,y)[0] * y + x % y" be very close\n to "x".\n\n[3] The Unicode standard distinguishes between *code points* (e.g.\n U+0041) and *abstract characters* (e.g. "LATIN CAPITAL LETTER A").\n While most abstract characters in Unicode are only represented\n using one code point, there is a number of abstract characters\n that can in addition be represented using a sequence of more than\n one code point. For example, the abstract character "LATIN\n CAPITAL LETTER C WITH CEDILLA" can be represented as a single\n *precomposed character* at code position U+00C7, or as a sequence\n of a *base character* at code position U+0043 (LATIN CAPITAL\n LETTER C), followed by a *combining character* at code position\n U+0327 (COMBINING CEDILLA).\n\n The comparison operators on strings compare at the level of\n Unicode code points. This may be counter-intuitive to humans. For\n example, ""\\u00C7" == "\\u0043\\u0327"" is "False", even though both\n strings represent the same abstract character "LATIN CAPITAL\n LETTER C WITH CEDILLA".\n\n To compare strings at the level of abstract characters (that is,\n in a way intuitive to humans), use "unicodedata.normalize()".\n\n[4] Due to automatic garbage-collection, free lists, and the\n dynamic nature of descriptors, you may notice seemingly unusual\n behaviour in certain uses of the "is" operator, like those\n involving comparisons between instance methods, or constants.\n Check their documentation for more info.\n\n[5] The "%" operator is also used for string formatting; the same\n precedence applies.\n\n[6] The power operator "**" binds less tightly than an arithmetic\n or bitwise unary operator on its right, that is, "2**-1" is "0.5".\n', + 'pass': u'\nThe "pass" statement\n********************\n\n pass_stmt ::= "pass"\n\n"pass" is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', + 'power': u'\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= await ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): "-1**2" results in "-1".\n\nThe power operator has the same semantics as the built-in "pow()"\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type, and the result is of that type.\n\nFor int operands, the result has the same type as the operands unless\nthe second argument is negative; in that case, all arguments are\nconverted to float and a float result is delivered. For example,\n"10**2" returns "100", but "10**-2" returns "0.01".\n\nRaising "0.0" to a negative power results in a "ZeroDivisionError".\nRaising a negative number to a fractional power results in a "complex"\nnumber. (In earlier versions it raised a "ValueError".)\n', + 'raise': u'\nThe "raise" statement\n*********************\n\n raise_stmt ::= "raise" [expression ["from" expression]]\n\nIf no expressions are present, "raise" re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a "RuntimeError" exception is raised indicating\nthat this is an error.\n\nOtherwise, "raise" evaluates the first expression as the exception\nobject. It must be either a subclass or an instance of\n"BaseException". If it is a class, the exception instance will be\nobtained when needed by instantiating the class with no arguments.\n\nThe *type* of the exception is the exception instance\'s class, the\n*value* is the instance itself.\n\nA traceback object is normally created automatically when an exception\nis raised and attached to it as the "__traceback__" attribute, which\nis writable. You can create an exception and set your own traceback in\none step using the "with_traceback()" exception method (which returns\nthe same exception instance, with its traceback set to its argument),\nlike so:\n\n raise Exception("foo occurred").with_traceback(tracebackobj)\n\nThe "from" clause is used for exception chaining: if given, the second\n*expression* must be another exception class or instance, which will\nthen be attached to the raised exception as the "__cause__" attribute\n(which is writable). If the raised exception is not handled, both\nexceptions will be printed:\n\n >>> try:\n ... print(1 / 0)\n ... except Exception as exc:\n ... raise RuntimeError("Something bad happened") from exc\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n The above exception was the direct cause of the following exception:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nA similar mechanism works implicitly if an exception is raised inside\nan exception handler or a "finally" clause: the previous exception is\nthen attached as the new exception\'s "__context__" attribute:\n\n >>> try:\n ... print(1 / 0)\n ... except:\n ... raise RuntimeError("Something bad happened")\n ...\n Traceback (most recent call last):\n File "", line 2, in \n ZeroDivisionError: int division or modulo by zero\n\n During handling of the above exception, another exception occurred:\n\n Traceback (most recent call last):\n File "", line 4, in \n RuntimeError: Something bad happened\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', + 'return': u'\nThe "return" statement\n**********************\n\n return_stmt ::= "return" [expression_list]\n\n"return" may only occur syntactically nested in a function definition,\nnot within a nested class definition.\n\nIf an expression list is present, it is evaluated, else "None" is\nsubstituted.\n\n"return" leaves the current function call with the expression list (or\n"None") as return value.\n\nWhen "return" passes control out of a "try" statement with a "finally"\nclause, that "finally" clause is executed before really leaving the\nfunction.\n\nIn a generator function, the "return" statement indicates that the\ngenerator is done and will cause "StopIteration" to be raised. The\nreturned value (if any) is used as an argument to construct\n"StopIteration" and becomes the "StopIteration.value" attribute.\n', + 'sequence-types': u'\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n', + 'shifting': u'\nShifting operations\n*******************\n\nThe shifting operations have lower priority than the arithmetic\noperations:\n\n shift_expr ::= a_expr | shift_expr ( "<<" | ">>" ) a_expr\n\nThese operators accept integers as arguments. They shift the first\nargument to the left or right by the number of bits given by the\nsecond argument.\n\nA right shift by *n* bits is defined as floor division by "pow(2,n)".\nA left shift by *n* bits is defined as multiplication with "pow(2,n)".\n\nNote: In the current implementation, the right-hand operand is\n required to be at most "sys.maxsize". If the right-hand operand is\n larger than "sys.maxsize" an "OverflowError" exception is raised.\n', + 'slicings': u'\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or "del" statements. The syntax for a slicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary is indexed\n(using the same "__getitem__()" method as normal subscription) with a\nkey that is constructed from the slice list, as follows. If the slice\nlist contains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n"start", "stop" and "step" attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting "None" for missing expressions.\n', + 'specialattrs': u'\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the "dir()" built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object\'s\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nclass.__qualname__\n\n The *qualified name* of the class or type.\n\n New in version 3.3.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in "__mro__".\n\nclass.__subclasses__()\n\n Each class keeps a list of weak references to its immediate\n subclasses. This method returns a list of all those references\n still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found\n in the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list "[1, 2]" is considered equal to\n "[1.0, 2.0]", and similarly for tuples.\n\n[3] They must have since the parser can\'t tell the type of the\n operands.\n\n[4] Cased characters are those with general category property\n being one of "Lu" (Letter, uppercase), "Ll" (Letter, lowercase),\n or "Lt" (Letter, titlecase).\n\n[5] To format only a tuple you should therefore provide a\n singleton tuple whose only element is the tuple to be formatted.\n', + 'specialnames': u'\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named "__getitem__()", and "x" is an instance of this class,\nthen "x[i]" is roughly equivalent to "type(x).__getitem__(x, i)".\nExcept where mentioned, attempts to execute an operation raise an\nexception when no appropriate method is defined (typically\n"AttributeError" or "TypeError").\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n"NodeList" interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. "__new__()" is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of "__new__()" should be the new object instance (usually an\n instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s "__new__()" method using\n "super(currentclass, cls).__new__(cls[, ...])" with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If "__new__()" returns an instance of *cls*, then the new\n instance\'s "__init__()" method will be invoked like\n "__init__(self[, ...])", where *self* is the new instance and the\n remaining arguments are the same as were passed to "__new__()".\n\n If "__new__()" does not return an instance of *cls*, then the new\n instance\'s "__init__()" method will not be invoked.\n\n "__new__()" is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called after the instance has been created (by "__new__()"), but\n before it is returned to the caller. The arguments are those\n passed to the class constructor expression. If a base class has an\n "__init__()" method, the derived class\'s "__init__()" method, if\n any, must explicitly call it to ensure proper initialization of the\n base class part of the instance; for example:\n "BaseClass.__init__(self, [args...])".\n\n Because "__new__()" and "__init__()" work together in constructing\n objects ("__new__()" to create it, and "__init__()" to customise\n it), no non-"None" value may be returned by "__init__()"; doing so\n will cause a "TypeError" to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a "__del__()" method, the\n derived class\'s "__del__()" method, if any, must explicitly call it\n to ensure proper deletion of the base class part of the instance.\n Note that it is possible (though not recommended!) for the\n "__del__()" method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n "__del__()" methods are called for objects that still exist when\n the interpreter exits.\n\n Note: "del x" doesn\'t directly call "x.__del__()" --- the former\n decrements the reference count for "x" by one, and the latter is\n only called when "x"\'s reference count reaches zero. Some common\n situations that may prevent the reference count of an object from\n going to zero include: circular references between objects (e.g.,\n a doubly-linked list or a tree data structure with parent and\n child pointers); a reference to the object on the stack frame of\n a function that caught an exception (the traceback stored in\n "sys.exc_info()[2]" keeps the stack frame alive); or a reference\n to the object on the stack frame that raised an unhandled\n exception in interactive mode (the traceback stored in\n "sys.last_traceback" keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the second can be resolved by freeing the reference to the\n traceback object when it is no longer useful, and the third can\n be resolved by storing "None" in "sys.last_traceback". Circular\n references which are garbage are detected and cleaned up when the\n cyclic garbage collector is enabled (it\'s on by default). Refer\n to the documentation for the "gc" module for more information\n about this topic.\n\n Warning: Due to the precarious circumstances under which\n "__del__()" methods are invoked, exceptions that occur during\n their execution are ignored, and a warning is printed to\n "sys.stderr" instead. Also, when "__del__()" is invoked in\n response to a module being deleted (e.g., when execution of the\n program is done), other globals referenced by the "__del__()"\n method may already have been deleted or in the process of being\n torn down (e.g. the import machinery shutting down). For this\n reason, "__del__()" methods should do the absolute minimum needed\n to maintain external invariants. Starting with version 1.5,\n Python guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the "__del__()" method is called.\n\nobject.__repr__(self)\n\n Called by the "repr()" built-in function to compute the "official"\n string representation of an object. If at all possible, this\n should look like a valid Python expression that could be used to\n recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n "<...some useful description...>" should be returned. The return\n value must be a string object. If a class defines "__repr__()" but\n not "__str__()", then "__repr__()" is also used when an "informal"\n string representation of instances of that class is required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by "str(object)" and the built-in functions "format()" and\n "print()" to compute the "informal" or nicely printable string\n representation of an object. The return value must be a *string*\n object.\n\n This method differs from "object.__repr__()" in that there is no\n expectation that "__str__()" return a valid Python expression: a\n more convenient or concise representation can be used.\n\n The default implementation defined by the built-in type "object"\n calls "object.__repr__()".\n\nobject.__bytes__(self)\n\n Called by "bytes()" to compute a byte-string representation of an\n object. This should return a "bytes" object.\n\nobject.__format__(self, format_spec)\n\n Called by the "format()" built-in function (and by extension, the\n "str.format()" method of class "str") to produce a "formatted"\n string representation of an object. The "format_spec" argument is a\n string that contains a description of the formatting options\n desired. The interpretation of the "format_spec" argument is up to\n the type implementing "__format__()", however most classes will\n either delegate formatting to one of the built-in types, or use a\n similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\n Changed in version 3.4: The __format__ method of "object" itself\n raises a "TypeError" if passed any non-empty string.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: "xy" calls\n "x.__gt__(y)", and "x>=y" calls "x.__ge__(y)".\n\n A rich comparison method may return the singleton "NotImplemented"\n if it does not implement the operation for a given pair of\n arguments. By convention, "False" and "True" are returned for a\n successful comparison. However, these methods can return any value,\n so if the comparison operator is used in a Boolean context (e.g.,\n in the condition of an "if" statement), Python will call "bool()"\n on the value to determine if the result is true or false.\n\n By default, "__ne__()" delegates to "__eq__()" and inverts the\n result unless it is "NotImplemented". There are no other implied\n relationships among the comparison operators, for example, the\n truth of "(x.__hash__".\n\n If a class that does not override "__eq__()" wishes to suppress\n hash support, it should include "__hash__ = None" in the class\n definition. A class which defines its own "__hash__()" that\n explicitly raises a "TypeError" would be incorrectly identified as\n hashable by an "isinstance(obj, collections.Hashable)" call.\n\n Note: By default, the "__hash__()" values of str, bytes and\n datetime objects are "salted" with an unpredictable random value.\n Although they remain constant within an individual Python\n process, they are not predictable between repeated invocations of\n Python.This is intended to provide protection against a denial-\n of-service caused by carefully-chosen inputs that exploit the\n worst case performance of a dict insertion, O(n^2) complexity.\n See http://www.ocert.org/advisories/ocert-2011-003.html for\n details.Changing hash values affects the iteration order of\n dicts, sets and other mappings. Python has never made guarantees\n about this ordering (and it typically varies between 32-bit and\n 64-bit builds).See also "PYTHONHASHSEED".\n\n Changed in version 3.3: Hash randomization is enabled by default.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n "bool()"; should return "False" or "True". When this method is not\n defined, "__len__()" is called, if it is defined, and the object is\n considered true if its result is nonzero. If a class defines\n neither "__len__()" nor "__bool__()", all its instances are\n considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of "x.name") for\nclass instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for "self"). "name" is the attribute name. This\n method should return the (computed) attribute value or raise an\n "AttributeError" exception.\n\n Note that if the attribute is found through the normal mechanism,\n "__getattr__()" is not called. (This is an intentional asymmetry\n between "__getattr__()" and "__setattr__()".) This is done both for\n efficiency reasons and because otherwise "__getattr__()" would have\n no way to access other attributes of the instance. Note that at\n least for instance variables, you can fake total control by not\n inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n "__getattribute__()" method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines "__getattr__()",\n the latter will not be called unless "__getattribute__()" either\n calls it explicitly or raises an "AttributeError". This method\n should return the (computed) attribute value or raise an\n "AttributeError" exception. In order to avoid infinite recursion in\n this method, its implementation should always call the base class\n method with the same name to access any attributes it needs, for\n example, "object.__getattribute__(self, name)".\n\n Note: This method may still be bypassed when looking up special\n methods as the result of implicit invocation via language syntax\n or built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If "__setattr__()" wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n "object.__setattr__(self, name, value)".\n\nobject.__delattr__(self, name)\n\n Like "__setattr__()" but for attribute deletion instead of\n assignment. This should only be implemented if "del obj.name" is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when "dir()" is called on the object. A sequence must be\n returned. "dir()" converts the returned sequence to a list and\n sorts it.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in an\n*owner* class (the descriptor must be in either the owner\'s class\ndictionary or in the class dictionary for one of its parents). In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' "__dict__".\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or "None" when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an "AttributeError"\n exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\nThe attribute "__objclass__" is interpreted by the "inspect" module as\nspecifying the class where this object was defined (setting this\nappropriately can assist in runtime introspection of dynamic class\nattributes). For callables, it may indicate that an instance of the\ngiven type (or a subclass) is expected or required as the first\npositional argument (for example, CPython sets this attribute for\nunbound methods that are implemented in C).\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: "__get__()", "__set__()", and\n"__delete__()". If any of those methods are defined for an object, it\nis said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, "a.x" has a\nlookup chain starting with "a.__dict__[\'x\']", then\n"type(a).__dict__[\'x\']", and continuing through the base classes of\n"type(a)" excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, "a.x". How\nthe arguments are assembled depends on "a":\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: "x.__get__(a)".\n\nInstance Binding\n If binding to an object instance, "a.x" is transformed into the\n call: "type(a).__dict__[\'x\'].__get__(a, type(a))".\n\nClass Binding\n If binding to a class, "A.x" is transformed into the call:\n "A.__dict__[\'x\'].__get__(None, A)".\n\nSuper Binding\n If "a" is an instance of "super", then the binding "super(B,\n obj).m()" searches "obj.__class__.__mro__" for the base class "A"\n immediately preceding "B" and then invokes the descriptor with the\n call: "A.__dict__[\'m\'].__get__(obj, obj.__class__)".\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of "__get__()", "__set__()" and "__delete__()". If it\ndoes not define "__get__()", then accessing the attribute will return\nthe descriptor object itself unless there is a value in the object\'s\ninstance dictionary. If the descriptor defines "__set__()" and/or\n"__delete__()", it is a data descriptor; if it defines neither, it is\na non-data descriptor. Normally, data descriptors define both\n"__get__()" and "__set__()", while non-data descriptors have just the\n"__get__()" method. Data descriptors with "__set__()" and "__get__()"\ndefined always override a redefinition in an instance dictionary. In\ncontrast, non-data descriptors can be overridden by instances.\n\nPython methods (including "staticmethod()" and "classmethod()") are\nimplemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe "property()" function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. *__slots__*\n reserves space for the declared variables and prevents the\n automatic creation of *__dict__* and *__weakref__* for each\n instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises "AttributeError". If\n dynamic assignment of new variables is desired, then add\n "\'__dict__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes\n defining *__slots__* do not support weak references to its\n instances. If weak reference support is needed, then add\n "\'__weakref__\'" to the sequence of strings in the *__slots__*\n declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the\n instance variable defined by the base class slot is inaccessible\n (except by retrieving its descriptor directly from the base class).\n This renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as "int", "bytes" and "tuple".\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings\n may also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using "type()". The class body is\nexecuted in a new namespace and the class name is bound locally to the\nresult of "type(name, bases, namespace)".\n\nThe class creation process can be customised by passing the\n"metaclass" keyword argument in the class definition line, or by\ninheriting from an existing class that included such an argument. In\nthe following example, both "MyClass" and "MySubclass" are instances\nof "Meta":\n\n class Meta(type):\n pass\n\n class MyClass(metaclass=Meta):\n pass\n\n class MySubclass(MyClass):\n pass\n\nAny other keyword arguments that are specified in the class definition\nare passed through to all metaclass operations described below.\n\nWhen a class definition is executed, the following steps occur:\n\n* the appropriate metaclass is determined\n\n* the class namespace is prepared\n\n* the class body is executed\n\n* the class object is created\n\n\nDetermining the appropriate metaclass\n-------------------------------------\n\nThe appropriate metaclass for a class definition is determined as\nfollows:\n\n* if no bases and no explicit metaclass are given, then "type()" is\n used\n\n* if an explicit metaclass is given and it is *not* an instance of\n "type()", then it is used directly as the metaclass\n\n* if an instance of "type()" is given as the explicit metaclass, or\n bases are defined, then the most derived metaclass is used\n\nThe most derived metaclass is selected from the explicitly specified\nmetaclass (if any) and the metaclasses (i.e. "type(cls)") of all\nspecified base classes. The most derived metaclass is one which is a\nsubtype of *all* of these candidate metaclasses. If none of the\ncandidate metaclasses meets that criterion, then the class definition\nwill fail with "TypeError".\n\n\nPreparing the class namespace\n-----------------------------\n\nOnce the appropriate metaclass has been identified, then the class\nnamespace is prepared. If the metaclass has a "__prepare__" attribute,\nit is called as "namespace = metaclass.__prepare__(name, bases,\n**kwds)" (where the additional keyword arguments, if any, come from\nthe class definition).\n\nIf the metaclass has no "__prepare__" attribute, then the class\nnamespace is initialised as an empty "dict()" instance.\n\nSee also: **PEP 3115** - Metaclasses in Python 3000\n\n Introduced the "__prepare__" namespace hook\n\n\nExecuting the class body\n------------------------\n\nThe class body is executed (approximately) as "exec(body, globals(),\nnamespace)". The key difference from a normal call to "exec()" is that\nlexical scoping allows the class body (including any methods) to\nreference names from the current and outer scopes when the class\ndefinition occurs inside a function.\n\nHowever, even when the class definition occurs inside the function,\nmethods defined inside the class still cannot see names defined at the\nclass scope. Class variables must be accessed through the first\nparameter of instance or class methods, and cannot be accessed at all\nfrom static methods.\n\n\nCreating the class object\n-------------------------\n\nOnce the class namespace has been populated by executing the class\nbody, the class object is created by calling "metaclass(name, bases,\nnamespace, **kwds)" (the additional keywords passed here are the same\nas those passed to "__prepare__").\n\nThis class object is the one that will be referenced by the zero-\nargument form of "super()". "__class__" is an implicit closure\nreference created by the compiler if any methods in a class body refer\nto either "__class__" or "super". This allows the zero argument form\nof "super()" to correctly identify the class being defined based on\nlexical scoping, while the class or instance that was used to make the\ncurrent call is identified based on the first argument passed to the\nmethod.\n\nAfter the class object is created, it is passed to the class\ndecorators included in the class definition (if any) and the resulting\nobject is bound in the local namespace as the defined class.\n\nSee also: **PEP 3135** - New super\n\n Describes the implicit "__class__" closure reference\n\n\nMetaclass example\n-----------------\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored include logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n"collections.OrderedDict" to remember the order that class variables\nare defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, namespace, **kwds):\n result = type.__new__(cls, name, bases, dict(namespace))\n result.members = tuple(namespace)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s "__prepare__()" method which returns an\nempty "collections.OrderedDict". That mapping records the methods and\nattributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s "__new__()" method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called "members".\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n"isinstance()" and "issubclass()" built-in functions.\n\nIn particular, the metaclass "abc.ABCMeta" implements these methods in\norder to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n "isinstance(instance, class)".\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n "issubclass(subclass, class)".\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also: **PEP 3119** - Introducing Abstract Base Classes\n\n Includes the specification for customizing "isinstance()" and\n "issubclass()" behavior through "__instancecheck__()" and\n "__subclasscheck__()", with motivation for this functionality in\n the context of adding Abstract Base Classes (see the "abc"\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, "x(arg1, arg2, ...)" is a shorthand for\n "x.__call__(arg1, arg2, ...)".\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which "0 <= k < N" where\n*N* is the length of the sequence, or slice objects, which define a\nrange of items. It is also recommended that mappings provide the\nmethods "keys()", "values()", "items()", "get()", "clear()",\n"setdefault()", "pop()", "popitem()", "copy()", and "update()"\nbehaving similar to those for Python\'s standard dictionary objects.\nThe "collections" module provides a "MutableMapping" abstract base\nclass to help create those methods from a base set of "__getitem__()",\n"__setitem__()", "__delitem__()", and "keys()". Mutable sequences\nshould provide methods "append()", "count()", "index()", "extend()",\n"insert()", "pop()", "remove()", "reverse()" and "sort()", like Python\nstandard list objects. Finally, sequence types should implement\naddition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods "__add__()", "__radd__()",\n"__iadd__()", "__mul__()", "__rmul__()" and "__imul__()" described\nbelow; they should not define other numerical operators. It is\nrecommended that both mappings and sequences implement the\n"__contains__()" method to allow efficient use of the "in" operator;\nfor mappings, "in" should search the mapping\'s keys; for sequences, it\nshould search through the values. It is further recommended that both\nmappings and sequences implement the "__iter__()" method to allow\nefficient iteration through the container; for mappings, "__iter__()"\nshould be the same as "keys()"; for sequences, it should iterate\nthrough the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function "len()". Should return\n the length of the object, an integer ">=" 0. Also, an object that\n doesn\'t define a "__bool__()" method and whose "__len__()" method\n returns zero is considered to be false in a Boolean context.\n\nobject.__length_hint__(self)\n\n Called to implement "operator.length_hint()". Should return an\n estimated length for the object (which may be greater or less than\n the actual length). The length must be an integer ">=" 0. This\n method is purely an optimization and is never required for\n correctness.\n\n New in version 3.4.\n\nNote: Slicing is done exclusively with the following three methods.\n A call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with "None".\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of "self[key]". For sequence types,\n the accepted keys should be integers and slice objects. Note that\n the special interpretation of negative indexes (if the class wishes\n to emulate a sequence type) is up to the "__getitem__()" method. If\n *key* is of an inappropriate type, "TypeError" may be raised; if of\n a value outside the set of indexes for the sequence (after any\n special interpretation of negative values), "IndexError" should be\n raised. For mapping types, if *key* is missing (not in the\n container), "KeyError" should be raised.\n\n Note: "for" loops expect that an "IndexError" will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__missing__(self, key)\n\n Called by "dict"."__getitem__()" to implement "self[key]" for dict\n subclasses when key is not in the dictionary.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the "__getitem__()" method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of "self[key]". Same note as for\n "__getitem__()". This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the "__getitem__()" method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the "reversed()" built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the "__reversed__()" method is not provided, the "reversed()"\n built-in will fall back to using the sequence protocol ("__len__()"\n and "__getitem__()"). Objects that support the sequence protocol\n should only provide "__reversed__()" if they can provide an\n implementation that is more efficient than the one provided by\n "reversed()".\n\nThe membership test operators ("in" and "not in") are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define "__contains__()", the membership test\n first tries iteration via "__iter__()", then the old sequence\n iteration protocol via "__getitem__()", see *this section in the\n language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__matmul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|"). For instance, to\n evaluate the expression "x + y", where *x* is an instance of a\n class that has an "__add__()" method, "x.__add__(y)" is called.\n The "__divmod__()" method should be the equivalent to using\n "__floordiv__()" and "__mod__()"; it should not be related to\n "__truediv__()". Note that "__pow__()" should be defined to accept\n an optional third argument if the ternary version of the built-in\n "pow()" function is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return "NotImplemented".\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rmatmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations ("+", "-", "*", "@", "/", "//", "%", "divmod()",\n "pow()", "**", "<<", ">>", "&", "^", "|") with reflected (swapped)\n operands. These functions are only called if the left operand does\n not support the corresponding operation and the operands are of\n different types. [2] For instance, to evaluate the expression "x -\n y", where *y* is an instance of a class that has an "__rsub__()"\n method, "y.__rsub__(x)" is called if "x.__sub__(y)" returns\n *NotImplemented*.\n\n Note that ternary "pow()" will not try calling "__rpow__()" (the\n coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left\n operand\'s type and that subclass provides the reflected method\n for the operation, this method will be called before the left\n operand\'s non-reflected method. This behavior allows subclasses\n to override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__imatmul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments ("+=", "-=", "*=", "@=", "/=", "//=", "%=", "**=",\n "<<=", ">>=", "&=", "^=", "|="). These methods should attempt to\n do the operation in-place (modifying *self*) and return the result\n (which could be, but does not have to be, *self*). If a specific\n method is not defined, the augmented assignment falls back to the\n normal methods. For instance, if *x* is an instance of a class\n with an "__iadd__()" method, "x += y" is equivalent to "x =\n x.__iadd__(y)" . Otherwise, "x.__add__(y)" and "y.__radd__(x)" are\n considered, as with the evaluation of "x + y". In certain\n situations, augmented assignment can result in unexpected errors\n (see *Why does a_tuple[i] += [\'item\'] raise an exception when the\n addition works?*), but this behavior is in fact part of the data\n model.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations ("-", "+",\n "abs()" and "~").\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions "complex()", "int()",\n "float()" and "round()". Should return a value of the appropriate\n type.\n\nobject.__index__(self)\n\n Called to implement "operator.index()", and whenever Python needs\n to losslessly convert the numeric object to an integer object (such\n as in slicing, or in the built-in "bin()", "hex()" and "oct()"\n functions). Presence of this method indicates that the numeric\n object is an integer type. Must return an integer.\n\n Note: In order to have a coherent integer type class, when\n "__index__()" is defined "__int__()" should also be defined, and\n both should return the same value.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a "with" statement. The context manager\nhandles the entry into, and the exit from, the desired runtime context\nfor the execution of the block of code. Context managers are normally\ninvoked using the "with" statement (described in section *The with\nstatement*), but can also be used by directly invoking their methods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The "with"\n statement will bind this method\'s return value to the target(s)\n specified in the "as" clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be "None".\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that "__exit__()" methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C:\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as "__hash__()" and "__repr__()" that are implemented by\nall objects, including type objects. If the implicit lookup of these\nmethods used the conventional lookup process, they would fail when\ninvoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe "__getattribute__()" method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the "__getattribute__()" machinery in this fashion provides\nsignificant scope for speed optimisations within the interpreter, at\nthe cost of some flexibility in the handling of special methods (the\nspecial method *must* be set on the class object itself in order to be\nconsistently invoked by the interpreter).\n', + 'string-methods': u'\nString Methods\n**************\n\nStrings implement all of the *common* sequence operations, along with\nthe additional methods described below.\n\nStrings also support two styles of string formatting, one providing a\nlarge degree of flexibility and customization (see "str.format()",\n*Format String Syntax* and *String Formatting*) and the other based on\nC "printf" style formatting that handles a narrower range of types and\nis slightly harder to use correctly, but is often faster for the cases\nit can handle (*printf-style String Formatting*).\n\nThe *Text Processing Services* section of the standard library covers\na number of other modules that provide various text related utilities\n(including regular expression support in the "re" module).\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.casefold()\n\n Return a casefolded copy of the string. Casefolded strings may be\n used for caseless matching.\n\n Casefolding is similar to lowercasing but more aggressive because\n it is intended to remove all case distinctions in a string. For\n example, the German lowercase letter "\'\xdf\'" is equivalent to ""ss"".\n Since it is already lowercase, "lower()" would do nothing to "\'\xdf\'";\n "casefold()" converts it to ""ss"".\n\n The casefolding algorithm is described in section 3.13 of the\n Unicode Standard.\n\n New in version 3.3.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is an ASCII space). The\n original string is returned if *width* is less than or equal to\n "len(s)".\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding="utf-8", errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is "\'utf-8\'". *errors* may be given to set a different\n error handling scheme. The default for *errors* is "\'strict\'",\n meaning that encoding errors raise a "UnicodeError". Other possible\n values are "\'ignore\'", "\'replace\'", "\'xmlcharrefreplace\'",\n "\'backslashreplace\'" and any other name registered via\n "codecs.register_error()", see section *Error Handlers*. For a list\n of possible encodings, see section *Standard Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return "True" if the string ends with the specified *suffix*,\n otherwise return "False". *suffix* can also be a tuple of suffixes\n to look for. With optional *start*, test beginning at that\n position. With optional *end*, stop comparing at that position.\n\nstr.expandtabs(tabsize=8)\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. Tab positions occur every *tabsize* characters\n (default is 8, giving tab positions at columns 0, 8, 16 and so on).\n To expand the string, the current column is set to zero and the\n string is examined character by character. If the character is a\n tab ("\\t"), one or more space characters are inserted in the result\n until the current column is equal to the next tab position. (The\n tab character itself is not copied.) If the character is a newline\n ("\\n") or return ("\\r"), it is copied and the current column is\n reset to zero. Any other character is copied unchanged and the\n current column is incremented by one regardless of how the\n character is represented when printed.\n\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs()\n \'01 012 0123 01234\'\n >>> \'01\\t012\\t0123\\t01234\'.expandtabs(4)\n \'01 012 0123 01234\'\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" if *sub* is not found.\n\n Note: The "find()" method should be used only if you need to know\n the position of *sub*. To check if *sub* is a substring or not,\n use the "in" operator:\n\n >>> \'Py\' in \'Python\'\n True\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces "{}". Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.format_map(mapping)\n\n Similar to "str.format(**mapping)", except that "mapping" is used\n directly and not copied to a "dict". This is useful if for example\n "mapping" is a dict subclass:\n\n >>> class Default(dict):\n ... def __missing__(self, key):\n ... return key\n ...\n >>> \'{name} was born in {country}\'.format_map(Default(name=\'Guido\'))\n \'Guido was born in country\'\n\n New in version 3.2.\n\nstr.index(sub[, start[, end]])\n\n Like "find()", but raise "ValueError" when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise. A character "c"\n is alphanumeric if one of the following returns "True":\n "c.isalpha()", "c.isdecimal()", "c.isdigit()", or "c.isnumeric()".\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise. Alphabetic\n characters are those characters defined in the Unicode character\n database as "Letter", i.e., those with general category property\n being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is\n different from the "Alphabetic" property defined in the Unicode\n Standard.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters are those from general category "Nd". This category\n includes digit characters, and all characters that can be used to\n form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise. Digits include decimal\n characters and digits that need special handling, such as the\n compatibility superscript digits. Formally, a digit is a character\n that has the property value Numeric_Type=Digit or\n Numeric_Type=Decimal.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\n Use "keyword.iskeyword()" to test for reserved identifiers such as\n "def" and "class".\n\nstr.islower()\n\n Return true if all cased characters [4] in the string are lowercase\n and there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH. Formally, numeric characters are those with the\n property value Numeric_Type=Digit, Numeric_Type=Decimal or\n Numeric_Type=Numeric.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when "repr()" is\n invoked on a string. It has no bearing on the handling of strings\n written to "sys.stdout" or "sys.stderr".)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise. Whitespace\n characters are those characters defined in the Unicode character\n database as "Other" or "Separator" and those with bidirectional\n property being one of "WS", "B", or "S".\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters [4] in the string are uppercase\n and there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A "TypeError" will be raised if there are\n any non-string values in *iterable*, including "bytes" objects.\n The separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.lower()\n\n Return a copy of the string with all the cased characters [4]\n converted to lowercase.\n\n The lowercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n "str.translate()".\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within "s[start:end]".\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return "-1" on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like "rfind()" but raises "ValueError" when the substring *sub* is\n not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is an ASCII\n space). The original string is returned if *width* is less than or\n equal to "len(s)".\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n "None", any whitespace string is a separator. Except for splitting\n from the right, "rsplit()" behaves like "split()" which is\n described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or "None", the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split(sep=None, maxsplit=-1)\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most "maxsplit+1"\n elements). If *maxsplit* is not specified or "-1", then there is\n no limit on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n "\'1,,2\'.split(\',\')" returns "[\'1\', \'\', \'2\']"). The *sep* argument\n may consist of multiple characters (for example,\n "\'1<>2<>3\'.split(\'<>\')" returns "[\'1\', \'2\', \'3\']"). Splitting an\n empty string with a specified separator returns "[\'\']".\n\n For example:\n\n >>> \'1,2,3\'.split(\',\')\n [\'1\', \'2\', \'3\']\n >>> \'1,2,3\'.split(\',\', maxsplit=1)\n [\'1\', \'2,3\']\n >>> \'1,2,,3,\'.split(\',\')\n [\'1\', \'2\', \'\', \'3\', \'\']\n\n If *sep* is not specified or is "None", a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a "None" separator returns "[]".\n\n For example:\n\n >>> \'1 2 3\'.split()\n [\'1\', \'2\', \'3\']\n >>> \'1 2 3\'.split(maxsplit=1)\n [\'1\', \'2 3\']\n >>> \' 1 2 3 \'.split()\n [\'1\', \'2\', \'3\']\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\n This method splits on the following line boundaries. In\n particular, the boundaries are a superset of *universal newlines*.\n\n +-------------------------+-------------------------------+\n | Representation | Description |\n +=========================+===============================+\n | "\\n" | Line Feed |\n +-------------------------+-------------------------------+\n | "\\r" | Carriage Return |\n +-------------------------+-------------------------------+\n | "\\r\\n" | Carriage Return + Line Feed |\n +-------------------------+-------------------------------+\n | "\\v" or "\\x0b" | Line Tabulation |\n +-------------------------+-------------------------------+\n | "\\f" or "\\x0c" | Form Feed |\n +-------------------------+-------------------------------+\n | "\\x1c" | File Separator |\n +-------------------------+-------------------------------+\n | "\\x1d" | Group Separator |\n +-------------------------+-------------------------------+\n | "\\x1e" | Record Separator |\n +-------------------------+-------------------------------+\n | "\\x85" | Next Line (C1 Control Code) |\n +-------------------------+-------------------------------+\n | "\\u2028" | Line Separator |\n +-------------------------+-------------------------------+\n | "\\u2029" | Paragraph Separator |\n +-------------------------+-------------------------------+\n\n Changed in version 3.2: "\\v" and "\\f" added to list of line\n boundaries.\n\n For example:\n\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines()\n [\'ab c\', \'\', \'de fg\', \'kl\']\n >>> \'ab c\\n\\nde fg\\rkl\\r\\n\'.splitlines(keepends=True)\n [\'ab c\\n\', \'\\n\', \'de fg\\r\', \'kl\\r\\n\']\n\n Unlike "split()" when a delimiter string *sep* is given, this\n method returns an empty list for the empty string, and a terminal\n line break does not result in an extra line:\n\n >>> "".splitlines()\n []\n >>> "One line\\n".splitlines()\n [\'One line\']\n\n For comparison, "split(\'\\n\')" gives:\n\n >>> \'\'.split(\'\\n\')\n [\'\']\n >>> \'Two lines\\n\'.split(\'\\n\')\n [\'Two lines\', \'\']\n\nstr.startswith(prefix[, start[, end]])\n\n Return "True" if string starts with the *prefix*, otherwise return\n "False". *prefix* can also be a tuple of prefixes to look for.\n With optional *start*, test string beginning at that position.\n With optional *end*, stop comparing string at that position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or "None", the *chars*\n argument defaults to removing whitespace. The *chars* argument is\n not a prefix or suffix; rather, all combinations of its values are\n stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\n The outermost leading and trailing *chars* argument values are\n stripped from the string. Characters are removed from the leading\n end until reaching a string character that is not contained in the\n set of characters in *chars*. A similar action takes place on the\n trailing end. For example:\n\n >>> comment_string = \'#....... Section 3.2.1 Issue #32 .......\'\n >>> comment_string.strip(\'.#! \')\n \'Section 3.2.1 Issue #32\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa. Note that it is not necessarily true that\n "s.swapcase().swapcase() == s".\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n For example:\n\n >>> \'Hello world\'.title()\n \'Hello World\'\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n ... return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n ... lambda mo: mo.group(0)[0].upper() +\n ... mo.group(0)[1:].lower(),\n ... s)\n ...\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(table)\n\n Return a copy of the string in which each character has been mapped\n through the given translation table. The table must be an object\n that implements indexing via "__getitem__()", typically a *mapping*\n or *sequence*. When indexed by a Unicode ordinal (an integer), the\n table object can do any of the following: return a Unicode ordinal\n or a string, to map the character to one or more other characters;\n return "None", to delete the character from the return string; or\n raise a "LookupError" exception, to map the character to itself.\n\n You can use "str.maketrans()" to create a translation map from\n character-to-character mappings in different formats.\n\n See also the "codecs" module for a more flexible approach to custom\n character mappings.\n\nstr.upper()\n\n Return a copy of the string with all the cased characters [4]\n converted to uppercase. Note that "str.upper().isupper()" might be\n "False" if "s" contains uncased characters or if the Unicode\n category of the resulting character(s) is not "Lu" (Letter,\n uppercase), but e.g. "Lt" (Letter, titlecase).\n\n The uppercasing algorithm used is described in section 3.13 of the\n Unicode Standard.\n\nstr.zfill(width)\n\n Return a copy of the string left filled with ASCII "\'0\'" digits to\n make a string of length *width*. A leading sign prefix\n ("\'+\'"/"\'-\'") is handled by inserting the padding *after* the sign\n character rather than before. The original string is returned if\n *width* is less than or equal to "len(s)".\n\n For example:\n\n >>> "42".zfill(5)\n \'00042\'\n >>> "-42".zfill(5)\n \'-0042\'\n', + 'strings': u'\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "u" | "R" | "U"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= \n longstringchar ::= \n stringescapeseq ::= "\\" \n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= \n longbyteschar ::= \n bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the "stringprefix" or "bytesprefix"\nand the rest of the literal. The source character set is defined by\nthe encoding declaration; it is UTF-8 if no encoding declaration is\ngiven in the source file; see section *Encoding declarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes ("\'") or double quotes ("""). They can also be enclosed\nin matching groups of three single or double quotes (these are\ngenerally referred to as *triple-quoted strings*). The backslash\n("\\") character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with "\'b\'" or "\'B\'"; they produce\nan instance of the "bytes" type instead of the "str" type. They may\nonly contain ASCII characters; bytes with a numeric value of 128 or\ngreater must be expressed with escapes.\n\nAs of Python 3.3 it is possible again to prefix string literals with a\n"u" prefix to simplify maintenance of dual 2.x and 3.x codebases.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter "\'r\'" or "\'R\'"; such strings are called *raw strings* and treat\nbackslashes as literal characters. As a result, in string literals,\n"\'\\U\'" and "\'\\u\'" escapes in raw strings are not treated specially.\nGiven that Python 2.x\'s raw unicode literals behave differently than\nPython 3.x\'s the "\'ur\'" syntax is not supported.\n\nNew in version 3.3: The "\'rb\'" prefix of raw bytes literals has been\nadded as a synonym of "\'br\'".\n\nNew in version 3.3: Support for the unicode legacy literal\n("u\'value\'") was reintroduced to simplify the maintenance of dual\nPython 2.x and 3.x codebases. See **PEP 414** for more information.\n\nIn triple-quoted literals, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the literal. (A "quote" is the character used to open the\nliteral, i.e. either "\'" or """.)\n\nUnless an "\'r\'" or "\'R\'" prefix is present, escape sequences in string\nand bytes literals are interpreted according to rules similar to those\nused by Standard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\newline" | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| "\\\\" | Backslash ("\\") | |\n+-------------------+-----------------------------------+---------+\n| "\\\'" | Single quote ("\'") | |\n+-------------------+-----------------------------------+---------+\n| "\\"" | Double quote (""") | |\n+-------------------+-----------------------------------+---------+\n| "\\a" | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| "\\b" | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| "\\f" | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| "\\n" | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| "\\r" | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| "\\t" | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| "\\v" | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| "\\ooo" | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| "\\xhh" | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| "\\N{name}" | Character named *name* in the | (4) |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| "\\uxxxx" | Character with 16-bit hex value | (5) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| "\\Uxxxxxxxx" | Character with 32-bit hex value | (6) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the\n byte with the given value. In a string literal, these escapes\n denote a Unicode character with the given value.\n\n4. Changed in version 3.3: Support for name aliases [1] has been\n added.\n\n5. Individual code units which form parts of a surrogate pair can\n be encoded using this escape sequence. Exactly four hex digits are\n required.\n\n6. Any Unicode character can be encoded this way. Exactly eight\n hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the result*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw literal, quotes can be escaped with a backslash, but the\nbackslash remains in the result; for example, "r"\\""" is a valid\nstring literal consisting of two characters: a backslash and a double\nquote; "r"\\"" is not a valid string literal (even a raw string cannot\nend in an odd number of backslashes). Specifically, *a raw literal\ncannot end in a single backslash* (since the backslash would escape\nthe following quote character). Note also that a single backslash\nfollowed by a newline is interpreted as those two characters as part\nof the literal, *not* as a line continuation.\n', + 'subscriptions': u'\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription\n(lists or dictionaries for example). User-defined objects can support\nsubscription by defining a "__getitem__()" method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer or a slice (as discussed in the following section).\n\nThe formal syntax makes no special provision for negative indices in\nsequences; however, built-in sequences all provide a "__getitem__()"\nmethod that interprets negative indices by adding the length of the\nsequence to the index (so that "x[-1]" selects the last item of "x").\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero). Since the support for\nnegative indices and slicing occurs in the object\'s "__getitem__()"\nmethod, subclasses overriding this method will need to explicitly add\nthat support.\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n', + 'truth': u'\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an "if" or\n"while" condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* "None"\n\n* "False"\n\n* zero of any numeric type, for example, "0", "0.0", "0j".\n\n* any empty sequence, for example, "\'\'", "()", "[]".\n\n* any empty mapping, for example, "{}".\n\n* instances of user-defined classes, if the class defines a\n "__bool__()" or "__len__()" method, when that method returns the\n integer zero or "bool" value "False". [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn "0" or "False" for false and "1" or "True" for true, unless\notherwise stated. (Important exception: the Boolean operations "or"\nand "and" always return one of their operands.)\n', + 'try': u'\nThe "try" statement\n*******************\n\nThe "try" statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" identifier]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe "except" clause(s) specify one or more exception handlers. When no\nexception occurs in the "try" clause, no exception handler is\nexecuted. When an exception occurs in the "try" suite, a search for an\nexception handler is started. This search inspects the except clauses\nin turn until one is found that matches the exception. An expression-\nless except clause, if present, must be last; it matches any\nexception. For an except clause with an expression, that expression\nis evaluated, and the clause matches the exception if the resulting\nobject is "compatible" with the exception. An object is compatible\nwith an exception if it is the class or a base class of the exception\nobject or a tuple containing an item compatible with the exception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire "try" statement raised\nthe exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the "as" keyword in that except clause, if\npresent, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using "as target", it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the "sys" module and can be accessed via\n"sys.exc_info()". "sys.exc_info()" returns a 3-tuple consisting of the\nexception class, the exception instance and a traceback object (see\nsection *The standard type hierarchy*) identifying the point in the\nprogram where the exception occurred. "sys.exc_info()" values are\nrestored to their previous values (before the call) when returning\nfrom a function that handled an exception.\n\nThe optional "else" clause is executed if and when control flows off\nthe end of the "try" clause. [2] Exceptions in the "else" clause are\nnot handled by the preceding "except" clauses.\n\nIf "finally" is present, it specifies a \'cleanup\' handler. The "try"\nclause is executed, including any "except" and "else" clauses. If an\nexception occurs in any of the clauses and is not handled, the\nexception is temporarily saved. The "finally" clause is executed. If\nthere is a saved exception it is re-raised at the end of the "finally"\nclause. If the "finally" clause raises another exception, the saved\nexception is set as the context of the new exception. If the "finally"\nclause executes a "return" or "break" statement, the saved exception\nis discarded:\n\n >>> def f():\n ... try:\n ... 1/0\n ... finally:\n ... return 42\n ...\n >>> f()\n 42\n\nThe exception information is not available to the program during\nexecution of the "finally" clause.\n\nWhen a "return", "break" or "continue" statement is executed in the\n"try" suite of a "try"..."finally" statement, the "finally" clause is\nalso executed \'on the way out.\' A "continue" statement is illegal in\nthe "finally" clause. (The reason is a problem with the current\nimplementation --- this restriction may be lifted in the future).\n\nThe return value of a function is determined by the last "return"\nstatement executed. Since the "finally" clause always executes, a\n"return" statement executed in the "finally" clause will always be the\nlast one executed:\n\n >>> def foo():\n ... try:\n ... return \'try\'\n ... finally:\n ... return \'finally\'\n ...\n >>> foo()\n \'finally\'\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the "raise" statement to\ngenerate exceptions may be found in section *The raise statement*.\n', + 'types': u'\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name "None". It\n is used to signify the absence of a value in many situations, e.g.,\n it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n "NotImplemented". Numeric methods and rich comparison methods\n should return this value if they do not implement the operation for\n the operands provided. (The interpreter will then try the\n reflected operation, or some other fallback, depending on the\n operator.) Its truth value is true.\n\n See *Implementing the arithmetic operations* for more details.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal "..." or the\n built-in name "Ellipsis". Its truth value is true.\n\n"numbers.Number"\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n "numbers.Integral"\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers ("int")\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans ("bool")\n These represent the truth values False and True. The two\n objects representing the values "False" and "True" are the\n only Boolean objects. The Boolean type is a subtype of the\n integer type, and Boolean values behave like the values 0 and\n 1, respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ""False"" or\n ""True"" are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n "numbers.Real" ("float")\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these are\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n "numbers.Complex" ("complex")\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number "z" can be retrieved through the read-only\n attributes "z.real" and "z.imag".\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function "len()" returns the number of items\n of a sequence. When the length of a sequence is *n*, the index set\n contains the numbers 0, 1, ..., *n*-1. Item *i* of sequence *a* is\n selected by "a[i]".\n\n Sequences also support slicing: "a[i:j]" selects all items with\n index *k* such that *i* "<=" *k* "<" *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: "a[i:j:k]" selects all items of *a* with index *x* where\n "x = i + n*k", *n* ">=" "0" and *i* "<=" *x* "<" *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n A string is a sequence of values that represent Unicode code\n points. All the code points in the range "U+0000 - U+10FFFF"\n can be represented in a string. Python doesn\'t have a "char"\n type; instead, every code point in the string is represented\n as a string object with length "1". The built-in function\n "ord()" converts a code point from its string form to an\n integer in the range "0 - 10FFFF"; "chr()" converts an\n integer in the range "0 - 10FFFF" to the corresponding length\n "1" string object. "str.encode()" can be used to convert a\n "str" to "bytes" using the given text encoding, and\n "bytes.decode()" can be used to achieve the opposite.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like "b\'abc\'") and the built-in function\n "bytes()" can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the "decode()"\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and "del" (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in "bytearray()" constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module "array" provides an additional example of a\n mutable sequence type, as does the "collections" module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function "len()"\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., "1" and\n "1.0"), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n "set()" constructor and can be modified afterwards by several\n methods, such as "add()".\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in "frozenset()" constructor. As a frozenset is immutable\n and *hashable*, it can be used again as an element of another\n set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation "a[k]" selects the item indexed by "k"\n from the mapping "a"; this can be used in expressions and as the\n target of assignments or "del" statements. The built-in function\n "len()" returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., "1" and "1.0")\n then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the "{...}"\n notation (see section *Dictionary displays*).\n\n The extension modules "dbm.ndbm" and "dbm.gnu" provide\n additional examples of mapping types, as does the "collections"\n module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | "__doc__" | The function\'s documentation | Writable |\n | | string, or "None" if | |\n | | unavailable; not inherited by | |\n | | subclasses | |\n +---------------------------+---------------------------------+-------------+\n | "__name__" | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | "__qualname__" | The function\'s *qualified name* | Writable |\n | | New in version 3.3. | |\n +---------------------------+---------------------------------+-------------+\n | "__module__" | The name of the module the | Writable |\n | | function was defined in, or | |\n | | "None" if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | "__defaults__" | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or "None" if no arguments have | |\n | | a default value | |\n +---------------------------+---------------------------------+-------------+\n | "__code__" | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | "__globals__" | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | "__dict__" | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | "__closure__" | "None" or a tuple of cells that | Read-only |\n | | contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | "__annotations__" | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | and "\'return\'" for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | "__kwdefaults__" | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: "__self__" is the class instance\n object, "__func__" is the function object; "__doc__" is the\n method\'s documentation (same as "__func__.__doc__"); "__name__"\n is the method name (same as "__func__.__name__"); "__module__"\n is the name of the module the method was defined in, or "None"\n if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its "__self__" attribute is the instance, and the method object\n is said to be bound. The new method\'s "__func__" attribute is\n the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the "__func__"\n attribute of the new instance is not the original method object\n but its "__func__" attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its "__self__" attribute\n is the class itself, and its "__func__" attribute is the\n function object underlying the class method.\n\n When an instance method object is called, the underlying\n function ("__func__") is called, inserting the class instance\n ("__self__") in front of the argument list. For instance, when\n "C" is a class which contains a definition for a function "f()",\n and "x" is an instance of "C", calling "x.f(1)" is equivalent to\n calling "C.f(x, 1)".\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in "__self__" will actually\n be the class itself, so that calling either "x.f(1)" or "C.f(1)"\n is equivalent to calling "f(C,1)" where "f" is the underlying\n function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the "yield" statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s "iterator.__next__()" method will cause the\n function to execute until it provides a value using the "yield"\n statement. When the function executes a "return" statement or\n falls off the end, a "StopIteration" exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Coroutine functions\n A function or method which is defined using "async def" is\n called a *coroutine function*. Such a function, when called,\n returns a *coroutine* object. It may contain "await"\n expressions, as well as "async with" and "async for" statements.\n See also the *Coroutine Objects* section.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are "len()" and "math.sin()"\n ("math" is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: "__doc__" is the function\'s documentation\n string, or "None" if unavailable; "__name__" is the function\'s\n name; "__self__" is set to "None" (but see the next item);\n "__module__" is the name of the module the function was defined\n in or "None" if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n "alist.append()", assuming *alist* is a list object. In this\n case, the special read-only attribute "__self__" is set to the\n object denoted by *alist*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override "__new__()". The arguments of the\n call are passed to "__new__()" and, in the typical case, to\n "__init__()" to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a "__call__()" method in their class.\n\nModules\n Modules are a basic organizational unit of Python code, and are\n created by the *import system* as invoked either by the "import"\n statement (see "import"), or by calling functions such as\n "importlib.import_module()" and built-in "__import__()". A module\n object has a namespace implemented by a dictionary object (this is\n the dictionary referenced by the "__globals__" attribute of\n functions defined in the module). Attribute references are\n translated to lookups in this dictionary, e.g., "m.x" is equivalent\n to "m.__dict__["x"]". A module object does not contain the code\n object used to initialize the module (since it isn\'t needed once\n the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., "m.x = 1" is equivalent to "m.__dict__["x"] = 1".\n\n Special read-only attribute: "__dict__" is the module\'s namespace\n as a dictionary object.\n\n **CPython implementation detail:** Because of the way CPython\n clears module dictionaries, the module dictionary will be cleared\n when the module falls out of scope even if the dictionary still has\n live references. To avoid this, copy the dictionary or keep the\n module around while using its dictionary directly.\n\n Predefined (writable) attributes: "__name__" is the module\'s name;\n "__doc__" is the module\'s documentation string, or "None" if\n unavailable; "__file__" is the pathname of the file from which the\n module was loaded, if it was loaded from a file. The "__file__"\n attribute may be missing for certain types of modules, such as C\n modules that are statically linked into the interpreter; for\n extension modules loaded dynamically from a shared library, it is\n the pathname of the shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., "C.x" is translated to\n "C.__dict__["x"]" (although there are a number of hooks which allow\n for other means of locating attributes). When the attribute name is\n not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n https://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class "C", say) would yield a\n class method object, it is transformed into an instance method\n object whose "__self__" attributes is "C". When it would yield a\n static method object, it is transformed into the object wrapped by\n the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its "__dict__".\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: "__name__" is the class name; "__module__" is\n the module name in which the class was defined; "__dict__" is the\n dictionary containing the class\'s namespace; "__bases__" is a tuple\n (possibly empty or a singleton) containing the base classes, in the\n order of their occurrence in the base class list; "__doc__" is the\n class\'s documentation string, or None if undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose "__self__" attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s "__dict__".\n If no class attribute is found, and the object\'s class has a\n "__getattr__()" method, that is called to satisfy the lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n "__setattr__()" or "__delattr__()" method, this is called instead\n of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: "__dict__" is the attribute dictionary;\n "__class__" is the instance\'s class.\n\nI/O objects (also known as file objects)\n A *file object* represents an open file. Various shortcuts are\n available to create file objects: the "open()" built-in function,\n and also "os.popen()", "os.fdopen()", and the "makefile()" method\n of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects "sys.stdin", "sys.stdout" and "sys.stderr" are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n "io.TextIOBase" abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: "co_name" gives the function name;\n "co_argcount" is the number of positional arguments (including\n arguments with default values); "co_nlocals" is the number of\n local variables used by the function (including arguments);\n "co_varnames" is a tuple containing the names of the local\n variables (starting with the argument names); "co_cellvars" is a\n tuple containing the names of local variables that are\n referenced by nested functions; "co_freevars" is a tuple\n containing the names of free variables; "co_code" is a string\n representing the sequence of bytecode instructions; "co_consts"\n is a tuple containing the literals used by the bytecode;\n "co_names" is a tuple containing the names used by the bytecode;\n "co_filename" is the filename from which the code was compiled;\n "co_firstlineno" is the first line number of the function;\n "co_lnotab" is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); "co_stacksize" is the required stack size\n (including local variables); "co_flags" is an integer encoding a\n number of flags for the interpreter.\n\n The following flag bits are defined for "co_flags": bit "0x04"\n is set if the function uses the "*arguments" syntax to accept an\n arbitrary number of positional arguments; bit "0x08" is set if\n the function uses the "**keywords" syntax to accept arbitrary\n keyword arguments; bit "0x20" is set if the function is a\n generator.\n\n Future feature declarations ("from __future__ import division")\n also use bits in "co_flags" to indicate whether a code object\n was compiled with a particular feature enabled: bit "0x2000" is\n set if the function was compiled with future division enabled;\n bits "0x10" and "0x1000" were used in earlier versions of\n Python.\n\n Other bits in "co_flags" are reserved for internal use.\n\n If a code object represents a function, the first item in\n "co_consts" is the documentation string of the function, or\n "None" if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: "f_back" is to the previous stack\n frame (towards the caller), or "None" if this is the bottom\n stack frame; "f_code" is the code object being executed in this\n frame; "f_locals" is the dictionary used to look up local\n variables; "f_globals" is used for global variables;\n "f_builtins" is used for built-in (intrinsic) names; "f_lasti"\n gives the precise instruction (this is an index into the\n bytecode string of the code object).\n\n Special writable attributes: "f_trace", if not "None", is a\n function called at the start of each source code line (this is\n used by the debugger); "f_lineno" is the current line number of\n the frame --- writing to this from within a trace function jumps\n to the given line (only for the bottom-most frame). A debugger\n can implement a Jump command (aka Set Next Statement) by writing\n to f_lineno.\n\n Frame objects support one method:\n\n frame.clear()\n\n This method clears all references to local variables held by\n the frame. Also, if the frame belonged to a generator, the\n generator is finalized. This helps break reference cycles\n involving frame objects (for example when catching an\n exception and storing its traceback for later use).\n\n "RuntimeError" is raised if the frame is currently executing.\n\n New in version 3.4.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by "sys.exc_info()". When the program contains no\n suitable handler, the stack trace is written (nicely formatted)\n to the standard error stream; if the interpreter is interactive,\n it is also made available to the user as "sys.last_traceback".\n\n Special read-only attributes: "tb_next" is the next level in the\n stack trace (towards the frame where the exception occurred), or\n "None" if there is no next level; "tb_frame" points to the\n execution frame of the current level; "tb_lineno" gives the line\n number where the exception occurred; "tb_lasti" indicates the\n precise instruction. The line number and last instruction in\n the traceback may differ from the line number of its frame\n object if the exception occurred in a "try" statement with no\n matching except clause or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for "__getitem__()"\n methods. They are also created by the built-in "slice()"\n function.\n\n Special read-only attributes: "start" is the lower bound; "stop"\n is the upper bound; "step" is the step value; each is "None" if\n omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n "staticmethod()" constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in "classmethod()" constructor.\n', + 'typesfunctions': u'\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: "func(argument-list)".\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n', + 'typesmapping': u'\nMapping Types --- "dict"\n************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built-\nin "list", "set", and "tuple" classes, and the "collections" module.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as "1" and "1.0") then they can be used interchangeably to index\nthe same dictionary entry. (Note however, that since computers store\nfloating-point numbers as approximations it is usually unwise to use\nthem as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of "key:\nvalue" pairs within braces, for example: "{\'jack\': 4098, \'sjoerd\':\n4127}" or "{4098: \'jack\', 4127: \'sjoerd\'}", or by the "dict"\nconstructor.\n\nclass class dict(**kwarg)\nclass class dict(mapping, **kwarg)\nclass class dict(iterable, **kwarg)\n\n Return a new dictionary initialized from an optional positional\n argument and a possibly empty set of keyword arguments.\n\n If no positional argument is given, an empty dictionary is created.\n If a positional argument is given and it is a mapping object, a\n dictionary is created with the same key-value pairs as the mapping\n object. Otherwise, the positional argument must be an *iterable*\n object. Each item in the iterable must itself be an iterable with\n exactly two objects. The first object of each item becomes a key\n in the new dictionary, and the second object the corresponding\n value. If a key occurs more than once, the last value for that key\n becomes the corresponding value in the new dictionary.\n\n If keyword arguments are given, the keyword arguments and their\n values are added to the dictionary created from the positional\n argument. If a key being added is already present, the value from\n the keyword argument replaces the value from the positional\n argument.\n\n To illustrate, the following examples all return a dictionary equal\n to "{"one": 1, "two": 2, "three": 3}":\n\n >>> a = dict(one=1, two=2, three=3)\n >>> b = {\'one\': 1, \'two\': 2, \'three\': 3}\n >>> c = dict(zip([\'one\', \'two\', \'three\'], [1, 2, 3]))\n >>> d = dict([(\'two\', 2), (\'one\', 1), (\'three\', 3)])\n >>> e = dict({\'three\': 3, \'one\': 1, \'two\': 2})\n >>> a == b == c == d == e\n True\n\n Providing keyword arguments as in the first example only works for\n keys that are valid Python identifiers. Otherwise, any valid keys\n can be used.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a "KeyError" if\n *key* is not in the map.\n\n If a subclass of dict defines a method "__missing__()" and *key*\n is not present, the "d[key]" operation calls that method with\n the key *key* as argument. The "d[key]" operation then returns\n or raises whatever is returned or raised by the\n "__missing__(key)" call. No other operations or methods invoke\n "__missing__()". If "__missing__()" is not defined, "KeyError"\n is raised. "__missing__()" must be a method; it cannot be an\n instance variable:\n\n >>> class Counter(dict):\n ... def __missing__(self, key):\n ... return 0\n >>> c = Counter()\n >>> c[\'red\']\n 0\n >>> c[\'red\'] += 1\n >>> c[\'red\']\n 1\n\n The example above shows part of the implementation of\n "collections.Counter". A different "__missing__" method is used\n by "collections.defaultdict".\n\n d[key] = value\n\n Set "d[key]" to *value*.\n\n del d[key]\n\n Remove "d[key]" from *d*. Raises a "KeyError" if *key* is not\n in the map.\n\n key in d\n\n Return "True" if *d* has a key *key*, else "False".\n\n key not in d\n\n Equivalent to "not key in d".\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for "iter(d.keys())".\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n "fromkeys()" is a class method that returns a new dictionary.\n *value* defaults to "None".\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to "None", so\n that this method never raises a "KeyError".\n\n items()\n\n Return a new view of the dictionary\'s items ("(key, value)"\n pairs). See the *documentation of view objects*.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See the\n *documentation of view objects*.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a "KeyError" is raised.\n\n popitem()\n\n Remove and return an arbitrary "(key, value)" pair from the\n dictionary.\n\n "popitem()" is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling "popitem()" raises a "KeyError".\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to "None".\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return "None".\n\n "update()" accepts either another dictionary object or an\n iterable of key/value pairs (as tuples or other iterables of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: "d.update(red=1,\n blue=2)".\n\n values()\n\n Return a new view of the dictionary\'s values. See the\n *documentation of view objects*.\n\n Dictionaries compare equal if and only if they have the same "(key,\n value)" pairs. Order comparisons (\'<\', \'<=\', \'>=\', \'>\') raise\n "TypeError".\n\nSee also: "types.MappingProxyType" can be used to create a read-only\n view of a "dict".\n\n\nDictionary view objects\n=======================\n\nThe objects returned by "dict.keys()", "dict.values()" and\n"dict.items()" are *view objects*. They provide a dynamic view on the\ndictionary\'s entries, which means that when the dictionary changes,\nthe view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of "(key, value)") in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of "(value, key)" pairs using\n "zip()": "pairs = zip(d.values(), d.keys())". Another way to\n create the same list is "pairs = [(v, k) for (k, v) in d.items()]".\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a "RuntimeError" or fail to iterate over all entries.\n\nx in dictview\n\n Return "True" if *x* is in the underlying dictionary\'s keys, values\n or items (in the latter case, *x* should be a "(key, value)"\n tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that "(key, value)" pairs are unique\nand hashable, then the items view is also set-like. (Values views are\nnot treated as set-like since the entries are generally not unique.)\nFor set-like views, all of the operations defined for the abstract\nbase class "collections.abc.Set" are available (for example, "==",\n"<", or "^").\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n >>> keys ^ {\'sausage\', \'juice\'}\n {\'juice\', \'sausage\', \'bacon\', \'spam\'}\n', + 'typesmethods': u'\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as "append()" on lists)\nand class instance methods. Built-in methods are described with the\ntypes that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the "self"\nargument to the argument list. Bound methods have two special read-\nonly attributes: "m.__self__" is the object on which the method\noperates, and "m.__func__" is the function implementing the method.\nCalling "m(arg-1, arg-2, ..., arg-n)" is completely equivalent to\ncalling "m.__func__(m.__self__, arg-1, arg-2, ..., arg-n)".\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object ("meth.__func__"), setting method\nattributes on bound methods is disallowed. Attempting to set an\nattribute on a method results in an "AttributeError" being raised. In\norder to set a method attribute, you need to explicitly set it on the\nunderlying function object:\n\n >>> class C:\n ... def method(self):\n ... pass\n ...\n >>> c = C()\n >>> c.method.whoami = \'my name is method\' # can\'t set on the method\n Traceback (most recent call last):\n File "", line 1, in \n AttributeError: \'method\' object has no attribute \'whoami\'\n >>> c.method.__func__.whoami = \'my name is method\'\n >>> c.method.whoami\n \'my name is method\'\n\nSee *The standard type hierarchy* for more information.\n', + 'typesmodules': u'\nModules\n*******\n\nThe only special operation on a module is attribute access: "m.name",\nwhere *m* is a module and *name* accesses a name defined in *m*\'s\nsymbol table. Module attributes can be assigned to. (Note that the\n"import" statement is not, strictly speaking, an operation on a module\nobject; "import foo" does not require a module object named *foo* to\nexist, rather it requires an (external) *definition* for a module\nnamed *foo* somewhere.)\n\nA special attribute of every module is "__dict__". This is the\ndictionary containing the module\'s symbol table. Modifying this\ndictionary will actually change the module\'s symbol table, but direct\nassignment to the "__dict__" attribute is not possible (you can write\n"m.__dict__[\'a\'] = 1", which defines "m.a" to be "1", but you can\'t\nwrite "m.__dict__ = {}"). Modifying "__dict__" directly is not\nrecommended.\n\nModules built into the interpreter are written like this: "". If loaded from a file, they are written as\n"".\n', + 'typesseq': u'\nSequence Types --- "list", "tuple", "range"\n*******************************************\n\nThere are three basic sequence types: lists, tuples, and range\nobjects. Additional sequence types tailored for processing of *binary\ndata* and *text strings* are described in dedicated sections.\n\n\nCommon Sequence Operations\n==========================\n\nThe operations in the following table are supported by most sequence\ntypes, both mutable and immutable. The "collections.abc.Sequence" ABC\nis provided to make it easier to correctly implement these operations\non custom sequence types.\n\nThis table lists the sequence operations sorted in ascending priority.\nIn the table, *s* and *t* are sequences of the same type, *n*, *i*,\n*j* and *k* are integers and *x* is an arbitrary object that meets any\ntype and value restrictions imposed by *s*.\n\nThe "in" and "not in" operations have the same priorities as the\ncomparison operations. The "+" (concatenation) and "*" (repetition)\noperations have the same priority as the corresponding numeric\noperations.\n\n+----------------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+============================+==================================+============+\n| "x in s" | "True" if an item of *s* is | (1) |\n| | equal to *x*, else "False" | |\n+----------------------------+----------------------------------+------------+\n| "x not in s" | "False" if an item of *s* is | (1) |\n| | equal to *x*, else "True" | |\n+----------------------------+----------------------------------+------------+\n| "s + t" | the concatenation of *s* and *t* | (6)(7) |\n+----------------------------+----------------------------------+------------+\n| "s * n" or "n * s" | equivalent to adding *s* to | (2)(7) |\n| | itself *n* times | |\n+----------------------------+----------------------------------+------------+\n| "s[i]" | *i*th item of *s*, origin 0 | (3) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j]" | slice of *s* from *i* to *j* | (3)(4) |\n+----------------------------+----------------------------------+------------+\n| "s[i:j:k]" | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+----------------------------+----------------------------------+------------+\n| "len(s)" | length of *s* | |\n+----------------------------+----------------------------------+------------+\n| "min(s)" | smallest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "max(s)" | largest item of *s* | |\n+----------------------------+----------------------------------+------------+\n| "s.index(x[, i[, j]])" | index of the first occurrence of | (8) |\n| | *x* in *s* (at or after index | |\n| | *i* and before index *j*) | |\n+----------------------------+----------------------------------+------------+\n| "s.count(x)" | total number of occurrences of | |\n| | *x* in *s* | |\n+----------------------------+----------------------------------+------------+\n\nSequences of the same type also support comparisons. In particular,\ntuples and lists are compared lexicographically by comparing\ncorresponding elements. This means that to compare equal, every\nelement must compare equal and the two sequences must be of the same\ntype and have the same length. (For full details see *Comparisons* in\nthe language reference.)\n\nNotes:\n\n1. While the "in" and "not in" operations are used only for simple\n containment testing in the general case, some specialised sequences\n (such as "str", "bytes" and "bytearray") also use them for\n subsequence testing:\n\n >>> "gg" in "eggs"\n True\n\n2. Values of *n* less than "0" are treated as "0" (which yields an\n empty sequence of the same type as *s*). Note that items in the\n sequence *s* are not copied; they are referenced multiple times.\n This often haunts new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that "[[]]" is a one-element list containing\n an empty list, so all three elements of "[[]] * 3" are references\n to this single empty list. Modifying any of the elements of\n "lists" modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n Further explanation is available in the FAQ entry *How do I create\n a multidimensional list?*.\n\n3. If *i* or *j* is negative, the index is relative to the end of\n the string: "len(s) + i" or "len(s) + j" is substituted. But note\n that "-0" is still "0".\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that "i <= k < j". If *i* or *j* is\n greater than "len(s)", use "len(s)". If *i* is omitted or "None",\n use "0". If *j* is omitted or "None", use "len(s)". If *i* is\n greater than or equal to *j*, the slice is empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index "x = i + n*k" such that "0 <= n <\n (j-i)/k". In other words, the indices are "i", "i+k", "i+2*k",\n "i+3*k" and so on, stopping when *j* is reached (but never\n including *j*). If *i* or *j* is greater than "len(s)", use\n "len(s)". If *i* or *j* are omitted or "None", they become "end"\n values (which end depends on the sign of *k*). Note, *k* cannot be\n zero. If *k* is "None", it is treated like "1".\n\n6. Concatenating immutable sequences always results in a new\n object. This means that building up a sequence by repeated\n concatenation will have a quadratic runtime cost in the total\n sequence length. To get a linear runtime cost, you must switch to\n one of the alternatives below:\n\n * if concatenating "str" objects, you can build a list and use\n "str.join()" at the end or else write to an "io.StringIO"\n instance and retrieve its value when complete\n\n * if concatenating "bytes" objects, you can similarly use\n "bytes.join()" or "io.BytesIO", or you can do in-place\n concatenation with a "bytearray" object. "bytearray" objects are\n mutable and have an efficient overallocation mechanism\n\n * if concatenating "tuple" objects, extend a "list" instead\n\n * for other types, investigate the relevant class documentation\n\n7. Some sequence types (such as "range") only support item\n sequences that follow specific patterns, and hence don\'t support\n sequence concatenation or repetition.\n\n8. "index" raises "ValueError" when *x* is not found in *s*. When\n supported, the additional arguments to the index method allow\n efficient searching of subsections of the sequence. Passing the\n extra arguments is roughly equivalent to using "s[i:j].index(x)",\n only without copying any data and with the returned index being\n relative to the start of the sequence rather than the start of the\n slice.\n\n\nImmutable Sequence Types\n========================\n\nThe only operation that immutable sequence types generally implement\nthat is not also implemented by mutable sequence types is support for\nthe "hash()" built-in.\n\nThis support allows immutable sequences, such as "tuple" instances, to\nbe used as "dict" keys and stored in "set" and "frozenset" instances.\n\nAttempting to hash an immutable sequence that contains unhashable\nvalues will result in "TypeError".\n\n\nMutable Sequence Types\n======================\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" or "s += t" | extends *s* with the contents of | |\n| | *t* (for the most part the same | |\n| | as "s[len(s):len(s)] = t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s *= n" | updates *s* with its contents | (6) |\n| | repeated *n* times | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n\n6. The value *n* is an integer, or an object implementing\n "__index__()". Zero and negative values of *n* clear the sequence.\n Items in the sequence are not copied; they are referenced multiple\n times, as explained for "s * n" under *Common Sequence Operations*.\n\n\nLists\n=====\n\nLists are mutable sequences, typically used to store collections of\nhomogeneous items (where the precise degree of similarity will vary by\napplication).\n\nclass class list([iterable])\n\n Lists may be constructed in several ways:\n\n * Using a pair of square brackets to denote the empty list: "[]"\n\n * Using square brackets, separating items with commas: "[a]",\n "[a, b, c]"\n\n * Using a list comprehension: "[x for x in iterable]"\n\n * Using the type constructor: "list()" or "list(iterable)"\n\n The constructor builds a list whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a list, a copy is made and\n returned, similar to "iterable[:]". For example, "list(\'abc\')"\n returns "[\'a\', \'b\', \'c\']" and "list( (1, 2, 3) )" returns "[1, 2,\n 3]". If no argument is given, the constructor creates a new empty\n list, "[]".\n\n Many other operations also produce lists, including the "sorted()"\n built-in.\n\n Lists implement all of the *common* and *mutable* sequence\n operations. Lists also provide the following additional method:\n\n sort(*, key=None, reverse=None)\n\n This method sorts the list in place, using only "<" comparisons\n between items. Exceptions are not suppressed - if any comparison\n operations fail, the entire sort operation will fail (and the\n list will likely be left in a partially modified state).\n\n "sort()" accepts two arguments that can only be passed by\n keyword (*keyword-only arguments*):\n\n *key* specifies a function of one argument that is used to\n extract a comparison key from each list element (for example,\n "key=str.lower"). The key corresponding to each item in the list\n is calculated once and then used for the entire sorting process.\n The default value of "None" means that list items are sorted\n directly without calculating a separate key value.\n\n The "functools.cmp_to_key()" utility is available to convert a\n 2.x style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to "True", then the list\n elements are sorted as if each comparison were reversed.\n\n This method modifies the sequence in place for economy of space\n when sorting a large sequence. To remind users that it operates\n by side effect, it does not return the sorted sequence (use\n "sorted()" to explicitly request a new sorted list instance).\n\n The "sort()" method is guaranteed to be stable. A sort is\n stable if it guarantees not to change the relative order of\n elements that compare equal --- this is helpful for sorting in\n multiple passes (for example, sort by department, then by salary\n grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises "ValueError" if it can detect\n that the list has been mutated during a sort.\n\n\nTuples\n======\n\nTuples are immutable sequences, typically used to store collections of\nheterogeneous data (such as the 2-tuples produced by the "enumerate()"\nbuilt-in). Tuples are also used for cases where an immutable sequence\nof homogeneous data is needed (such as allowing storage in a "set" or\n"dict" instance).\n\nclass class tuple([iterable])\n\n Tuples may be constructed in a number of ways:\n\n * Using a pair of parentheses to denote the empty tuple: "()"\n\n * Using a trailing comma for a singleton tuple: "a," or "(a,)"\n\n * Separating items with commas: "a, b, c" or "(a, b, c)"\n\n * Using the "tuple()" built-in: "tuple()" or "tuple(iterable)"\n\n The constructor builds a tuple whose items are the same and in the\n same order as *iterable*\'s items. *iterable* may be either a\n sequence, a container that supports iteration, or an iterator\n object. If *iterable* is already a tuple, it is returned\n unchanged. For example, "tuple(\'abc\')" returns "(\'a\', \'b\', \'c\')"\n and "tuple( [1, 2, 3] )" returns "(1, 2, 3)". If no argument is\n given, the constructor creates a new empty tuple, "()".\n\n Note that it is actually the comma which makes a tuple, not the\n parentheses. The parentheses are optional, except in the empty\n tuple case, or when they are needed to avoid syntactic ambiguity.\n For example, "f(a, b, c)" is a function call with three arguments,\n while "f((a, b, c))" is a function call with a 3-tuple as the sole\n argument.\n\n Tuples implement all of the *common* sequence operations.\n\nFor heterogeneous collections of data where access by name is clearer\nthan access by index, "collections.namedtuple()" may be a more\nappropriate choice than a simple tuple object.\n\n\nRanges\n======\n\nThe "range" type represents an immutable sequence of numbers and is\ncommonly used for looping a specific number of times in "for" loops.\n\nclass class range(stop)\nclass class range(start, stop[, step])\n\n The arguments to the range constructor must be integers (either\n built-in "int" or any object that implements the "__index__"\n special method). If the *step* argument is omitted, it defaults to\n "1". If the *start* argument is omitted, it defaults to "0". If\n *step* is zero, "ValueError" is raised.\n\n For a positive *step*, the contents of a range "r" are determined\n by the formula "r[i] = start + step*i" where "i >= 0" and "r[i] <\n stop".\n\n For a negative *step*, the contents of the range are still\n determined by the formula "r[i] = start + step*i", but the\n constraints are "i >= 0" and "r[i] > stop".\n\n A range object will be empty if "r[0]" does not meet the value\n constraint. Ranges do support negative indices, but these are\n interpreted as indexing from the end of the sequence determined by\n the positive indices.\n\n Ranges containing absolute values larger than "sys.maxsize" are\n permitted but some features (such as "len()") may raise\n "OverflowError".\n\n Range examples:\n\n >>> list(range(10))\n [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n >>> list(range(1, 11))\n [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n >>> list(range(0, 30, 5))\n [0, 5, 10, 15, 20, 25]\n >>> list(range(0, 10, 3))\n [0, 3, 6, 9]\n >>> list(range(0, -10, -1))\n [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]\n >>> list(range(0))\n []\n >>> list(range(1, 0))\n []\n\n Ranges implement all of the *common* sequence operations except\n concatenation and repetition (due to the fact that range objects\n can only represent sequences that follow a strict pattern and\n repetition and concatenation will usually violate that pattern).\n\nThe advantage of the "range" type over a regular "list" or "tuple" is\nthat a "range" object will always take the same (small) amount of\nmemory, no matter the size of the range it represents (as it only\nstores the "start", "stop" and "step" values, calculating individual\nitems and subranges as needed).\n\nRange objects implement the "collections.abc.Sequence" ABC, and\nprovide features such as containment tests, element index lookup,\nslicing and support for negative indices (see *Sequence Types ---\nlist, tuple, range*):\n\n>>> r = range(0, 20, 2)\n>>> r\nrange(0, 20, 2)\n>>> 11 in r\nFalse\n>>> 10 in r\nTrue\n>>> r.index(10)\n5\n>>> r[5]\n10\n>>> r[:5]\nrange(0, 10, 2)\n>>> r[-1]\n18\n\nTesting range objects for equality with "==" and "!=" compares them as\nsequences. That is, two range objects are considered equal if they\nrepresent the same sequence of values. (Note that two range objects\nthat compare equal might have different "start", "stop" and "step"\nattributes, for example "range(0) == range(2, 1, 3)" or "range(0, 3,\n2) == range(0, 4, 2)".)\n\nChanged in version 3.2: Implement the Sequence ABC. Support slicing\nand negative indices. Test "int" objects for membership in constant\ntime instead of iterating through all items.\n\nChanged in version 3.3: Define \'==\' and \'!=\' to compare range objects\nbased on the sequence of values they define (instead of comparing\nbased on object identity).\n\nNew in version 3.3: The "start", "stop" and "step" attributes.\n', + 'typesseq-mutable': u'\nMutable Sequence Types\n**********************\n\nThe operations in the following table are defined on mutable sequence\ntypes. The "collections.abc.MutableSequence" ABC is provided to make\nit easier to correctly implement these operations on custom sequence\ntypes.\n\nIn the table *s* is an instance of a mutable sequence type, *t* is any\niterable object and *x* is an arbitrary object that meets any type and\nvalue restrictions imposed by *s* (for example, "bytearray" only\naccepts integers that meet the value restriction "0 <= x <= 255").\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| "s[i] = x" | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j] = t" | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j]" | same as "s[i:j] = []" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s[i:j:k] = t" | the elements of "s[i:j:k]" are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "del s[i:j:k]" | removes the elements of | |\n| | "s[i:j:k]" from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.append(x)" | appends *x* to the end of the | |\n| | sequence (same as | |\n| | "s[len(s):len(s)] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.clear()" | removes all items from "s" (same | (5) |\n| | as "del s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.copy()" | creates a shallow copy of "s" | (5) |\n| | (same as "s[:]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.extend(t)" or "s += t" | extends *s* with the contents of | |\n| | *t* (for the most part the same | |\n| | as "s[len(s):len(s)] = t") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s *= n" | updates *s* with its contents | (6) |\n| | repeated *n* times | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.insert(i, x)" | inserts *x* into *s* at the | |\n| | index given by *i* (same as | |\n| | "s[i:i] = [x]") | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.pop([i])" | retrieves the item at *i* and | (2) |\n| | also removes it from *s* | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.remove(x)" | remove the first item from *s* | (3) |\n| | where "s[i] == x" | |\n+--------------------------------+----------------------------------+-----------------------+\n| "s.reverse()" | reverses the items of *s* in | (4) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. The optional argument *i* defaults to "-1", so that by default\n the last item is removed and returned.\n\n3. "remove" raises "ValueError" when *x* is not found in *s*.\n\n4. The "reverse()" method modifies the sequence in place for\n economy of space when reversing a large sequence. To remind users\n that it operates by side effect, it does not return the reversed\n sequence.\n\n5. "clear()" and "copy()" are included for consistency with the\n interfaces of mutable containers that don\'t support slicing\n operations (such as "dict" and "set")\n\n New in version 3.3: "clear()" and "copy()" methods.\n\n6. The value *n* is an integer, or an object implementing\n "__index__()". Zero and negative values of *n* clear the sequence.\n Items in the sequence are not copied; they are referenced multiple\n times, as explained for "s * n" under *Common Sequence Operations*.\n', + 'unary': u'\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary "-" (minus) operator yields the negation of its numeric\nargument.\n\nThe unary "+" (plus) operator yields its numeric argument unchanged.\n\nThe unary "~" (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of "x" is defined as\n"-(x+1)". It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n"TypeError" exception is raised.\n', + 'while': u'\nThe "while" statement\n*********************\n\nThe "while" statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the "else" clause, if present, is executed\nand the loop terminates.\n\nA "break" statement executed in the first suite terminates the loop\nwithout executing the "else" clause\'s suite. A "continue" statement\nexecuted in the first suite skips the rest of the suite and goes back\nto testing the expression.\n', + 'with': u'\nThe "with" statement\n********************\n\nThe "with" statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common "try"..."except"..."finally"\nusage patterns to be encapsulated for convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the "with" statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the "with_item")\n is evaluated to obtain a context manager.\n\n2. The context manager\'s "__exit__()" is loaded for later use.\n\n3. The context manager\'s "__enter__()" method is invoked.\n\n4. If a target was included in the "with" statement, the return\n value from "__enter__()" is assigned to it.\n\n Note: The "with" statement guarantees that if the "__enter__()"\n method returns without an error, then "__exit__()" will always be\n called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s "__exit__()" method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to "__exit__()". Otherwise, three\n "None" arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the "__exit__()" method was false, the exception is reraised.\n If the return value was true, the exception is suppressed, and\n execution continues with the statement following the "with"\n statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from "__exit__()" is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple "with" statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also: **PEP 0343** - The "with" statement\n\n The specification, background, and examples for the Python "with"\n statement.\n', + 'yield': u'\nThe "yield" statement\n*********************\n\n yield_stmt ::= yield_expression\n\nA "yield" statement is semantically equivalent to a *yield\nexpression*. The yield statement can be used to omit the parentheses\nthat would otherwise be required in the equivalent yield expression\nstatement. For example, the yield statements\n\n yield \n yield from \n\nare equivalent to the yield expression statements\n\n (yield )\n (yield from )\n\nYield expressions and statements are only used when defining a\n*generator* function, and are only used in the body of the generator\nfunction. Using yield in a function definition is sufficient to cause\nthat definition to create a generator function instead of a normal\nfunction.\n\nFor full details of "yield" semantics, refer to the *Yield\nexpressions* section.\n'} -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 02:37:46 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:37:46 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_Updates_for_3=2E4_and_3=2E5_r?= =?utf-8?q?elease_schedules=2E?= Message-ID: <20151123073746.21511.41784@psf.io> https://hg.python.org/peps/rev/fe2c75a2300d changeset: 6129:fe2c75a2300d user: Larry Hastings date: Sun Nov 22 23:37:42 2015 -0800 summary: Updates for 3.4 and 3.5 release schedules. files: pep-0429.txt | 6 ++++++ pep-0478.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/pep-0429.txt b/pep-0429.txt --- a/pep-0429.txt +++ b/pep-0429.txt @@ -68,6 +68,12 @@ - 3.4.3 candidate 1: February 8, 2015 - 3.4.3 final: February 25, 2015 +3.4.4 schedule (planned) +------------------------ + +- 3.4.4 candidate 1: December 6, 2015 +- 3.4.4 final: December 20, 2015 + Features for 3.4 diff --git a/pep-0478.txt b/pep-0478.txt --- a/pep-0478.txt +++ b/pep-0478.txt @@ -49,10 +49,10 @@ - 3.5.0 release candidate 2: August 25, 2015 - 3.5.0 release candidate 3: September 7, 2015 - 3.5.0 final: September 13, 2015 +- 3.5.1 release candidate 1: November 22, 2015 Planned future release dates: -- 3.5.1 release candidate 1: November 22, 2015 - 3.5.1 final: December 6, 2015 -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Mon Nov 23 02:46:18 2015 From: python-checkins at python.org (larry.hastings) Date: Mon, 23 Nov 2015 07:46:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Null_merge_from_3=2E5=2E?= Message-ID: <20151123074618.9712.14620@psf.io> https://hg.python.org/cpython/rev/59f33f4249ec changeset: 99304:59f33f4249ec parent: 99297:936fcd0ba6b1 parent: 99303:a077bab36ae4 user: Larry Hastings date: Sun Nov 22 23:46:02 2015 -0800 summary: Null merge from 3.5. files: .hgtags | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgtags b/.hgtags --- a/.hgtags +++ b/.hgtags @@ -157,3 +157,4 @@ 66ed52375df802f9d0a34480daaa8ce79fc41313 v3.5.0rc3 2d033fedfa7f1e325fd14ccdaa9cb42155da206f v3.5.0rc4 374f501f4567b7595f2ad7798aa09afa2456bb28 v3.5.0 +948ef16a69513ba1ff15c9d7d0b012b949df4c80 v3.5.1rc1 -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Mon Nov 23 03:44:12 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 23 Nov 2015 08:44:12 +0000 Subject: [Python-checkins] Daily reference leaks (2662099d477e): sum=4 Message-ID: <20151123084412.22159.78852@psf.io> results for 2662099d477e on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogjl3lds', '--timeout', '7200'] From python-checkins at python.org Mon Nov 23 08:21:09 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:21:09 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2323914=3A_Fixed_SystemError_raised_by_unpickler_?= =?utf-8?q?on_broken_pickle_data=2E?= Message-ID: <20151123132109.3546.80508@psf.io> https://hg.python.org/cpython/rev/b08c3a733fda changeset: 99307:b08c3a733fda parent: 99304:59f33f4249ec parent: 99306:531e2674f003 user: Serhiy Storchaka date: Mon Nov 23 15:20:21 2015 +0200 summary: Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. files: Lib/test/pickletester.py | 85 +++++++++++++++++++++++++++- Lib/test/test_pickle.py | 3 + Misc/NEWS | 2 + Modules/_pickle.c | 19 +++++- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -12,7 +12,7 @@ from http.cookies import SimpleCookie from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, + TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, _2G, _4G, bigmemtest, ) @@ -987,6 +987,89 @@ self.assertIs(type(unpickled), collections.UserDict) self.assertEqual(unpickled, collections.UserDict({1: 2})) + def test_bad_stack(self): + badpickles = [ + b'0.', # POP + b'1.', # POP_MARK + b'2.', # DUP + # b'(2.', # PyUnpickler doesn't raise + b'R.', # REDUCE + b')R.', + b'a.', # APPEND + b'Na.', + b'b.', # BUILD + b'Nb.', + b'd.', # DICT + b'e.', # APPENDS + # b'(e.', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n.', # INST + b'l.', # LIST + b'o.', # OBJ + b'(o.', + b'p1\n.', # PUT + b'q\x00.', # BINPUT + b'r\x00\x00\x00\x00.', # LONG_BINPUT + b's.', # SETITEM + b'Ns.', + b'NNs.', + b't.', # TUPLE + b'u.', # SETITEMS + b'(u.', + b'}(Nu.', + b'\x81.', # NEWOBJ + b')\x81.', + b'\x85.', # TUPLE1 + b'\x86.', # TUPLE2 + b'N\x86.', + b'\x87.', # TUPLE3 + b'N\x87.', + b'NN\x87.', + b'\x90.', # ADDITEMS + # b'(\x90.', # PyUnpickler raises AttributeError + b'\x91.', # FROZENSET + b'\x92.', # NEWOBJ_EX + b')}\x92.', + b'\x93.', # STACK_GLOBAL + b'Vlist\n\x93.', + b'\x94.', # MEMOIZE + ] + for p in badpickles: + with self.subTest(p): + self.assertRaises(self.bad_stack_errors, self.loads, p) + + def test_bad_mark(self): + badpickles = [ + b'cbuiltins\nlist\n)(R.', # REDUCE + b'cbuiltins\nlist\n()R.', + b']N(a.', # APPEND + b'cbuiltins\nValueError\n)R}(b.', # BUILD + b'cbuiltins\nValueError\n)R(}b.', + b'(Nd.', # DICT + b'}NN(s.', # SETITEM + b'}N(Ns.', + b'cbuiltins\nlist\n)(\x81.', # NEWOBJ + b'cbuiltins\nlist\n()\x81.', + b'N(\x85.', # TUPLE1 + b'NN(\x86.', # TUPLE2 + b'N(N\x86.', + b'NNN(\x87.', # TUPLE3 + b'NN(N\x87.', + b'N(NN\x87.', + b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX + b'cbuiltins\nlist\n)(}\x92.', + b'cbuiltins\nlist\n()}\x92.', + b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL + b'Vbuiltins\nVlist\n(\x93.', + ] + for p in badpickles: + # PyUnpickler prints reduce errors to stdout + with self.subTest(p), captured_stdout(): + try: + self.loads(p) + except (IndexError, AttributeError, TypeError, + pickle.UnpicklingError): + pass + class AbstractPickleTests(unittest.TestCase): # Subclass must define self.dumps, self.loads. diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -32,6 +32,7 @@ class PyUnpicklerTests(AbstractUnpickleTests): unpickler = pickle._Unpickler + bad_stack_errors = (IndexError,) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -62,6 +63,7 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler + bad_stack_errors = (pickle.UnpicklingError, IndexError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -119,6 +121,7 @@ if has_c_implementation: class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler + bad_stack_errors = (pickle.UnpicklingError,) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,8 @@ Library ------- +- Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. + - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -473,8 +473,8 @@ static PyObject * Pdata_pop(Pdata *self) { - PickleState *st = _Pickle_GetGlobalState(); if (Py_SIZE(self) == 0) { + PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "bad pickle data"); return NULL; } @@ -5211,6 +5211,9 @@ if ((i = marker(self)) < 0) return -1; + if (Py_SIZE(self->stack) - i < 1) + return stack_underflow(); + args = Pdata_poptuple(self->stack, i + 1); if (args == NULL) return -1; @@ -5869,13 +5872,18 @@ static int load_append(UnpicklerObject *self) { + if (Py_SIZE(self->stack) - 1 <= 0) + return stack_underflow(); return do_append(self, Py_SIZE(self->stack) - 1); } static int load_appends(UnpicklerObject *self) { - return do_append(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_append(self, i); } static int @@ -5925,7 +5933,10 @@ static int load_setitems(UnpicklerObject *self) { - return do_setitems(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_setitems(self, i); } static int @@ -5935,6 +5946,8 @@ Py_ssize_t mark, len, i; mark = marker(self); + if (mark < 0) + return -1; len = Py_SIZE(self->stack); if (mark > len || mark <= 0) return stack_underflow(); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:21:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:21:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIzOTE0?= =?utf-8?q?=3A_Fixed_SystemError_raised_by_unpickler_on_broken_pickle_data?= =?utf-8?q?=2E?= Message-ID: <20151123132109.21511.38332@psf.io> https://hg.python.org/cpython/rev/686fa9439d38 changeset: 99308:686fa9439d38 branch: 2.7 parent: 99298:e3dea2e4f93d user: Serhiy Storchaka date: Mon Nov 23 15:20:43 2015 +0200 summary: Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. files: Lib/test/pickletester.py | 74 +++++++++++++++++++++++++++- Lib/test/test_cpickle.py | 2 + Lib/test/test_pickle.py | 3 +- Misc/NEWS | 1 + Modules/cPickle.c | 24 ++++++++- 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -7,7 +7,7 @@ import pickletools import copy_reg -from test.test_support import TestFailed, verbose, have_unicode, TESTFN +from test.test_support import TestFailed, verbose, have_unicode, TESTFN, captured_stdout try: from test.test_support import _2G, _1M, precisionbigmemtest except ImportError: @@ -634,6 +634,78 @@ self.assertEqual(unpickled, ([],)*2) self.assertIs(unpickled[0], unpickled[1]) + def test_bad_stack(self): + badpickles = [ + b'0.', # POP + b'1.', # POP_MARK + b'2.', # DUP + # b'(2.', # PyUnpickler doesn't raise + b'R.', # REDUCE + b')R.', + b'a.', # APPEND + b'Na.', + b'b.', # BUILD + b'Nb.', + b'd.', # DICT + b'e.', # APPENDS + # b'(e.', # PyUnpickler raises AttributeError + b'i__builtin__\nlist\n.', # INST + b'l.', # LIST + b'o.', # OBJ + b'(o.', + b'p1\n.', # PUT + b'q\x00.', # BINPUT + b'r\x00\x00\x00\x00.', # LONG_BINPUT + b's.', # SETITEM + b'Ns.', + b'NNs.', + b't.', # TUPLE + b'u.', # SETITEMS + b'(u.', + b'}(Nu.', + b'\x81.', # NEWOBJ + b')\x81.', + b'\x85.', # TUPLE1 + b'\x86.', # TUPLE2 + b'N\x86.', + b'\x87.', # TUPLE3 + b'N\x87.', + b'NN\x87.', + ] + for p in badpickles: + try: + self.assertRaises(self.bad_stack_errors, self.loads, p) + except: + print '***', repr(p) + raise + + def test_bad_mark(self): + badpickles = [ + b'c__builtin__\nlist\n)(R.', # REDUCE + b'c__builtin__\nlist\n()R.', + b']N(a.', # APPEND + b'cexceptions\nValueError\n)R}(b.', # BUILD + b'cexceptions\nValueError\n)R(}b.', + b'(Nd.', # DICT + b'}NN(s.', # SETITEM + b'}N(Ns.', + b'c__builtin__\nlist\n)(\x81.', # NEWOBJ + b'c__builtin__\nlist\n()\x81.', + b'N(\x85.', # TUPLE1 + b'NN(\x86.', # TUPLE2 + b'N(N\x86.', + b'NNN(\x87.', # TUPLE3 + b'NN(N\x87.', + b'N(NN\x87.', + ] + for p in badpickles: + # PyUnpickler prints reduce errors to stdout + try: + self.loads(p) + except (IndexError, AttributeError, TypeError, + pickle.UnpicklingError): + pass + class AbstractPickleTests(unittest.TestCase): # Subclass must define self.dumps, self.loads. diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py --- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -51,6 +51,7 @@ error = cPickle.BadPickleGet module = cPickle + bad_stack_errors = (cPickle.UnpicklingError,) class cPickleUnpicklerTests(AbstractUnpickleTests): @@ -63,6 +64,7 @@ self.close(f) error = cPickle.BadPickleGet + bad_stack_errors = (cPickle.UnpicklingError,) class cStringIOCUnpicklerTests(cStringIOMixin, cPickleUnpicklerTests): pass diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -23,17 +23,18 @@ module = pickle error = KeyError + bad_stack_errors = (IndexError,) class UnpicklerTests(AbstractUnpickleTests): error = KeyError + bad_stack_errors = (IndexError,) def loads(self, buf): f = StringIO(buf) u = pickle.Unpickler(f) return u.load() - class PicklerTests(AbstractPickleTests): def dumps(self, arg, proto=0, fast=0): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,7 @@ Library ------- +- Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data. What's New in Python 2.7.11? ============================ diff --git a/Modules/cPickle.c b/Modules/cPickle.c --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -3945,6 +3945,10 @@ Py_ssize_t i; if ((i = marker(self)) < 0) return -1; + + if (self->stack->length - i < 1) + return stackUnderflow(); + if (!( tup=Pdata_popTuple(self->stack, i+1))) return -1; PDATA_POP(self->stack, class); if (class) { @@ -4496,6 +4500,8 @@ static int load_append(Unpicklerobject *self) { + if (self->stack->length - 1 <= 0) + return stackUnderflow(); return do_append(self, self->stack->length - 1); } @@ -4503,7 +4509,10 @@ static int load_appends(Unpicklerobject *self) { - return do_append(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_append(self, i); } @@ -4515,6 +4524,14 @@ if (!( (len=self->stack->length) >= x && x > 0 )) return stackUnderflow(); + if (len == x) /* nothing to do */ + return 0; + if ((len - x) % 2 != 0) { + /* Currupt or hostile pickle -- we never write one like this. */ + PyErr_SetString(UnpicklingError, + "odd number of items for SETITEMS"); + return -1; + } dict=self->stack->data[x-1]; @@ -4542,7 +4559,10 @@ static int load_setitems(Unpicklerobject *self) { - return do_setitems(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_setitems(self, i); } -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:21:25 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:21:25 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2323914=3A_Fixed_SystemError_raised_by_unpickler_on_bro?= =?utf-8?q?ken_pickle_data=2E?= Message-ID: <20151123132109.127560.82971@psf.io> https://hg.python.org/cpython/rev/531e2674f003 changeset: 99306:531e2674f003 branch: 3.5 parent: 99303:a077bab36ae4 parent: 99305:bac3f63ea747 user: Serhiy Storchaka date: Mon Nov 23 15:19:23 2015 +0200 summary: Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. files: Lib/test/pickletester.py | 85 +++++++++++++++++++++++++++- Lib/test/test_pickle.py | 3 + Misc/NEWS | 2 + Modules/_pickle.c | 19 +++++- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -12,7 +12,7 @@ from http.cookies import SimpleCookie from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, + TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, _2G, _4G, bigmemtest, ) @@ -987,6 +987,89 @@ self.assertIs(type(unpickled), collections.UserDict) self.assertEqual(unpickled, collections.UserDict({1: 2})) + def test_bad_stack(self): + badpickles = [ + b'0.', # POP + b'1.', # POP_MARK + b'2.', # DUP + # b'(2.', # PyUnpickler doesn't raise + b'R.', # REDUCE + b')R.', + b'a.', # APPEND + b'Na.', + b'b.', # BUILD + b'Nb.', + b'd.', # DICT + b'e.', # APPENDS + # b'(e.', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n.', # INST + b'l.', # LIST + b'o.', # OBJ + b'(o.', + b'p1\n.', # PUT + b'q\x00.', # BINPUT + b'r\x00\x00\x00\x00.', # LONG_BINPUT + b's.', # SETITEM + b'Ns.', + b'NNs.', + b't.', # TUPLE + b'u.', # SETITEMS + b'(u.', + b'}(Nu.', + b'\x81.', # NEWOBJ + b')\x81.', + b'\x85.', # TUPLE1 + b'\x86.', # TUPLE2 + b'N\x86.', + b'\x87.', # TUPLE3 + b'N\x87.', + b'NN\x87.', + b'\x90.', # ADDITEMS + # b'(\x90.', # PyUnpickler raises AttributeError + b'\x91.', # FROZENSET + b'\x92.', # NEWOBJ_EX + b')}\x92.', + b'\x93.', # STACK_GLOBAL + b'Vlist\n\x93.', + b'\x94.', # MEMOIZE + ] + for p in badpickles: + with self.subTest(p): + self.assertRaises(self.bad_stack_errors, self.loads, p) + + def test_bad_mark(self): + badpickles = [ + b'cbuiltins\nlist\n)(R.', # REDUCE + b'cbuiltins\nlist\n()R.', + b']N(a.', # APPEND + b'cbuiltins\nValueError\n)R}(b.', # BUILD + b'cbuiltins\nValueError\n)R(}b.', + b'(Nd.', # DICT + b'}NN(s.', # SETITEM + b'}N(Ns.', + b'cbuiltins\nlist\n)(\x81.', # NEWOBJ + b'cbuiltins\nlist\n()\x81.', + b'N(\x85.', # TUPLE1 + b'NN(\x86.', # TUPLE2 + b'N(N\x86.', + b'NNN(\x87.', # TUPLE3 + b'NN(N\x87.', + b'N(NN\x87.', + b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX + b'cbuiltins\nlist\n)(}\x92.', + b'cbuiltins\nlist\n()}\x92.', + b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL + b'Vbuiltins\nVlist\n(\x93.', + ] + for p in badpickles: + # PyUnpickler prints reduce errors to stdout + with self.subTest(p), captured_stdout(): + try: + self.loads(p) + except (IndexError, AttributeError, TypeError, + pickle.UnpicklingError): + pass + class AbstractPickleTests(unittest.TestCase): # Subclass must define self.dumps, self.loads. diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -32,6 +32,7 @@ class PyUnpicklerTests(AbstractUnpickleTests): unpickler = pickle._Unpickler + bad_stack_errors = (IndexError,) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -62,6 +63,7 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler + bad_stack_errors = (pickle.UnpicklingError, IndexError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -119,6 +121,7 @@ if has_c_implementation: class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler + bad_stack_errors = (pickle.UnpicklingError,) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,8 @@ Library ------- +- Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. + - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -459,8 +459,8 @@ static PyObject * Pdata_pop(Pdata *self) { - PickleState *st = _Pickle_GetGlobalState(); if (Py_SIZE(self) == 0) { + PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "bad pickle data"); return NULL; } @@ -5148,6 +5148,9 @@ if ((i = marker(self)) < 0) return -1; + if (Py_SIZE(self->stack) - i < 1) + return stack_underflow(); + args = Pdata_poptuple(self->stack, i + 1); if (args == NULL) return -1; @@ -5806,13 +5809,18 @@ static int load_append(UnpicklerObject *self) { + if (Py_SIZE(self->stack) - 1 <= 0) + return stack_underflow(); return do_append(self, Py_SIZE(self->stack) - 1); } static int load_appends(UnpicklerObject *self) { - return do_append(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_append(self, i); } static int @@ -5862,7 +5870,10 @@ static int load_setitems(UnpicklerObject *self) { - return do_setitems(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_setitems(self, i); } static int @@ -5872,6 +5883,8 @@ Py_ssize_t mark, len, i; mark = marker(self); + if (mark < 0) + return -1; len = Py_SIZE(self->stack); if (mark > len || mark <= 0) return stack_underflow(); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:21:26 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:21:26 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzIzOTE0?= =?utf-8?q?=3A_Fixed_SystemError_raised_by_unpickler_on_broken_pickle_data?= =?utf-8?q?=2E?= Message-ID: <20151123132109.20256.65504@psf.io> https://hg.python.org/cpython/rev/bac3f63ea747 changeset: 99305:bac3f63ea747 branch: 3.4 parent: 99295:852c9ed9115c user: Serhiy Storchaka date: Mon Nov 23 15:17:43 2015 +0200 summary: Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. files: Lib/test/pickletester.py | 85 +++++++++++++++++++++++++++- Lib/test/test_pickle.py | 3 + Misc/NEWS | 2 + Modules/_pickle.c | 19 +++++- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -12,7 +12,7 @@ from http.cookies import SimpleCookie from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, + TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, _2G, _4G, bigmemtest, ) @@ -987,6 +987,89 @@ self.assertIs(type(unpickled), collections.UserDict) self.assertEqual(unpickled, collections.UserDict({1: 2})) + def test_bad_stack(self): + badpickles = [ + b'0.', # POP + b'1.', # POP_MARK + b'2.', # DUP + # b'(2.', # PyUnpickler doesn't raise + b'R.', # REDUCE + b')R.', + b'a.', # APPEND + b'Na.', + b'b.', # BUILD + b'Nb.', + b'd.', # DICT + b'e.', # APPENDS + # b'(e.', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n.', # INST + b'l.', # LIST + b'o.', # OBJ + b'(o.', + b'p1\n.', # PUT + b'q\x00.', # BINPUT + b'r\x00\x00\x00\x00.', # LONG_BINPUT + b's.', # SETITEM + b'Ns.', + b'NNs.', + b't.', # TUPLE + b'u.', # SETITEMS + b'(u.', + b'}(Nu.', + b'\x81.', # NEWOBJ + b')\x81.', + b'\x85.', # TUPLE1 + b'\x86.', # TUPLE2 + b'N\x86.', + b'\x87.', # TUPLE3 + b'N\x87.', + b'NN\x87.', + b'\x90.', # ADDITEMS + # b'(\x90.', # PyUnpickler raises AttributeError + b'\x91.', # FROZENSET + b'\x92.', # NEWOBJ_EX + b')}\x92.', + b'\x93.', # STACK_GLOBAL + b'Vlist\n\x93.', + b'\x94.', # MEMOIZE + ] + for p in badpickles: + with self.subTest(p): + self.assertRaises(self.bad_stack_errors, self.loads, p) + + def test_bad_mark(self): + badpickles = [ + b'cbuiltins\nlist\n)(R.', # REDUCE + b'cbuiltins\nlist\n()R.', + b']N(a.', # APPEND + b'cbuiltins\nValueError\n)R}(b.', # BUILD + b'cbuiltins\nValueError\n)R(}b.', + b'(Nd.', # DICT + b'}NN(s.', # SETITEM + b'}N(Ns.', + b'cbuiltins\nlist\n)(\x81.', # NEWOBJ + b'cbuiltins\nlist\n()\x81.', + b'N(\x85.', # TUPLE1 + b'NN(\x86.', # TUPLE2 + b'N(N\x86.', + b'NNN(\x87.', # TUPLE3 + b'NN(N\x87.', + b'N(NN\x87.', + b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX + b'cbuiltins\nlist\n)(}\x92.', + b'cbuiltins\nlist\n()}\x92.', + b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL + b'Vbuiltins\nVlist\n(\x93.', + ] + for p in badpickles: + # PyUnpickler prints reduce errors to stdout + with self.subTest(p), captured_stdout(): + try: + self.loads(p) + except (IndexError, AttributeError, TypeError, + pickle.UnpicklingError): + pass + class AbstractPickleTests(unittest.TestCase): # Subclass must define self.dumps, self.loads. diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -32,6 +32,7 @@ class PyUnpicklerTests(AbstractUnpickleTests): unpickler = pickle._Unpickler + bad_stack_errors = (IndexError,) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -62,6 +63,7 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler + bad_stack_errors = (pickle.UnpicklingError, IndexError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -119,6 +121,7 @@ if has_c_implementation: class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler + bad_stack_errors = (pickle.UnpicklingError,) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,8 @@ Library ------- +- Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. + - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -448,8 +448,8 @@ static PyObject * Pdata_pop(Pdata *self) { - PickleState *st = _Pickle_GetGlobalState(); if (Py_SIZE(self) == 0) { + PickleState *st = _Pickle_GetGlobalState(); PyErr_SetString(st->UnpicklingError, "bad pickle data"); return NULL; } @@ -5079,6 +5079,9 @@ if ((i = marker(self)) < 0) return -1; + if (Py_SIZE(self->stack) - i < 1) + return stack_underflow(); + args = Pdata_poptuple(self->stack, i + 1); if (args == NULL) return -1; @@ -5737,13 +5740,18 @@ static int load_append(UnpicklerObject *self) { + if (Py_SIZE(self->stack) - 1 <= 0) + return stack_underflow(); return do_append(self, Py_SIZE(self->stack) - 1); } static int load_appends(UnpicklerObject *self) { - return do_append(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_append(self, i); } static int @@ -5793,7 +5801,10 @@ static int load_setitems(UnpicklerObject *self) { - return do_setitems(self, marker(self)); + Py_ssize_t i = marker(self); + if (i < 0) + return -1; + return do_setitems(self, i); } static int @@ -5803,6 +5814,8 @@ Py_ssize_t mark, len, i; mark = marker(self); + if (mark < 0) + return -1; len = Py_SIZE(self->stack); if (mark > len || mark <= 0) return stack_underflow(); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:47:06 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:47:06 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325688=3A_Fixed_file_leak_in_ElementTree=2Eiterparse?= =?utf-8?q?=28=29_raising_an_error=2E?= Message-ID: <20151123134705.3548.42916@psf.io> https://hg.python.org/cpython/rev/267d04459ba3 changeset: 99310:267d04459ba3 branch: 3.5 parent: 99306:531e2674f003 parent: 99309:6e23777948f3 user: Serhiy Storchaka date: Mon Nov 23 15:45:12 2015 +0200 summary: Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. files: Lib/test/test_xml_etree.py | 29 +++++++++++++++- Lib/xml/etree/ElementTree.py | 41 +++++++++++++++-------- Misc/NEWS | 2 + 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -561,11 +561,21 @@ self.assertEqual(res, ['start-ns', 'end-ns']) events = ("start", "end", "bogus") - with self.assertRaises(ValueError) as cm: - with open(SIMPLE_XMLFILE, "rb") as f: + with open(SIMPLE_XMLFILE, "rb") as f: + with self.assertRaises(ValueError) as cm: iterparse(f, events) + self.assertFalse(f.closed) self.assertEqual(str(cm.exception), "unknown event 'bogus'") + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ValueError) as cm: + iterparse(SIMPLE_XMLFILE, events) + self.assertEqual(str(cm.exception), "unknown event 'bogus'") + del cm + support.gc_collect() + self.assertEqual(w, []) + source = io.BytesIO( b"\n" b"junk") + it = iterparse(TESTFN) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'document')) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ET.ParseError) as cm: + next(it) + self.assertEqual(str(cm.exception), + 'junk after document element: line 1, column 12') + del cm, it + support.gc_collect() + self.assertEqual(w, []) + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1202,7 +1202,12 @@ if not hasattr(source, "read"): source = open(source, "rb") close_source = True - return _IterParseIterator(source, events, parser, close_source) + try: + return _IterParseIterator(source, events, parser, close_source) + except: + if close_source: + source.close() + raise class XMLPullParser: @@ -1285,20 +1290,26 @@ self.root = self._root = None def __next__(self): - while 1: - for event in self._parser.read_events(): - return event - if self._parser._parser is None: - self.root = self._root - if self._close_file: - self._file.close() - raise StopIteration - # load event buffer - data = self._file.read(16 * 1024) - if data: - self._parser.feed(data) - else: - self._root = self._parser._close_and_return_root() + try: + while 1: + for event in self._parser.read_events(): + return event + if self._parser._parser is None: + break + # load event buffer + data = self._file.read(16 * 1024) + if data: + self._parser.feed(data) + else: + self._root = self._parser._close_and_return_root() + self.root = self._root + except: + if self._close_file: + self._file.close() + raise + if self._close_file: + self._file.close() + raise StopIteration def __iter__(self): return self diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,8 @@ Library ------- +- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. + - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:47:06 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:47:06 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325688=3A_Fixed_file_leak_in_ElementTree=2Eiterp?= =?utf-8?q?arse=28=29_raising_an_error=2E?= Message-ID: <20151123134706.22165.63697@psf.io> https://hg.python.org/cpython/rev/d841205776fe changeset: 99311:d841205776fe parent: 99307:b08c3a733fda parent: 99310:267d04459ba3 user: Serhiy Storchaka date: Mon Nov 23 15:46:14 2015 +0200 summary: Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. files: Lib/test/test_xml_etree.py | 29 +++++++++++++++- Lib/xml/etree/ElementTree.py | 41 +++++++++++++++-------- Misc/NEWS | 2 + 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -561,11 +561,21 @@ self.assertEqual(res, ['start-ns', 'end-ns']) events = ("start", "end", "bogus") - with self.assertRaises(ValueError) as cm: - with open(SIMPLE_XMLFILE, "rb") as f: + with open(SIMPLE_XMLFILE, "rb") as f: + with self.assertRaises(ValueError) as cm: iterparse(f, events) + self.assertFalse(f.closed) self.assertEqual(str(cm.exception), "unknown event 'bogus'") + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ValueError) as cm: + iterparse(SIMPLE_XMLFILE, events) + self.assertEqual(str(cm.exception), "unknown event 'bogus'") + del cm + support.gc_collect() + self.assertEqual(w, []) + source = io.BytesIO( b"\n" b"junk") + it = iterparse(TESTFN) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'document')) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ET.ParseError) as cm: + next(it) + self.assertEqual(str(cm.exception), + 'junk after document element: line 1, column 12') + del cm, it + support.gc_collect() + self.assertEqual(w, []) + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1202,7 +1202,12 @@ if not hasattr(source, "read"): source = open(source, "rb") close_source = True - return _IterParseIterator(source, events, parser, close_source) + try: + return _IterParseIterator(source, events, parser, close_source) + except: + if close_source: + source.close() + raise class XMLPullParser: @@ -1285,20 +1290,26 @@ self.root = self._root = None def __next__(self): - while 1: - for event in self._parser.read_events(): - return event - if self._parser._parser is None: - self.root = self._root - if self._close_file: - self._file.close() - raise StopIteration - # load event buffer - data = self._file.read(16 * 1024) - if data: - self._parser.feed(data) - else: - self._root = self._parser._close_and_return_root() + try: + while 1: + for event in self._parser.read_events(): + return event + if self._parser._parser is None: + break + # load event buffer + data = self._file.read(16 * 1024) + if data: + self._parser.feed(data) + else: + self._root = self._parser._close_and_return_root() + self.root = self._root + except: + if self._close_file: + self._file.close() + raise + if self._close_file: + self._file.close() + raise StopIteration def __iter__(self): return self diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,8 @@ Library ------- +- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. + - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:47:29 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:47:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Njg4?= =?utf-8?q?=3A_Fixed_file_leak_in_ElementTree=2Eiterparse=28=29_raising_an?= =?utf-8?q?_error=2E?= Message-ID: <20151123134706.20256.9792@psf.io> https://hg.python.org/cpython/rev/09a8ac75b351 changeset: 99312:09a8ac75b351 branch: 2.7 parent: 99308:686fa9439d38 user: Serhiy Storchaka date: Mon Nov 23 15:46:36 2015 +0200 summary: Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. files: Lib/xml/etree/ElementTree.py | 71 +++++++++++++---------- Misc/NEWS | 3 + 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1198,9 +1198,14 @@ if not hasattr(source, "read"): source = open(source, "rb") close_source = True - if not parser: - parser = XMLParser(target=TreeBuilder()) - return _IterParseIterator(source, events, parser, close_source) + try: + if not parser: + parser = XMLParser(target=TreeBuilder()) + return _IterParseIterator(source, events, parser, close_source) + except: + if close_source: + source.close() + raise class _IterParseIterator(object): @@ -1252,34 +1257,40 @@ raise ValueError("unknown event %r" % event) def next(self): - while 1: - try: - item = self._events[self._index] - self._index += 1 - return item - except IndexError: - pass - if self._error: - e = self._error - self._error = None - raise e - if self._parser is None: - self.root = self._root - if self._close_file: - self._file.close() - raise StopIteration - # load event buffer - del self._events[:] - self._index = 0 - data = self._file.read(16384) - if data: + try: + while 1: try: - self._parser.feed(data) - except SyntaxError as exc: - self._error = exc - else: - self._root = self._parser.close() - self._parser = None + item = self._events[self._index] + self._index += 1 + return item + except IndexError: + pass + if self._error: + e = self._error + self._error = None + raise e + if self._parser is None: + self.root = self._root + break + # load event buffer + del self._events[:] + self._index = 0 + data = self._file.read(16384) + if data: + try: + self._parser.feed(data) + except SyntaxError as exc: + self._error = exc + else: + self._root = self._parser.close() + self._parser = None + except: + if self._close_file: + self._file.close() + raise + if self._close_file: + self._file.close() + raise StopIteration def __iter__(self): return self diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,8 +13,11 @@ Library ------- +- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. + - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data. + What's New in Python 2.7.11? ============================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 08:47:29 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 13:47:29 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Njg4?= =?utf-8?q?=3A_Fixed_file_leak_in_ElementTree=2Eiterparse=28=29_raising_an?= =?utf-8?q?_error=2E?= Message-ID: <20151123134705.20262.60855@psf.io> https://hg.python.org/cpython/rev/6e23777948f3 changeset: 99309:6e23777948f3 branch: 3.4 parent: 99305:bac3f63ea747 user: Serhiy Storchaka date: Mon Nov 23 15:44:03 2015 +0200 summary: Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. files: Lib/test/test_xml_etree.py | 29 +++++++++++++++- Lib/xml/etree/ElementTree.py | 41 +++++++++++++++-------- Misc/NEWS | 2 + 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -561,11 +561,21 @@ self.assertEqual(res, ['start-ns', 'end-ns']) events = ("start", "end", "bogus") - with self.assertRaises(ValueError) as cm: - with open(SIMPLE_XMLFILE, "rb") as f: + with open(SIMPLE_XMLFILE, "rb") as f: + with self.assertRaises(ValueError) as cm: iterparse(f, events) + self.assertFalse(f.closed) self.assertEqual(str(cm.exception), "unknown event 'bogus'") + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ValueError) as cm: + iterparse(SIMPLE_XMLFILE, events) + self.assertEqual(str(cm.exception), "unknown event 'bogus'") + del cm + support.gc_collect() + self.assertEqual(w, []) + source = io.BytesIO( b"\n" b"junk") + it = iterparse(TESTFN) + action, elem = next(it) + self.assertEqual((action, elem.tag), ('end', 'document')) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings("always", category=ResourceWarning) + with self.assertRaises(ET.ParseError) as cm: + next(it) + self.assertEqual(str(cm.exception), + 'junk after document element: line 1, column 12') + del cm, it + support.gc_collect() + self.assertEqual(w, []) + def test_writefile(self): elem = ET.Element("tag") elem.text = "text" diff --git a/Lib/xml/etree/ElementTree.py b/Lib/xml/etree/ElementTree.py --- a/Lib/xml/etree/ElementTree.py +++ b/Lib/xml/etree/ElementTree.py @@ -1206,7 +1206,12 @@ if not hasattr(source, "read"): source = open(source, "rb") close_source = True - return _IterParseIterator(source, events, parser, close_source) + try: + return _IterParseIterator(source, events, parser, close_source) + except: + if close_source: + source.close() + raise class XMLPullParser: @@ -1289,20 +1294,26 @@ self.root = self._root = None def __next__(self): - while 1: - for event in self._parser.read_events(): - return event - if self._parser._parser is None: - self.root = self._root - if self._close_file: - self._file.close() - raise StopIteration - # load event buffer - data = self._file.read(16 * 1024) - if data: - self._parser.feed(data) - else: - self._root = self._parser._close_and_return_root() + try: + while 1: + for event in self._parser.read_events(): + return event + if self._parser._parser is None: + break + # load event buffer + data = self._file.read(16 * 1024) + if data: + self._parser.feed(data) + else: + self._root = self._parser._close_and_return_root() + self.root = self._root + except: + if self._close_file: + self._file.close() + raise + if self._close_file: + self._file.close() + raise StopIteration def __iter__(self): return self diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,8 @@ Library ------- +- Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. + - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. - Issue #25691: Fixed crash on deleting ElementTree.Element attributes. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 09:46:13 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 14:46:13 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NzA2?= =?utf-8?q?=3A_Fixed_markup_in_the_documentation=2E?= Message-ID: <20151123144612.3558.3584@psf.io> https://hg.python.org/cpython/rev/a33d76465a18 changeset: 99313:a33d76465a18 branch: 3.4 parent: 99309:6e23777948f3 user: Serhiy Storchaka date: Mon Nov 23 16:43:05 2015 +0200 summary: Issue #25706: Fixed markup in the documentation. files: Doc/c-api/arg.rst | 2 +- Doc/library/base64.rst | 4 ++-- Doc/library/stdtypes.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -322,7 +322,7 @@ ``Py_CLEANUP_SUPPORTED`` was added. ``p`` (:class:`bool`) [int] - Tests the value passed in for truth (a boolean **p**\redicate) and converts + Tests the value passed in for truth (a boolean **p**\ redicate) and converts the result to its equivalent C true/false integer value. Sets the int to 1 if the expression was true and 0 if it was false. This accepts any valid Python value. See :ref:`truth` for more diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -148,7 +148,7 @@ instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This feature is not supported by the "standard" Ascii85 encoding. - *wrapcol* controls whether the output should have newline ('\n') + *wrapcol* controls whether the output should have newline (``'\n'``) characters added to it. If this is non-zero, each output line will be at most this many characters long. @@ -161,7 +161,7 @@ .. versionadded:: 3.4 -.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v') +.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \\t\\n\\r\\v') Decode an Ascii85 encoded byte string. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2904,7 +2904,7 @@ Return true if all bytes in the sequence are ASCII whitespace and the sequence is not empty, false otherwise. ASCII whitespace characters are - those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline, + those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 09:46:13 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 14:46:13 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325706=3A_Fixed_markup_in_the_documentation=2E?= Message-ID: <20151123144613.21521.78062@psf.io> https://hg.python.org/cpython/rev/f4918e98d085 changeset: 99314:f4918e98d085 branch: 3.5 parent: 99310:267d04459ba3 parent: 99313:a33d76465a18 user: Serhiy Storchaka date: Mon Nov 23 16:43:54 2015 +0200 summary: Issue #25706: Fixed markup in the documentation. files: Doc/c-api/arg.rst | 2 +- Doc/library/base64.rst | 4 ++-- Doc/library/stdtypes.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -322,7 +322,7 @@ ``Py_CLEANUP_SUPPORTED`` was added. ``p`` (:class:`bool`) [int] - Tests the value passed in for truth (a boolean **p**\redicate) and converts + Tests the value passed in for truth (a boolean **p**\ redicate) and converts the result to its equivalent C true/false integer value. Sets the int to 1 if the expression was true and 0 if it was false. This accepts any valid Python value. See :ref:`truth` for more diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -148,7 +148,7 @@ instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This feature is not supported by the "standard" Ascii85 encoding. - *wrapcol* controls whether the output should have newline ('\n') + *wrapcol* controls whether the output should have newline (``'\n'``) characters added to it. If this is non-zero, each output line will be at most this many characters long. @@ -161,7 +161,7 @@ .. versionadded:: 3.4 -.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v') +.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \\t\\n\\r\\v') Decode an Ascii85 encoded byte string. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2940,7 +2940,7 @@ Return true if all bytes in the sequence are ASCII whitespace and the sequence is not empty, false otherwise. ASCII whitespace characters are - those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline, + those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 09:46:15 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 23 Nov 2015 14:46:15 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325706=3A_Fixed_markup_in_the_documentation=2E?= Message-ID: <20151123144613.127578.30996@psf.io> https://hg.python.org/cpython/rev/ebec1a98ab81 changeset: 99315:ebec1a98ab81 parent: 99311:d841205776fe parent: 99314:f4918e98d085 user: Serhiy Storchaka date: Mon Nov 23 16:44:30 2015 +0200 summary: Issue #25706: Fixed markup in the documentation. files: Doc/c-api/arg.rst | 2 +- Doc/library/base64.rst | 4 ++-- Doc/library/stdtypes.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/c-api/arg.rst b/Doc/c-api/arg.rst --- a/Doc/c-api/arg.rst +++ b/Doc/c-api/arg.rst @@ -322,7 +322,7 @@ ``Py_CLEANUP_SUPPORTED`` was added. ``p`` (:class:`bool`) [int] - Tests the value passed in for truth (a boolean **p**\redicate) and converts + Tests the value passed in for truth (a boolean **p**\ redicate) and converts the result to its equivalent C true/false integer value. Sets the int to 1 if the expression was true and 0 if it was false. This accepts any valid Python value. See :ref:`truth` for more diff --git a/Doc/library/base64.rst b/Doc/library/base64.rst --- a/Doc/library/base64.rst +++ b/Doc/library/base64.rst @@ -148,7 +148,7 @@ instead of 4 consecutive spaces (ASCII 0x20) as supported by 'btoa'. This feature is not supported by the "standard" Ascii85 encoding. - *wrapcol* controls whether the output should have newline ('\n') + *wrapcol* controls whether the output should have newline (``'\n'``) characters added to it. If this is non-zero, each output line will be at most this many characters long. @@ -161,7 +161,7 @@ .. versionadded:: 3.4 -.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \t\n\r\v') +.. function:: a85decode(s, *, foldspaces=False, adobe=False, ignorechars=b' \\t\\n\\r\\v') Decode an Ascii85 encoded byte string. diff --git a/Doc/library/stdtypes.rst b/Doc/library/stdtypes.rst --- a/Doc/library/stdtypes.rst +++ b/Doc/library/stdtypes.rst @@ -2940,7 +2940,7 @@ Return true if all bytes in the sequence are ASCII whitespace and the sequence is not empty, false otherwise. ASCII whitespace characters are - those byte values in the sequence b' \t\n\r\x0b\f' (space, tab, newline, + those byte values in the sequence ``b' \t\n\r\x0b\f'`` (space, tab, newline, carriage return, vertical tab, form feed). -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Mon Nov 23 13:18:26 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 23 Nov 2015 18:18:26 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-23 Message-ID: <01099f07-22d5-4ea3-84b7-b4ac843db02b@irsmsx106.ger.corp.intel.com> Results for project Python default, build date 2015-11-23 04:02:38 +0000 commit: 2662099d477ee1a409bacffcb6dc5bcadb4e0078 revision date: 2015-11-23 02:20:37 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.43% -0.54% 9.05% 15.84% :-( pybench 0.13% -0.62% -2.58% 10.07% :-( regex_v8 2.67% -0.43% -5.24% 6.47% :-| nbody 0.15% -0.33% -1.99% 11.06% :-| json_dump_v2 0.19% -0.21% -0.09% 9.96% :-| normal_startup 0.95% -0.32% 0.33% 4.69% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Mon Nov 23 13:19:20 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 23 Nov 2015 18:19:20 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-23 Message-ID: <5f6938be-1b94-4ba9-ada9-4c126ba77a26@irsmsx106.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-23 04:51:56 +0000 commit: 94da1d00000bc33b8f09340b67db99d6c516ceb3 revision date: 2015-11-23 03:05:29 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% -1.97% 2.03% 9.82% :-) pybench 0.13% -0.68% 5.88% 7.77% :-( regex_v8 0.67% -0.42% -2.39% 8.81% :-) nbody 0.13% -1.63% 7.60% 4.22% :-( json_dump_v2 0.23% -2.88% 0.73% 16.09% :-| normal_startup 1.54% 1.27% -0.99% 2.62% :-| ssbench 0.35% 0.59% -0.27% 2.60% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Mon Nov 23 18:31:32 2015 From: python-checkins at python.org (nick.coghlan) Date: Mon, 23 Nov 2015 23:31:32 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_PEP_493=3A_Update_for_python-?= =?utf-8?q?dev_comments?= Message-ID: <20151123233132.31403.58690@psf.io> https://hg.python.org/peps/rev/8decac213ebf changeset: 6130:8decac213ebf user: Nick Coghlan date: Tue Nov 24 09:30:31 2015 +1000 summary: PEP 493: Update for python-dev comments * Describe the fallback in the absence of the PEP * Check sys.flags.ignore_environment in sample code * Explicitly limit backport scope to Linux distros * Explicitly cover (lack of) interaction with virtualenv files: pep-0493.txt | 62 ++++++++++++++++++++++++++++++++------- 1 files changed, 50 insertions(+), 12 deletions(-) diff --git a/pep-0493.txt b/pep-0493.txt --- a/pep-0493.txt +++ b/pep-0493.txt @@ -9,7 +9,7 @@ Type: Informational Content-Type: text/x-rst Created: 10-May-2015 -Post-History: 06-Jul-2015 +Post-History: 06-Jul-2015, 11-Nov-2015, 24-Nov-2015 Abstract @@ -74,6 +74,23 @@ version of Python 3 (whether published directly by the Python Software Foundation or by a redistributor). +Alternatives +------------ + +In the absence of clear upstream guidance and recommendations, commercial +redistributors will still make their own design decisions in the interests of +their customers. The main approaches available are: + +* Continuing to rebase on new Python 2.7.x releases, while providing no + additional assistance beyond the mechanisms defined in PEP 476 in migrating + from unchecked to checked hostnames in standard library HTTPS clients +* Gating availability of the improved default handling of HTTPS connections on + upgrading from Python 2 to Python 3 +* For Linux distribution vendors, gating availability of the improved default + handling of HTTPS connections on upgrading to a new operating system version +* Implementing one or both of the design suggestions described in this PEP, + regardless of the formal status of the PEP + Requirements for capability detection ===================================== @@ -150,9 +167,10 @@ _https_verify_envvar = 'PYTHONHTTPSVERIFY' def _get_https_context_factory(): - config_setting = os.environ.get(_https_verify_envvar) - if config_setting == '0': - return _create_unverified_context + if not sys.flags.ignore_environment: + config_setting = os.environ.get(_https_verify_envvar) + if config_setting == '0': + return _create_unverified_context return create_default_context _create_default_https_context = _get_https_context_factory() @@ -170,6 +188,13 @@ and any attacker with such access would already be able to modify the behaviour of the underlying OpenSSL implementation. +Interaction with Python virtual environments +-------------------------------------------- + +This setting is read directly from the process environment, and hence works +the same way regardless of whether or not the interpreter is being run inside +an activated Python virtual environment. + Recommendation for backporting to earlier Python versions ========================================================= @@ -233,9 +258,11 @@ Recommended file location ------------------------- -This approach is currently only defined for \*nix system Python installations. +As the PEP authors are not aware of any vendors providing long-term support +releases targeting Windows, Mac OS X or \*BSD systems, this approach is +currently only specifically defined for Linux system Python installations. -The recommended configuration file name is +The recommended configuration file name on Linux systems is ``/etc/python/cert-verification.cfg``. The ``.cfg`` filename extension is recommended for consistency with the @@ -248,6 +275,9 @@ The configuration file should use a ConfigParser ini-style format with a single section named ``[https]`` containing one required setting ``verify``. +The suggested section name is taken from the "https" URL schema passed to +affected client APIs. + Permitted values for ``verify`` are: * ``enable``: ensure HTTPS certificate verification is enabled by default @@ -319,6 +349,13 @@ variable has the essential feature of providing a smoother migration path, even for applications being run with the ``-E`` switch. +Interaction with Python virtual environments +-------------------------------------------- + +This setting is scoped by the interpreter installation and affects all Python +processes using that interpreter, regardless of whether or not the interpreter +is being run inside an activated Python virtual environment. + Combining the recommendations ============================= @@ -341,12 +378,13 @@ _cert_verification_config = '/etc/python/cert-verification.cfg' def _get_https_context_factory(): - # Check for am environmental override of the default behaviour - config_setting = os.environ.get(_https_verify_envvar) - if config_setting is not None: - if config_setting == '0': - return _create_unverified_context - return create_default_context + # Check for an environmental override of the default behaviour + if not sys.flags.ignore_environment: + config_setting = os.environ.get(_https_verify_envvar) + if config_setting is not None: + if config_setting == '0': + return _create_unverified_context + return create_default_context # Check for a system-wide override of the default behaviour context_factories = { -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Mon Nov 23 19:40:30 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 00:40:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjYz?= =?utf-8?q?=3A_Make_rlcompleter_avoid_duplicate_global_names?= Message-ID: <20151124004030.31415.62376@psf.io> https://hg.python.org/cpython/rev/4799615f4f26 changeset: 99316:4799615f4f26 branch: 3.4 parent: 99313:a33d76465a18 user: Martin Panter date: Mon Nov 23 23:50:26 2015 +0000 summary: Issue #25663: Make rlcompleter avoid duplicate global names files: Lib/rlcompleter.py | 7 +++++-- Lib/test/test_rlcompleter.py | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -103,13 +103,16 @@ """ import keyword matches = [] + seen = {"__builtins__"} n = len(text) for word in keyword.kwlist: if word[:n] == text: + seen.add(word) matches.append(word) - for nspace in [builtins.__dict__, self.namespace]: + for nspace in [self.namespace, builtins.__dict__]: for word, val in nspace.items(): - if word[:n] == text and word != "__builtins__": + if word[:n] == text and word not in seen: + seen.add(word) matches.append(self._callable_postfix(val, word)) return matches diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -85,6 +85,27 @@ self.assertEqual(completer.complete('as', 2), 'assert') self.assertEqual(completer.complete('an', 0), 'and') + def test_duplicate_globals(self): + namespace = { + 'False': None, # Keyword vs builtin vs namespace + 'assert': None, # Keyword vs namespace + 'try': lambda: None, # Keyword vs callable + 'memoryview': None, # Callable builtin vs non-callable + 'Ellipsis': lambda: None, # Non-callable builtin vs callable + } + completer = rlcompleter.Completer(namespace) + self.assertEqual(completer.complete('False', 0), 'False') + self.assertIsNone(completer.complete('False', 1)) # No duplicates + self.assertEqual(completer.complete('assert', 0), 'assert') + self.assertIsNone(completer.complete('assert', 1)) + self.assertEqual(completer.complete('try', 0), 'try') + self.assertIsNone(completer.complete('try', 1)) + # No opening bracket "(" because we overrode the built-in class + self.assertEqual(completer.complete('memoryview', 0), 'memoryview') + self.assertIsNone(completer.complete('memoryview', 1)) + self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(') + self.assertIsNone(completer.complete('Ellipsis', 1)) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,9 @@ Library ------- +- Issue #25663: In the Readline completer, avoid listing duplicate global + names, and search the global namespace before searching builtins. + - Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 19:40:31 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 00:40:31 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325663=3A_Update_r?= =?utf-8?q?lcompleter_test_for_new_3=2E6_behaviour?= Message-ID: <20151124004031.29804.19704@psf.io> https://hg.python.org/cpython/rev/f742c31491e3 changeset: 99319:f742c31491e3 user: Martin Panter date: Tue Nov 24 00:20:00 2015 +0000 summary: Issue #25663: Update rlcompleter test for new 3.6 behaviour files: Lib/test/test_rlcompleter.py | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -124,9 +124,10 @@ completer = rlcompleter.Completer(namespace) self.assertEqual(completer.complete('False', 0), 'False') self.assertIsNone(completer.complete('False', 1)) # No duplicates - self.assertEqual(completer.complete('assert', 0), 'assert') + # Space or colon added due to being a reserved keyword + self.assertEqual(completer.complete('assert', 0), 'assert ') self.assertIsNone(completer.complete('assert', 1)) - self.assertEqual(completer.complete('try', 0), 'try') + self.assertEqual(completer.complete('try', 0), 'try:') self.assertIsNone(completer.complete('try', 1)) # No opening bracket "(" because we overrode the built-in class self.assertEqual(completer.complete('memoryview', 0), 'memoryview') -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 19:40:31 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 00:40:31 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325663=3A_Merge_rlcompleter_fix_from_3=2E5?= Message-ID: <20151124004031.69572.40782@psf.io> https://hg.python.org/cpython/rev/96fb9daf64a5 changeset: 99318:96fb9daf64a5 parent: 99315:ebec1a98ab81 parent: 99317:4ed70c568baf user: Martin Panter date: Tue Nov 24 00:19:10 2015 +0000 summary: Issue #25663: Merge rlcompleter fix from 3.5 files: Lib/rlcompleter.py | 7 +++++-- Lib/test/test_rlcompleter.py | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -103,9 +103,11 @@ """ import keyword matches = [] + seen = {"__builtins__"} n = len(text) for word in keyword.kwlist: if word[:n] == text: + seen.add(word) if word in {'finally', 'try'}: word = word + ':' elif word not in {'False', 'None', 'True', @@ -113,9 +115,10 @@ 'else'}: word = word + ' ' matches.append(word) - for nspace in [builtins.__dict__, self.namespace]: + for nspace in [self.namespace, builtins.__dict__]: for word, val in nspace.items(): - if word[:n] == text and word != "__builtins__": + if word[:n] == text and word not in seen: + seen.add(word) matches.append(self._callable_postfix(val, word)) return matches diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -113,5 +113,26 @@ self.assertEqual(completer.complete('el', 1), 'else') self.assertEqual(completer.complete('tr', 0), 'try:') + def test_duplicate_globals(self): + namespace = { + 'False': None, # Keyword vs builtin vs namespace + 'assert': None, # Keyword vs namespace + 'try': lambda: None, # Keyword vs callable + 'memoryview': None, # Callable builtin vs non-callable + 'Ellipsis': lambda: None, # Non-callable builtin vs callable + } + completer = rlcompleter.Completer(namespace) + self.assertEqual(completer.complete('False', 0), 'False') + self.assertIsNone(completer.complete('False', 1)) # No duplicates + self.assertEqual(completer.complete('assert', 0), 'assert') + self.assertIsNone(completer.complete('assert', 1)) + self.assertEqual(completer.complete('try', 0), 'try') + self.assertIsNone(completer.complete('try', 1)) + # No opening bracket "(" because we overrode the built-in class + self.assertEqual(completer.complete('memoryview', 0), 'memoryview') + self.assertIsNone(completer.complete('memoryview', 1)) + self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(') + self.assertIsNone(completer.complete('Ellipsis', 1)) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,9 @@ Library ------- +- Issue #25663: In the Readline completer, avoid listing duplicate global + names, and search the global namespace before searching builtins. + - Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 19:40:31 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 00:40:31 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325663=3A_Merge_rlcompleter_fix_from_3=2E4_into_3=2E5?= Message-ID: <20151124004031.59403.80397@psf.io> https://hg.python.org/cpython/rev/4ed70c568baf changeset: 99317:4ed70c568baf branch: 3.5 parent: 99314:f4918e98d085 parent: 99316:4799615f4f26 user: Martin Panter date: Tue Nov 24 00:10:45 2015 +0000 summary: Issue #25663: Merge rlcompleter fix from 3.4 into 3.5 files: Lib/rlcompleter.py | 7 +++++-- Lib/test/test_rlcompleter.py | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -103,13 +103,16 @@ """ import keyword matches = [] + seen = {"__builtins__"} n = len(text) for word in keyword.kwlist: if word[:n] == text: + seen.add(word) matches.append(word) - for nspace in [builtins.__dict__, self.namespace]: + for nspace in [self.namespace, builtins.__dict__]: for word, val in nspace.items(): - if word[:n] == text and word != "__builtins__": + if word[:n] == text and word not in seen: + seen.add(word) matches.append(self._callable_postfix(val, word)) return matches diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -85,5 +85,26 @@ self.assertEqual(completer.complete('as', 2), 'assert') self.assertEqual(completer.complete('an', 0), 'and') + def test_duplicate_globals(self): + namespace = { + 'False': None, # Keyword vs builtin vs namespace + 'assert': None, # Keyword vs namespace + 'try': lambda: None, # Keyword vs callable + 'memoryview': None, # Callable builtin vs non-callable + 'Ellipsis': lambda: None, # Non-callable builtin vs callable + } + completer = rlcompleter.Completer(namespace) + self.assertEqual(completer.complete('False', 0), 'False') + self.assertIsNone(completer.complete('False', 1)) # No duplicates + self.assertEqual(completer.complete('assert', 0), 'assert') + self.assertIsNone(completer.complete('assert', 1)) + self.assertEqual(completer.complete('try', 0), 'try') + self.assertIsNone(completer.complete('try', 1)) + # No opening bracket "(" because we overrode the built-in class + self.assertEqual(completer.complete('memoryview', 0), 'memoryview') + self.assertIsNone(completer.complete('memoryview', 1)) + self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(') + self.assertIsNone(completer.complete('Ellipsis', 1)) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25663: In the Readline completer, avoid listing duplicate global + names, and search the global namespace before searching builtins. + - Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. - Issue #23914: Fixed SystemError raised by unpickler on broken pickle data. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 20:18:58 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 01:18:58 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjYz?= =?utf-8?q?=3A_Make_rlcompleter_avoid_duplicate_global_names?= Message-ID: <20151124011857.87869.60620@psf.io> https://hg.python.org/cpython/rev/d3a9b055206c changeset: 99320:d3a9b055206c branch: 2.7 parent: 99312:09a8ac75b351 user: Martin Panter date: Mon Nov 23 23:50:26 2015 +0000 summary: Issue #25663: Make rlcompleter avoid duplicate global names files: Lib/rlcompleter.py | 7 +++++-- Lib/test/test_rlcompleter.py | 21 +++++++++++++++++++++ Misc/NEWS | 3 +++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Lib/rlcompleter.py b/Lib/rlcompleter.py --- a/Lib/rlcompleter.py +++ b/Lib/rlcompleter.py @@ -102,13 +102,16 @@ """ import keyword matches = [] + seen = {"__builtins__"} n = len(text) for word in keyword.kwlist: if word[:n] == text: + seen.add(word) matches.append(word) - for nspace in [__builtin__.__dict__, self.namespace]: + for nspace in [self.namespace, __builtin__.__dict__]: for word, val in nspace.items(): - if word[:n] == text and word != "__builtins__": + if word[:n] == text and word not in seen: + seen.add(word) matches.append(self._callable_postfix(val, word)) return matches diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -81,6 +81,27 @@ def test_main(): support.run_unittest(TestRlcompleter) + def test_duplicate_globals(self): + namespace = { + 'False': None, # Keyword vs builtin vs namespace + 'assert': None, # Keyword vs namespace + 'try': lambda: None, # Keyword vs callable + 'memoryview': None, # Callable builtin vs non-callable + 'Ellipsis': lambda: None, # Non-callable builtin vs callable + } + completer = rlcompleter.Completer(namespace) + self.assertEqual(completer.complete('False', 0), 'False') + self.assertIsNone(completer.complete('False', 1)) # No duplicates + self.assertEqual(completer.complete('assert', 0), 'assert') + self.assertIsNone(completer.complete('assert', 1)) + self.assertEqual(completer.complete('try', 0), 'try') + self.assertIsNone(completer.complete('try', 1)) + # No opening bracket "(" because we overrode the built-in class + self.assertEqual(completer.complete('memoryview', 0), 'memoryview') + self.assertIsNone(completer.complete('memoryview', 1)) + self.assertEqual(completer.complete('Ellipsis', 0), 'Ellipsis(') + self.assertIsNone(completer.complete('Ellipsis', 1)) + if __name__ == '__main__': test_main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25663: In the Readline completer, avoid listing duplicate global + names, and search the global namespace before searching builtins. + - Issue #25688: Fixed file leak in ElementTree.iterparse() raising an error. - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 23:44:04 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 04:44:04 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151124044403.13419.77767@psf.io> https://hg.python.org/cpython/rev/efaef2b15533 changeset: 99322:efaef2b15533 parent: 99319:f742c31491e3 parent: 99321:935e29e1bbe1 user: Raymond Hettinger date: Mon Nov 23 20:43:56 2015 -0800 summary: merge files: Lib/collections/__init__.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1,3 +1,19 @@ +'''This module implements specialized container datatypes providing +alternatives to Python?s general purpose built-in containers, dict, +list, set, and tuple. + +* namedtuple factory function for creating tuple subclasses with named fields +* deque list-like container with fast appends and pops on either end +* ChainMap dict-like class for creating a single view of multiple mappings +* Counter dict subclass for counting hashable objects +* OrderedDict dict subclass that remembers the order entries were added +* defaultdict dict subclass that calls a factory function to supply missing values +* UserDict wrapper around dictionary objects for easier dict subclassing +* UserList wrapper around list objects for easier list subclassing +* UserString wrapper around string objects for easier string subclassing + +''' + __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 23:44:04 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 04:44:04 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Add_a_missing_?= =?utf-8?q?docstring?= Message-ID: <20151124044403.87879.70990@psf.io> https://hg.python.org/cpython/rev/935e29e1bbe1 changeset: 99321:935e29e1bbe1 branch: 3.5 parent: 99317:4ed70c568baf user: Raymond Hettinger date: Mon Nov 23 20:43:28 2015 -0800 summary: Add a missing docstring files: Lib/collections/__init__.py | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1,3 +1,19 @@ +'''This module implements specialized container datatypes providing +alternatives to Python?s general purpose built-in containers, dict, +list, set, and tuple. + +* namedtuple factory function for creating tuple subclasses with named fields +* deque list-like container with fast appends and pops on either end +* ChainMap dict-like class for creating a single view of multiple mappings +* Counter dict subclass for counting hashable objects +* OrderedDict dict subclass that remembers the order entries were added +* defaultdict dict subclass that calls a factory function to supply missing values +* UserDict wrapper around dictionary objects for easier dict subclassing +* UserList wrapper around list objects for easier list subclassing +* UserString wrapper around string objects for easier string subclassing + +''' + __all__ = ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap'] -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 23 23:47:11 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 04:47:11 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Add_a_missing_?= =?utf-8?q?docstring?= Message-ID: <20151124044711.87889.6969@psf.io> https://hg.python.org/cpython/rev/4773be6110e3 changeset: 99323:4773be6110e3 branch: 2.7 parent: 99320:d3a9b055206c user: Raymond Hettinger date: Mon Nov 23 20:47:05 2015 -0800 summary: Add a missing docstring files: Lib/collections.py | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/Lib/collections.py b/Lib/collections.py --- a/Lib/collections.py +++ b/Lib/collections.py @@ -1,3 +1,15 @@ +'''This module implements specialized container datatypes providing +alternatives to Python?s general purpose built-in containers, dict, +list, set, and tuple. + +* namedtuple factory function for creating tuple subclasses with named fields +* deque list-like container with fast appends and pops on either end +* Counter dict subclass for counting hashable objects +* OrderedDict dict subclass that remembers the order entries were added +* defaultdict dict subclass that calls a factory function to supply missing values + +''' + __all__ = ['Counter', 'deque', 'defaultdict', 'namedtuple', 'OrderedDict'] # For bootstrapping reasons, the collection ABCs are defined in _abcoll.py. # They should however be considered an integral part of collections.py. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 00:00:54 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 05:00:54 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fix_non-ascii_?= =?utf-8?q?character?= Message-ID: <20151124050053.59391.86553@psf.io> https://hg.python.org/cpython/rev/01444d85bfe0 changeset: 99324:01444d85bfe0 branch: 2.7 user: Raymond Hettinger date: Mon Nov 23 21:00:45 2015 -0800 summary: Fix non-ascii character files: Lib/collections.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/collections.py b/Lib/collections.py --- a/Lib/collections.py +++ b/Lib/collections.py @@ -1,5 +1,5 @@ '''This module implements specialized container datatypes providing -alternatives to Python?s general purpose built-in containers, dict, +alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 00:05:34 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 05:05:34 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151124050501.31375.3476@psf.io> https://hg.python.org/cpython/rev/e5e507a357a6 changeset: 99326:e5e507a357a6 parent: 99322:efaef2b15533 parent: 99325:3f5a15f6e8fa user: Raymond Hettinger date: Mon Nov 23 21:04:53 2015 -0800 summary: merge files: Lib/collections/__init__.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1,5 +1,5 @@ '''This module implements specialized container datatypes providing -alternatives to Python?s general purpose built-in containers, dict, +alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 00:05:55 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 05:05:55 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E5=29=3A_Fix_non-ascii_?= =?utf-8?q?character?= Message-ID: <20151124050501.59409.80221@psf.io> https://hg.python.org/cpython/rev/3f5a15f6e8fa changeset: 99325:3f5a15f6e8fa branch: 3.5 parent: 99321:935e29e1bbe1 user: Raymond Hettinger date: Mon Nov 23 21:03:09 2015 -0800 summary: Fix non-ascii character files: Lib/collections/__init__.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/collections/__init__.py b/Lib/collections/__init__.py --- a/Lib/collections/__init__.py +++ b/Lib/collections/__init__.py @@ -1,5 +1,5 @@ '''This module implements specialized container datatypes providing -alternatives to Python?s general purpose built-in containers, dict, +alternatives to Python's general purpose built-in containers, dict, list, set, and tuple. * namedtuple factory function for creating tuple subclasses with named fields -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 01:19:20 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 06:19:20 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_merge?= Message-ID: <20151124061920.29819.51533@psf.io> https://hg.python.org/cpython/rev/fac5562ae9c6 changeset: 99328:fac5562ae9c6 parent: 99326:e5e507a357a6 parent: 99327:f611e2244c69 user: Raymond Hettinger date: Mon Nov 23 22:19:12 2015 -0800 summary: merge files: Doc/library/collections.rst | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -934,6 +934,9 @@ >>> Book.title.__doc__ = 'Title of first printing' >>> Book.authors.__doc__ = 'List of authors sorted by last name' +.. versionchanged:: 3.5 + Property docstrings became writeable. + Default values can be implemented by using :meth:`_replace` to customize a prototype instance: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 01:19:21 2015 From: python-checkins at python.org (raymond.hettinger) Date: Tue, 24 Nov 2015 06:19:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NzAw?= =?utf-8?q?=3A_Clarify_that_namedtuple_property_docstrings_became_writeabl?= =?utf-8?q?e_in?= Message-ID: <20151124061920.87889.89880@psf.io> https://hg.python.org/cpython/rev/f611e2244c69 changeset: 99327:f611e2244c69 branch: 3.5 parent: 99325:3f5a15f6e8fa user: Raymond Hettinger date: Mon Nov 23 22:18:55 2015 -0800 summary: Issue #25700: Clarify that namedtuple property docstrings became writeable in 3.5 files: Doc/library/collections.rst | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -934,6 +934,9 @@ >>> Book.title.__doc__ = 'Title of first printing' >>> Book.authors.__doc__ = 'List of authors sorted by last name' +.. versionchanged:: 3.5 + Property docstrings became writeable. + Default values can be implemented by using :meth:`_replace` to customize a prototype instance: -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Tue Nov 24 03:45:07 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 24 Nov 2015 08:45:07 +0000 Subject: [Python-checkins] Daily reference leaks (e5e507a357a6): sum=103 Message-ID: <20151124084506.81870.97482@psf.io> results for e5e507a357a6 on branch "default" -------------------------------------------- test_asyncio leaked [3, 0, 0] memory blocks, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 test_pickle leaked [20, 20, 20] references, sum=60 test_pickle leaked [12, 12, 12] memory blocks, sum=36 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogUP9efi', '--timeout', '7200'] From lp_benchmark_robot at intel.com Tue Nov 24 07:01:23 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 24 Nov 2015 12:01:23 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-24 Message-ID: Results for project Python default, build date 2015-11-24 04:02:08 +0000 commit: f742c31491e34ab6e0d2a712bb8e9c17b56b5953 revision date: 2015-11-24 00:20:00 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.43% -1.21% 7.95% 16.90% :-( pybench 0.17% 0.08% -2.49% 9.97% :-( regex_v8 3.08% -0.16% -5.41% 6.25% :-| nbody 0.10% 0.03% -1.96% 11.30% :-| json_dump_v2 0.18% 0.55% 0.46% 7.68% :-| normal_startup 1.08% -0.11% 0.21% 5.08% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Tue Nov 24 07:02:47 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 24 Nov 2015 12:02:47 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-24 Message-ID: <5ae43ebb-3409-4395-bf25-a70054fabdf9@irsmsx106.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-24 07:37:11 +0000 commit: 01444d85bfe0e4b3f2670da27c3d1e38fd015ff2 revision date: 2015-11-24 05:00:45 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.18% 0.10% 2.13% 11.03% :-) pybench 0.18% 0.11% 5.99% 7.39% :-( regex_v8 0.66% 0.22% -2.17% 8.16% :-) nbody 0.12% 0.08% 7.68% 5.67% :-| json_dump_v2 0.22% -0.07% 0.67% 16.24% :-| normal_startup 1.80% -0.95% -1.96% 3.91% :-| ssbench 0.38% 0.65% 0.38% 1.06% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From storchaka at gmail.com Tue Nov 24 16:22:22 2015 From: storchaka at gmail.com (Serhiy Storchaka) Date: Tue, 24 Nov 2015 23:22:22 +0200 Subject: [Python-checkins] Daily reference leaks (e5e507a357a6): sum=103 In-Reply-To: References: <20151124084506.81870.97482@psf.io> Message-ID: On 24.11.15 21:31, Brett Cannon wrote: > Someone just added a leak to pickle. It always was here. I just added tests that expose it. http://bugs.python.org/issue25725 From python-checkins at python.org Tue Nov 24 17:27:40 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 22:27:40 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325695=3A_Defer_cr?= =?utf-8?q?eation_of_TESTDIRN_until_the_test_case_is_run?= Message-ID: <20151124221704.81870.69389@psf.io> https://hg.python.org/cpython/rev/fb72d6d7703c changeset: 99329:fb72d6d7703c user: Martin Panter date: Tue Nov 24 22:12:05 2015 +0000 summary: Issue #25695: Defer creation of TESTDIRN until the test case is run files: Lib/test/test_support.py | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py --- a/Lib/test/test_support.py +++ b/Lib/test/test_support.py @@ -9,13 +9,11 @@ from test import support TESTFN = support.TESTFN -TESTDIRN = os.path.basename(tempfile.mkdtemp(dir='.')) class TestSupport(unittest.TestCase): def setUp(self): support.unlink(TESTFN) - support.rmtree(TESTDIRN) tearDown = setUp def test_import_module(self): @@ -48,6 +46,10 @@ support.unlink(TESTFN) def test_rmtree(self): + TESTDIRN = os.path.basename(tempfile.mkdtemp(dir='.')) + self.addCleanup(support.rmtree, TESTDIRN) + support.rmtree(TESTDIRN) + os.mkdir(TESTDIRN) os.mkdir(os.path.join(TESTDIRN, TESTDIRN)) support.rmtree(TESTDIRN) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:07:21 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 23:07:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTc2?= =?utf-8?q?=3A_Remove_application/x-www-form-urlencoded_charset_advice?= Message-ID: <20151124230720.13429.49383@psf.io> https://hg.python.org/cpython/rev/16fec577fd8b changeset: 99330:16fec577fd8b branch: 3.4 parent: 99316:4799615f4f26 user: Martin Panter date: Tue Nov 24 22:33:18 2015 +0000 summary: Issue #25576: Remove application/x-www-form-urlencoded charset advice No charset parameter is standardized for this Content-Type value. Also clarify that urlencode() outputs ASCII. files: Doc/howto/urllib2.rst | 6 ++-- Doc/library/urllib.parse.rst | 9 +++-- Doc/library/urllib.request.rst | 31 +++++---------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -115,7 +115,7 @@ 'language' : 'Python' } data = urllib.parse.urlencode(values) - data = data.encode('utf-8') # data should be bytes + data = data.encode('ascii') # data should be bytes req = urllib.request.Request(url, data) with urllib.request.urlopen(req) as response: the_page = response.read() @@ -180,8 +180,8 @@ 'language' : 'Python' } headers = { 'User-Agent' : user_agent } - data = urllib.parse.urlencode(values) - data = data.encode('utf-8') + data = urllib.parse.urlencode(values) + data = data.encode('ascii') req = urllib.request.Request(url, data, headers) with urllib.request.urlopen(req) as response: the_page = response.read() diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -519,10 +519,11 @@ .. function:: urlencode(query, doseq=False, safe='', encoding=None, errors=None) Convert a mapping object or a sequence of two-element tuples, which may - contain :class:`str` or :class:`bytes` objects, to a "percent-encoded" - string. If the resultant string is to be used as a *data* for POST - operation with :func:`~urllib.request.urlopen` function, then it should be - properly encoded to bytes, otherwise it would result in a :exc:`TypeError`. + contain :class:`str` or :class:`bytes` objects, to a percent-encoded ASCII + text string. If the resultant string is to be used as a *data* for POST + operation with the :func:`~urllib.request.urlopen` function, then + it should be encoded to bytes, otherwise it would result in a + :exc:`TypeError`. The resulting string is a series of ``key=value`` pairs separated by ``'&'`` characters, where both *key* and *value* are quoted using :func:`quote_plus` diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -36,13 +36,8 @@ *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. + 2-tuples and returns an ASCII text string in this format. It should + be encoded to bytes before being used as the *data* parameter. urllib.request module uses HTTP/1.1 and includes ``Connection:close`` header in its HTTP requests. @@ -179,16 +174,9 @@ the only ones that use *data*; the HTTP request will be a POST instead of a GET when the *data* parameter is provided. *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. - The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. - + 2-tuples and returns an ASCII string in this format. It should be + encoded to bytes before being used as the *data* parameter. *headers* should be a dictionary, and will be treated as if :meth:`add_header` was called with each key and value as arguments. @@ -201,7 +189,7 @@ ``"Python-urllib/2.6"`` (on Python 2.6). An example of using ``Content-Type`` header with *data* argument would be - sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}``. + sending a dictionary like ``{"Content-Type": "application/x-www-form-urlencoded"}``. The final two arguments are only of interest for correct handling of third-party HTTP cookies: @@ -1169,7 +1157,7 @@ opener.open('http://www.example.com/') Also, remember that a few standard headers (:mailheader:`Content-Length`, -:mailheader:`Content-Type` without charset parameter and :mailheader:`Host`) +:mailheader:`Content-Type` and :mailheader:`Host`) are added when the :class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`). @@ -1192,11 +1180,8 @@ >>> import urllib.request >>> import urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) - >>> data = data.encode('utf-8') - >>> request = urllib.request.Request("http://requestb.in/xrbl82xr") - >>> # adding charset parameter to the Content-Type header. - >>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8") - >>> with urllib.request.urlopen(request, data) as f: + >>> data = data.encode('ascii') + >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f: ... print(f.read().decode('utf-8')) ... -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:07:21 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 23:07:21 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325576=3A_Merge_www-form-urlencoded_doc_from_3?= =?utf-8?q?=2E5?= Message-ID: <20151124230721.29824.4765@psf.io> https://hg.python.org/cpython/rev/d52521d13a64 changeset: 99332:d52521d13a64 parent: 99329:fb72d6d7703c parent: 99331:95ae5262d27c user: Martin Panter date: Tue Nov 24 22:59:28 2015 +0000 summary: Issue #25576: Merge www-form-urlencoded doc from 3.5 files: Doc/howto/urllib2.rst | 6 ++-- Doc/library/urllib.parse.rst | 9 +++-- Doc/library/urllib.request.rst | 31 +++++---------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -115,7 +115,7 @@ 'language' : 'Python' } data = urllib.parse.urlencode(values) - data = data.encode('utf-8') # data should be bytes + data = data.encode('ascii') # data should be bytes req = urllib.request.Request(url, data) with urllib.request.urlopen(req) as response: the_page = response.read() @@ -180,8 +180,8 @@ 'language' : 'Python' } headers = { 'User-Agent' : user_agent } - data = urllib.parse.urlencode(values) - data = data.encode('utf-8') + data = urllib.parse.urlencode(values) + data = data.encode('ascii') req = urllib.request.Request(url, data, headers) with urllib.request.urlopen(req) as response: the_page = response.read() diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -535,10 +535,11 @@ errors=None, quote_via=quote_plus) Convert a mapping object or a sequence of two-element tuples, which may - contain :class:`str` or :class:`bytes` objects, to a "percent-encoded" - string. If the resultant string is to be used as a *data* for POST - operation with :func:`~urllib.request.urlopen` function, then it should be - properly encoded to bytes, otherwise it would result in a :exc:`TypeError`. + contain :class:`str` or :class:`bytes` objects, to a percent-encoded ASCII + text string. If the resultant string is to be used as a *data* for POST + operation with the :func:`~urllib.request.urlopen` function, then + it should be encoded to bytes, otherwise it would result in a + :exc:`TypeError`. The resulting string is a series of ``key=value`` pairs separated by ``'&'`` characters, where both *key* and *value* are quoted using the *quote_via* diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -36,13 +36,8 @@ *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. + 2-tuples and returns an ASCII text string in this format. It should + be encoded to bytes before being used as the *data* parameter. urllib.request module uses HTTP/1.1 and includes ``Connection:close`` header in its HTTP requests. @@ -180,16 +175,9 @@ the only ones that use *data*; the HTTP request will be a POST instead of a GET when the *data* parameter is provided. *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. - The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. - + 2-tuples and returns an ASCII string in this format. It should be + encoded to bytes before being used as the *data* parameter. *headers* should be a dictionary, and will be treated as if :meth:`add_header` was called with each key and value as arguments. @@ -202,7 +190,7 @@ ``"Python-urllib/2.6"`` (on Python 2.6). An example of using ``Content-Type`` header with *data* argument would be - sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}``. + sending a dictionary like ``{"Content-Type": "application/x-www-form-urlencoded"}``. The final two arguments are only of interest for correct handling of third-party HTTP cookies: @@ -1230,7 +1218,7 @@ opener.open('http://www.example.com/') Also, remember that a few standard headers (:mailheader:`Content-Length`, -:mailheader:`Content-Type` without charset parameter and :mailheader:`Host`) +:mailheader:`Content-Type` and :mailheader:`Host`) are added when the :class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`). @@ -1253,11 +1241,8 @@ >>> import urllib.request >>> import urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) - >>> data = data.encode('utf-8') - >>> request = urllib.request.Request("http://requestb.in/xrbl82xr") - >>> # adding charset parameter to the Content-Type header. - >>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8") - >>> with urllib.request.urlopen(request, data) as f: + >>> data = data.encode('ascii') + >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f: ... print(f.read().decode('utf-8')) ... -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:07:21 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 23:07:21 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325576=3A_Apply_fi?= =?utf-8?q?x_to_new_urlopen=28=29_doc_string?= Message-ID: <20151124230721.13425.4332@psf.io> https://hg.python.org/cpython/rev/671429cc1d96 changeset: 99333:671429cc1d96 user: Martin Panter date: Tue Nov 24 23:00:37 2015 +0000 summary: Issue #25576: Apply fix to new urlopen() doc string files: Lib/urllib/request.py | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -149,13 +149,8 @@ *data* should be a buffer in the standard application/x-www-form-urlencoded format. The urllib.parse.urlencode() function takes a mapping or sequence - of 2-tuples and returns a string in this format. It should be encoded to - bytes before being used as the data parameter. The charset parameter in - Content-Type header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following - the HTTP 1.1 recommendation may assume that the data is encoded in - ISO-8859-1 encoding. It is advisable to use charset parameter with encoding - used in Content-Type header with the Request. + of 2-tuples and returns an ASCII text string in this format. It should be + encoded to bytes before being used as the data parameter. urllib.request module uses HTTP/1.1 and includes a "Connection:close" header in its HTTP requests. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:07:21 2015 From: python-checkins at python.org (martin.panter) Date: Tue, 24 Nov 2015 23:07:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325576=3A_Merge_www-form-urlencoded_doc_from_3=2E4_int?= =?utf-8?q?o_3=2E5?= Message-ID: <20151124230721.81872.36254@psf.io> https://hg.python.org/cpython/rev/95ae5262d27c changeset: 99331:95ae5262d27c branch: 3.5 parent: 99327:f611e2244c69 parent: 99330:16fec577fd8b user: Martin Panter date: Tue Nov 24 22:57:46 2015 +0000 summary: Issue #25576: Merge www-form-urlencoded doc from 3.4 into 3.5 files: Doc/howto/urllib2.rst | 6 ++-- Doc/library/urllib.parse.rst | 9 +++-- Doc/library/urllib.request.rst | 31 +++++---------------- 3 files changed, 16 insertions(+), 30 deletions(-) diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -115,7 +115,7 @@ 'language' : 'Python' } data = urllib.parse.urlencode(values) - data = data.encode('utf-8') # data should be bytes + data = data.encode('ascii') # data should be bytes req = urllib.request.Request(url, data) with urllib.request.urlopen(req) as response: the_page = response.read() @@ -180,8 +180,8 @@ 'language' : 'Python' } headers = { 'User-Agent' : user_agent } - data = urllib.parse.urlencode(values) - data = data.encode('utf-8') + data = urllib.parse.urlencode(values) + data = data.encode('ascii') req = urllib.request.Request(url, data, headers) with urllib.request.urlopen(req) as response: the_page = response.read() diff --git a/Doc/library/urllib.parse.rst b/Doc/library/urllib.parse.rst --- a/Doc/library/urllib.parse.rst +++ b/Doc/library/urllib.parse.rst @@ -525,10 +525,11 @@ errors=None, quote_via=quote_plus) Convert a mapping object or a sequence of two-element tuples, which may - contain :class:`str` or :class:`bytes` objects, to a "percent-encoded" - string. If the resultant string is to be used as a *data* for POST - operation with :func:`~urllib.request.urlopen` function, then it should be - properly encoded to bytes, otherwise it would result in a :exc:`TypeError`. + contain :class:`str` or :class:`bytes` objects, to a percent-encoded ASCII + text string. If the resultant string is to be used as a *data* for POST + operation with the :func:`~urllib.request.urlopen` function, then + it should be encoded to bytes, otherwise it would result in a + :exc:`TypeError`. The resulting string is a series of ``key=value`` pairs separated by ``'&'`` characters, where both *key* and *value* are quoted using the *quote_via* diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -36,13 +36,8 @@ *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. + 2-tuples and returns an ASCII text string in this format. It should + be encoded to bytes before being used as the *data* parameter. urllib.request module uses HTTP/1.1 and includes ``Connection:close`` header in its HTTP requests. @@ -180,16 +175,9 @@ the only ones that use *data*; the HTTP request will be a POST instead of a GET when the *data* parameter is provided. *data* should be a buffer in the standard :mimetype:`application/x-www-form-urlencoded` format. - The :func:`urllib.parse.urlencode` function takes a mapping or sequence of - 2-tuples and returns a string in this format. It should be encoded to bytes - before being used as the *data* parameter. The charset parameter in - ``Content-Type`` header may be used to specify the encoding. If charset - parameter is not sent with the Content-Type header, the server following the - HTTP 1.1 recommendation may assume that the data is encoded in ISO-8859-1 - encoding. It is advisable to use charset parameter with encoding used in - ``Content-Type`` header with the :class:`Request`. - + 2-tuples and returns an ASCII string in this format. It should be + encoded to bytes before being used as the *data* parameter. *headers* should be a dictionary, and will be treated as if :meth:`add_header` was called with each key and value as arguments. @@ -202,7 +190,7 @@ ``"Python-urllib/2.6"`` (on Python 2.6). An example of using ``Content-Type`` header with *data* argument would be - sending a dictionary like ``{"Content-Type":" application/x-www-form-urlencoded;charset=utf-8"}``. + sending a dictionary like ``{"Content-Type": "application/x-www-form-urlencoded"}``. The final two arguments are only of interest for correct handling of third-party HTTP cookies: @@ -1230,7 +1218,7 @@ opener.open('http://www.example.com/') Also, remember that a few standard headers (:mailheader:`Content-Length`, -:mailheader:`Content-Type` without charset parameter and :mailheader:`Host`) +:mailheader:`Content-Type` and :mailheader:`Host`) are added when the :class:`Request` is passed to :func:`urlopen` (or :meth:`OpenerDirector.open`). @@ -1253,11 +1241,8 @@ >>> import urllib.request >>> import urllib.parse >>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0}) - >>> data = data.encode('utf-8') - >>> request = urllib.request.Request("http://requestb.in/xrbl82xr") - >>> # adding charset parameter to the Content-Type header. - >>> request.add_header("Content-Type","application/x-www-form-urlencoded;charset=utf-8") - >>> with urllib.request.urlopen(request, data) as f: + >>> data = data.encode('ascii') + >>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f: ... print(f.read().decode('utf-8')) ... -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:24:30 2015 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2015 23:24:30 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Closes_=2325508=3A_Merged_documentation_fix_from_3=2E5?= =?utf-8?q?=2E?= Message-ID: <20151124232430.31405.64039@psf.io> https://hg.python.org/cpython/rev/1da622f4630b changeset: 99337:1da622f4630b parent: 99333:671429cc1d96 parent: 99336:ca512b568368 user: Vinay Sajip date: Tue Nov 24 23:24:17 2015 +0000 summary: Closes #25508: Merged documentation fix from 3.5. files: Doc/library/logging.rst | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -743,7 +743,9 @@ | Attribute name | Format | Description | +================+=========================+===============================================+ | args | You shouldn't need to | The tuple of arguments merged into ``msg`` to | -| | format this yourself. | produce ``message``. | +| | format this yourself. | produce ``message``, or a dict whose values | +| | | are used for the merge (when there is only one| +| | | argument, and it is a dictionary). | +----------------+-------------------------+-----------------------------------------------+ | asctime | ``%(asctime)s`` | Human-readable time when the | | | | :class:`LogRecord` was created. By default | -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:24:30 2015 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2015 23:24:30 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NTA4?= =?utf-8?q?=3A_Clarify_documentation_on_LogRecord_args_attribute=2E?= Message-ID: <20151124232430.22386.15845@psf.io> https://hg.python.org/cpython/rev/01998efb605a changeset: 99335:01998efb605a branch: 3.4 parent: 99330:16fec577fd8b user: Vinay Sajip date: Tue Nov 24 23:21:15 2015 +0000 summary: Issue #25508: Clarify documentation on LogRecord args attribute. files: Doc/library/logging.rst | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -738,7 +738,9 @@ | Attribute name | Format | Description | +================+=========================+===============================================+ | args | You shouldn't need to | The tuple of arguments merged into ``msg`` to | -| | format this yourself. | produce ``message``. | +| | format this yourself. | produce ``message``, or a dict whose values | +| | | are used for the merge (when there is only one| +| | | argument, and it is a dictionary). | +----------------+-------------------------+-----------------------------------------------+ | asctime | ``%(asctime)s`` | Human-readable time when the | | | | :class:`LogRecord` was created. By default | -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:24:31 2015 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2015 23:24:31 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325508=3A_Merged_documentation_fix_from_3=2E4=2E?= Message-ID: <20151124232430.59403.20885@psf.io> https://hg.python.org/cpython/rev/ca512b568368 changeset: 99336:ca512b568368 branch: 3.5 parent: 99331:95ae5262d27c parent: 99335:01998efb605a user: Vinay Sajip date: Tue Nov 24 23:22:48 2015 +0000 summary: Issue #25508: Merged documentation fix from 3.4. files: Doc/library/logging.rst | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -743,7 +743,9 @@ | Attribute name | Format | Description | +================+=========================+===============================================+ | args | You shouldn't need to | The tuple of arguments merged into ``msg`` to | -| | format this yourself. | produce ``message``. | +| | format this yourself. | produce ``message``, or a dict whose values | +| | | are used for the merge (when there is only one| +| | | argument, and it is a dictionary). | +----------------+-------------------------+-----------------------------------------------+ | asctime | ``%(asctime)s`` | Human-readable time when the | | | | :class:`LogRecord` was created. By default | -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Tue Nov 24 18:24:31 2015 From: python-checkins at python.org (vinay.sajip) Date: Tue, 24 Nov 2015 23:24:31 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NTA4?= =?utf-8?q?=3A_Clarify_documentation_on_LogRecord_args_attribute=2E?= Message-ID: <20151124232430.87879.40143@psf.io> https://hg.python.org/cpython/rev/a365fb0dd5e1 changeset: 99334:a365fb0dd5e1 branch: 2.7 parent: 99324:01444d85bfe0 user: Vinay Sajip date: Tue Nov 24 23:18:30 2015 +0000 summary: Issue #25508: Clarify documentation on LogRecord args attribute. files: Doc/library/logging.rst | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Doc/library/logging.rst b/Doc/library/logging.rst --- a/Doc/library/logging.rst +++ b/Doc/library/logging.rst @@ -622,7 +622,9 @@ | Attribute name | Format | Description | +================+=========================+===============================================+ | args | You shouldn't need to | The tuple of arguments merged into ``msg`` to | -| | format this yourself. | produce ``message``. | +| | format this yourself. | produce ``message``, or a dict whose values | +| | | are used for the merge (when there is only one| +| | | argument, and it is a dictionary). | +----------------+-------------------------+-----------------------------------------------+ | asctime | ``%(asctime)s`` | Human-readable time when the | | | | :class:`LogRecord` was created. By default | -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 00:29:01 2015 From: python-checkins at python.org (zach.ware) Date: Wed, 25 Nov 2015 05:29:01 +0000 Subject: [Python-checkins] =?utf-8?q?benchmarks=3A_Fix_typo_resulting_in_N?= =?utf-8?q?ameError?= Message-ID: <20151125052901.22388.87910@psf.io> https://hg.python.org/benchmarks/rev/ecd113b086e4 changeset: 233:ecd113b086e4 user: Zachary Ware date: Thu Nov 12 15:50:29 2015 -0600 summary: Fix typo resulting in NameError files: perf.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/perf.py b/perf.py --- a/perf.py +++ b/perf.py @@ -1082,7 +1082,7 @@ assert exp_data.mem_usage is not None return CompareMemoryUsage(base_data.mem_usage, exp_data.mem_usage, options) - return BencharkError("Benchmark does not report memory usage yet") + return BenchmarkError("Benchmark does not report memory usage yet") if options.diff_instrumentation: inst_diff = DiffInstrumentation(base_data.inst_output, exp_data.inst_output) -- Repository URL: https://hg.python.org/benchmarks From python-checkins at python.org Wed Nov 25 00:29:05 2015 From: python-checkins at python.org (zach.ware) Date: Wed, 25 Nov 2015 05:29:05 +0000 Subject: [Python-checkins] =?utf-8?q?benchmarks=3A_Add_=2Eidea/_to_=2Ehgig?= =?utf-8?q?nore?= Message-ID: <20151125052901.81878.74977@psf.io> https://hg.python.org/benchmarks/rev/90b842aacb64 changeset: 232:90b842aacb64 user: Zachary Ware date: Thu Nov 12 15:50:07 2015 -0600 summary: Add .idea/ to .hgignore files: .hgignore | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -8,6 +8,7 @@ lib3/2to3/lib2to3/*.pickle *.cover *~ +.idea/ .coverage coverage/ htmlcov/ -- Repository URL: https://hg.python.org/benchmarks From python-checkins at python.org Wed Nov 25 00:29:05 2015 From: python-checkins at python.org (zach.ware) Date: Wed, 25 Nov 2015 05:29:05 +0000 Subject: [Python-checkins] =?utf-8?q?benchmarks=3A_Fix_usage_of_re=2Epurge?= =?utf-8?q?=28=29_in_bm=5Fregex=5Fcompile?= Message-ID: <20151125052901.69560.93488@psf.io> https://hg.python.org/benchmarks/rev/f7283190e896 changeset: 234:f7283190e896 user: Zachary Ware date: Thu Nov 12 23:16:25 2015 -0600 summary: Fix usage of re.purge() in bm_regex_compile files: performance/bm_regex_compile.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/performance/bm_regex_compile.py b/performance/bm_regex_compile.py --- a/performance/bm_regex_compile.py +++ b/performance/bm_regex_compile.py @@ -53,14 +53,13 @@ def test_regex_compile(count, timer): - re.purge() regexes = capture_regexes() times = [] for _ in xrange(count): t0 = timer() for regex, flags in regexes: - clear_cache() + re.purge() re.compile(regex, flags) t1 = timer() times.append(t1 - t0) -- Repository URL: https://hg.python.org/benchmarks From solipsis at pitrou.net Wed Nov 25 03:43:35 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 25 Nov 2015 08:43:35 +0000 Subject: [Python-checkins] Daily reference leaks (1da622f4630b): sum=109 Message-ID: <20151125084334.81854.39013@psf.io> results for 1da622f4630b on branch "default" -------------------------------------------- test_collections leaked [6, 0, 0] references, sum=6 test_collections leaked [3, 0, 0] memory blocks, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 test_pickle leaked [20, 20, 20] references, sum=60 test_pickle leaked [12, 12, 12] memory blocks, sum=36 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogXzWlAn', '--timeout', '7200'] From python-checkins at python.org Wed Nov 25 04:56:20 2015 From: python-checkins at python.org (victor.stinner) Date: Wed, 25 Nov 2015 09:56:20 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_Issue_=2325712=3A_Fix_link_to?= =?utf-8?q?_the_marshal_doc_in_PEP_3147?= Message-ID: <20151125095620.662.54159@psf.io> https://hg.python.org/peps/rev/a34df6445747 changeset: 6131:a34df6445747 user: Victor Stinner date: Wed Nov 25 10:56:15 2015 +0100 summary: Issue #25712: Fix link to the marshal doc in PEP 3147 files: pep-3147.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/pep-3147.txt b/pep-3147.txt --- a/pep-3147.txt +++ b/pep-3147.txt @@ -568,7 +568,7 @@ .. [1] PEP 3146 .. [2] The marshal module: - http://www.python.org/doc/current/library/marshal.html + https://docs.python.org/dev/library/marshal.html .. [3] import.c: http://svn.python.org/view/python/branches/py3k/Python/import.c?view=markup -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Wed Nov 25 05:23:48 2015 From: python-checkins at python.org (victor.stinner) Date: Wed, 25 Nov 2015 10:23:48 +0000 Subject: [Python-checkins] =?utf-8?q?benchmarks=3A_Issue_=2325721=3A_Fixes?= =?utf-8?q?_for_pybench?= Message-ID: <20151125102348.29802.71878@psf.io> https://hg.python.org/benchmarks/rev/e77ed7d18a68 changeset: 235:e77ed7d18a68 user: Victor Stinner date: Wed Nov 25 11:17:24 2015 +0100 summary: Issue #25721: Fixes for pybench * Write a base class for benchmark result classes to ensure that always_display attribute is set * Implement table output format for pybench files: perf.py | 63 +++++++++++++++++++++++++++++++++++---------- 1 files changed, 49 insertions(+), 14 deletions(-) diff --git a/perf.py b/perf.py --- a/perf.py +++ b/perf.py @@ -420,7 +420,17 @@ self.inst_output = inst_output -class BenchmarkResult(object): +class BaseBenchmarkResult(object): + always_display = True + + def __str__(self): + raise NotImplementedError + + def as_csv(self): + raise NotImplementedError + + +class BenchmarkResult(BaseBenchmarkResult): """An object representing data from a succesful benchmark run.""" def __init__(self, min_base, min_changed, delta_min, avg_base, @@ -458,11 +468,9 @@ return ["%f" % self.min_base, "%f" % self.min_changed] -class BenchmarkError(object): +class BenchmarkError(BaseBenchmarkResult): """Object representing the error from a failed benchmark run.""" - always_display = True - def __init__(self, e): self.msg = str(e) @@ -470,11 +478,9 @@ return self.msg -class MemoryUsageResult(object): +class MemoryUsageResult(BaseBenchmarkResult): """Memory usage data from a successful benchmark run.""" - always_display = True - def __init__(self, max_base, max_changed, delta_max, timeline_link): self.max_base = max_base self.max_changed = max_changed @@ -496,11 +502,9 @@ return ["%.3f" % self.max_base, "%.3f" % self.max_changed] -class SimpleBenchmarkResult(object): +class SimpleBenchmarkResult(BaseBenchmarkResult): """Object representing result data from a successful benchmark run.""" - always_display = True - def __init__(self, base_time, changed_time, time_delta): self.base_time = base_time self.changed_time = changed_time @@ -515,11 +519,9 @@ return ["%f" % self.base_time, "%f" % self.changed_time] -class InstrumentationResult(object): +class InstrumentationResult(BaseBenchmarkResult): """Object respresenting a --diff_instrumentation result.""" - always_display = True - def __init__(self, inst_diff, options): self.inst_diff = inst_diff self._control_label = options.control_label @@ -599,6 +601,33 @@ return table +def _FormatPyBenchDataForTable(base_label, changed_label, results): + """Prepare PyBench performance data for tabular output. + + Args: + base_label: label for the control binary. + changed_label: label for the experimental binary. + results: iterable of (bench_name, result) 2-tuples where bench_name is + the name of the benchmark being reported; and result is a + PyBenchBenchmarkResult object. + + Returns: + A list of 4-tuples, where each tuple corresponds to a row in the output + table, and each item in the tuples corresponds to a cell in the output + table. + """ + table = [("Benchmark", base_label, changed_label, "Change")] + + for (bench_name, result) in results: + table.append((bench_name, + # Limit the precision for conciseness in the table. + str(round(result.avg_base, 2)), + str(round(result.avg_changed, 2)), + result.delta_avg)) + + return table + + def _FormatMemoryUsageForTable(base_label, changed_label, results): """Prepare memory usage data for tabular output. @@ -644,6 +673,8 @@ table = _FormatPerfDataForTable(base_label, changed_label, results) elif isinstance(results[0][1], MemoryUsageResult): table = _FormatMemoryUsageForTable(base_label, changed_label, results) + elif isinstance(results[0][1], PyBenchBenchmarkResult): + table = _FormatPyBenchDataForTable(base_label, changed_label, results) else: raise TypeError("Unknown result type: %r" % type(results[0][1])) @@ -1183,7 +1214,7 @@ return deco -class PyBenchBenchmarkResult(object): +class PyBenchBenchmarkResult(BaseBenchmarkResult): def __init__(self, min_base, min_changed, delta_min, avg_base, avg_changed, delta_avg): @@ -1199,6 +1230,10 @@ "Avg: %(avg_base)d -> %(avg_changed)d: %(delta_avg)s") % self.__dict__) + def as_csv(self): + # Min base, min changed + return ["%f" % self.min_base, "%f" % self.min_changed] + _PY_BENCH_TOTALS_LINE = re.compile(""" Totals:\s+(?P\d+)ms\s+ -- Repository URL: https://hg.python.org/benchmarks From lp_benchmark_robot at intel.com Wed Nov 25 07:16:10 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 25 Nov 2015 12:16:10 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-25 Message-ID: <5eeb1343-75d5-4013-8037-23434db4867c@irsmsx103.ger.corp.intel.com> Results for project Python 2.7, build date 2015-11-25 04:49:27 +0000 commit: a365fb0dd5e1282dbf7b3e17a62f576a20e8f322 revision date: 2015-11-24 23:18:30 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.36% 0.36% 2.48% 9.91% :-) pybench 0.20% -0.03% 5.96% 7.03% :-( regex_v8 0.66% 0.06% -2.10% 8.36% :-) nbody 0.41% -0.10% 7.58% 5.58% :-| json_dump_v2 0.29% 0.10% 0.77% 14.93% :-| normal_startup 1.92% 0.40% -1.55% 3.15% :-| ssbench 0.32% 0.26% 0.64% 1.26% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Wed Nov 25 07:15:46 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 25 Nov 2015 12:15:46 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-25 Message-ID: Results for project Python default, build date 2015-11-25 04:02:09 +0000 commit: 1da622f4630bfe9f9059414ef009088619bbe04f revision date: 2015-11-24 23:24:17 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% 1.74% 9.55% 15.45% :-( pybench 0.16% 0.33% -2.16% 9.21% :-( regex_v8 3.15% -0.03% -5.44% 7.32% :-| nbody 0.14% 0.03% -1.93% 12.13% :-| json_dump_v2 0.28% -0.62% -0.16% 10.97% :-| normal_startup 0.93% 0.11% 0.26% 4.93% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Wed Nov 25 08:08:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:08:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NzI1?= =?utf-8?q?=3A_Fixed_a_reference_leak_in_pickle=2Eloads=28=29_when_unpickl?= =?utf-8?q?ing?= Message-ID: <20151125130814.31373.97452@psf.io> https://hg.python.org/cpython/rev/c85eca74f3a5 changeset: 99338:c85eca74f3a5 branch: 3.4 parent: 99335:01998efb605a user: Serhiy Storchaka date: Wed Nov 25 15:01:53 2015 +0200 summary: Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. files: Misc/NEWS | 3 ++ Modules/_pickle.c | 39 ++++++++++++---------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -106,6 +106,9 @@ Library ------- +- Issue #25725: Fixed a reference leak in pickle.loads() when unpickling + invalid data including tuple instructions. + - Issue #25663: In the Readline completer, avoid listing duplicate global names, and search the global namespace before searching builtins. diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4915,15 +4915,14 @@ } static int -load_tuple(UnpicklerObject *self) +load_counted_tuple(UnpicklerObject *self, int len) { PyObject *tuple; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - tuple = Pdata_poptuple(self->stack, i); + + if (Py_SIZE(self->stack) < len) + return stack_underflow(); + + tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); if (tuple == NULL) return -1; PDATA_PUSH(self->stack, tuple, -1); @@ -4931,24 +4930,14 @@ } static int -load_counted_tuple(UnpicklerObject *self, int len) -{ - PyObject *tuple; - - tuple = PyTuple_New(len); - if (tuple == NULL) - return -1; - - while (--len >= 0) { - PyObject *item; - - PDATA_POP(self->stack, item); - if (item == NULL) - return -1; - PyTuple_SET_ITEM(tuple, len, item); - } - PDATA_PUSH(self->stack, tuple, -1); - return 0; +load_tuple(UnpicklerObject *self) +{ + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + return load_counted_tuple(self, Py_SIZE(self->stack) - i); } static int -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:08:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:08:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325725=3A_Fixed_a_reference_leak_in_pickle=2Eloads=28?= =?utf-8?q?=29_when_unpickling?= Message-ID: <20151125130814.29830.54776@psf.io> https://hg.python.org/cpython/rev/88ad2b8480b1 changeset: 99339:88ad2b8480b1 branch: 3.5 parent: 99336:ca512b568368 parent: 99338:c85eca74f3a5 user: Serhiy Storchaka date: Wed Nov 25 15:06:49 2015 +0200 summary: Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. files: Misc/NEWS | 3 ++ Modules/_pickle.c | 39 ++++++++++++---------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25725: Fixed a reference leak in pickle.loads() when unpickling + invalid data including tuple instructions. + - Issue #25663: In the Readline completer, avoid listing duplicate global names, and search the global namespace before searching builtins. diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -4984,15 +4984,14 @@ } static int -load_tuple(UnpicklerObject *self) +load_counted_tuple(UnpicklerObject *self, int len) { PyObject *tuple; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - tuple = Pdata_poptuple(self->stack, i); + + if (Py_SIZE(self->stack) < len) + return stack_underflow(); + + tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); if (tuple == NULL) return -1; PDATA_PUSH(self->stack, tuple, -1); @@ -5000,24 +4999,14 @@ } static int -load_counted_tuple(UnpicklerObject *self, int len) -{ - PyObject *tuple; - - tuple = PyTuple_New(len); - if (tuple == NULL) - return -1; - - while (--len >= 0) { - PyObject *item; - - PDATA_POP(self->stack, item); - if (item == NULL) - return -1; - PyTuple_SET_ITEM(tuple, len, item); - } - PDATA_PUSH(self->stack, tuple, -1); - return 0; +load_tuple(UnpicklerObject *self) +{ + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + return load_counted_tuple(self, Py_SIZE(self->stack) - i); } static int -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:08:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:08:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325725=3A_Fixed_a_reference_leak_in_pickle=2Eloa?= =?utf-8?q?ds=28=29_when_unpickling?= Message-ID: <20151125130814.29826.27581@psf.io> https://hg.python.org/cpython/rev/935debb548a3 changeset: 99340:935debb548a3 parent: 99337:1da622f4630b parent: 99339:88ad2b8480b1 user: Serhiy Storchaka date: Wed Nov 25 15:07:36 2015 +0200 summary: Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. files: Misc/NEWS | 3 ++ Modules/_pickle.c | 39 ++++++++++++---------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,9 @@ Library ------- +- Issue #25725: Fixed a reference leak in pickle.loads() when unpickling + invalid data including tuple instructions. + - Issue #25663: In the Readline completer, avoid listing duplicate global names, and search the global namespace before searching builtins. diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5047,15 +5047,14 @@ } static int -load_tuple(UnpicklerObject *self) +load_counted_tuple(UnpicklerObject *self, int len) { PyObject *tuple; - Py_ssize_t i; - - if ((i = marker(self)) < 0) - return -1; - - tuple = Pdata_poptuple(self->stack, i); + + if (Py_SIZE(self->stack) < len) + return stack_underflow(); + + tuple = Pdata_poptuple(self->stack, Py_SIZE(self->stack) - len); if (tuple == NULL) return -1; PDATA_PUSH(self->stack, tuple, -1); @@ -5063,24 +5062,14 @@ } static int -load_counted_tuple(UnpicklerObject *self, int len) -{ - PyObject *tuple; - - tuple = PyTuple_New(len); - if (tuple == NULL) - return -1; - - while (--len >= 0) { - PyObject *item; - - PDATA_POP(self->stack, item); - if (item == NULL) - return -1; - PyTuple_SET_ITEM(tuple, len, item); - } - PDATA_PUSH(self->stack, tuple, -1); - return 0; +load_tuple(UnpicklerObject *self) +{ + Py_ssize_t i; + + if ((i = marker(self)) < 0) + return -1; + + return load_counted_tuple(self, Py_SIZE(self->stack) - i); } static int -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:08:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:08:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NzI1?= =?utf-8?q?=3A_Fixed_a_reference_leak_in_cPickle=2Eloads=28=29_when_unpick?= =?utf-8?q?ling?= Message-ID: <20151125130814.662.26632@psf.io> https://hg.python.org/cpython/rev/9a4db1ac5e10 changeset: 99341:9a4db1ac5e10 branch: 2.7 parent: 99334:a365fb0dd5e1 user: Serhiy Storchaka date: Wed Nov 25 15:07:49 2015 +0200 summary: Issue #25725: Fixed a reference leak in cPickle.loads() when unpickling invalid data including tuple instructions. files: Misc/NEWS | 3 +++ Modules/cPickle.c | 33 ++++++++++++--------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -13,6 +13,9 @@ Library ------- +- Issue #25725: Fixed a reference leak in cPickle.loads() when unpickling + invalid data including tuple instructions. + - Issue #25663: In the Readline completer, avoid listing duplicate global names, and search the global namespace before searching builtins. diff --git a/Modules/cPickle.c b/Modules/cPickle.c --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -3798,35 +3798,26 @@ static int -load_tuple(Unpicklerobject *self) +load_counted_tuple(Unpicklerobject *self, int len) { PyObject *tup; - Py_ssize_t i; - - if ((i = marker(self)) < 0) return -1; - if (!( tup=Pdata_popTuple(self->stack, i))) return -1; + + if (self->stack->length < len) + return stackUnderflow(); + + if (!(tup = Pdata_popTuple(self->stack, self->stack->length - len))) + return -1; PDATA_PUSH(self->stack, tup, -1); return 0; } static int -load_counted_tuple(Unpicklerobject *self, int len) +load_tuple(Unpicklerobject *self) { - PyObject *tup = PyTuple_New(len); - - if (tup == NULL) - return -1; - - while (--len >= 0) { - PyObject *element; - - PDATA_POP(self->stack, element); - if (element == NULL) - return -1; - PyTuple_SET_ITEM(tup, len, element); - } - PDATA_PUSH(self->stack, tup, -1); - return 0; + Py_ssize_t i; + + if ((i = marker(self)) < 0) return -1; + return load_counted_tuple(self, self->stack->length - i); } static int -- Repository URL: https://hg.python.org/cpython From brett at snarky.ca Tue Nov 24 14:31:48 2015 From: brett at snarky.ca (Brett Cannon) Date: Tue, 24 Nov 2015 19:31:48 +0000 Subject: [Python-checkins] Daily reference leaks (e5e507a357a6): sum=103 In-Reply-To: <20151124084506.81870.97482@psf.io> References: <20151124084506.81870.97482@psf.io> Message-ID: Someone just added a leak to pickle. On Tue, 24 Nov 2015 at 01:45 wrote: > results for e5e507a357a6 on branch "default" > -------------------------------------------- > > test_asyncio leaked [3, 0, 0] memory blocks, sum=3 > test_functools leaked [0, 2, 2] memory blocks, sum=4 > test_pickle leaked [20, 20, 20] references, sum=60 > test_pickle leaked [12, 12, 12] memory blocks, sum=36 > > > Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', > '3:3:/home/psf-users/antoine/refleaks/reflogUP9efi', '--timeout', '7200'] > _______________________________________________ > Python-checkins mailing list > Python-checkins at python.org > https://mail.python.org/mailman/listinfo/python-checkins > -------------- next part -------------- An HTML attachment was scrubbed... URL: From python-checkins at python.org Wed Nov 25 08:28:50 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:28:50 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbjogSXNzdWUgIzc5OTA6IGRpcigp?= =?utf-8?q?_on_ElementTree=2EElement_now_lists_properties=3A_=22tag=22=2C?= Message-ID: <20151125132850.662.62223@psf.io> https://hg.python.org/cpython/rev/fef7f041c1a7 changeset: 99342:fef7f041c1a7 parent: 99340:935debb548a3 user: Serhiy Storchaka date: Wed Nov 25 15:28:13 2015 +0200 summary: Issue #7990: dir() on ElementTree.Element now lists properties: "tag", "text", "tail" and "attrib". Original patch by Santoso Wijaya. files: Lib/test/test_xml_etree.py | 10 +- Misc/NEWS | 3 + Modules/_elementtree.c | 184 +++++++++++++----------- 3 files changed, 110 insertions(+), 87 deletions(-) diff --git a/Lib/test/test_xml_etree.py b/Lib/test/test_xml_etree.py --- a/Lib/test/test_xml_etree.py +++ b/Lib/test/test_xml_etree.py @@ -182,10 +182,12 @@ def check_element(element): self.assertTrue(ET.iselement(element), msg="not an element") - self.assertTrue(hasattr(element, "tag"), msg="no tag member") - self.assertTrue(hasattr(element, "attrib"), msg="no attrib member") - self.assertTrue(hasattr(element, "text"), msg="no text member") - self.assertTrue(hasattr(element, "tail"), msg="no tail member") + direlem = dir(element) + for attr in 'tag', 'attrib', 'text', 'tail': + self.assertTrue(hasattr(element, attr), + msg='no %s member' % attr) + self.assertIn(attr, direlem, + msg='no %s visible by dir' % attr) check_string(element.tag) check_mapping(element.attrib) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -95,6 +95,9 @@ Library ------- +- Issue #7990: dir() on ElementTree.Element now lists properties: "tag", + "text", "tail" and "attrib". Original patch by Santoso Wijaya. + - Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1870,94 +1870,92 @@ } static PyObject* -element_getattro(ElementObject* self, PyObject* nameobj) +element_tag_getter(ElementObject *self, void *closure) { - PyObject* res; - char *name = ""; - - if (PyUnicode_Check(nameobj)) - name = _PyUnicode_AsString(nameobj); - - if (name == NULL) - return NULL; - - /* handle common attributes first */ - if (strcmp(name, "tag") == 0) { - res = self->tag; - Py_INCREF(res); - return res; - } else if (strcmp(name, "text") == 0) { - res = element_get_text(self); - Py_XINCREF(res); - return res; - } - - /* methods */ - res = PyObject_GenericGetAttr((PyObject*) self, nameobj); - if (res) - return res; - - /* less common attributes */ - if (strcmp(name, "tail") == 0) { - PyErr_Clear(); - res = element_get_tail(self); - } else if (strcmp(name, "attrib") == 0) { - PyErr_Clear(); - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return NULL; - } - res = element_get_attrib(self); - } - - if (!res) - return NULL; - + PyObject *res = self->tag; Py_INCREF(res); return res; } +static PyObject* +element_text_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_text(self); + Py_XINCREF(res); + return res; +} + +static PyObject* +element_tail_getter(ElementObject *self, void *closure) +{ + PyObject *res = element_get_tail(self); + Py_XINCREF(res); + return res; +} + +static PyObject* +element_attrib_getter(ElementObject *self, void *closure) +{ + PyObject *res; + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return NULL; + } + res = element_get_attrib(self); + Py_XINCREF(res); + return res; +} + +/* macro for setter validation */ +#define _VALIDATE_ATTR_VALUE(V) \ + if ((V) == NULL) { \ + PyErr_SetString( \ + PyExc_AttributeError, \ + "can't delete element attribute"); \ + return -1; \ + } + static int -element_setattro(ElementObject* self, PyObject* nameobj, PyObject* value) +element_tag_setter(ElementObject *self, PyObject *value, void *closure) { - char *name = ""; - - if (value == NULL) { - PyErr_SetString(PyExc_AttributeError, - "can't delete attribute"); - return -1; + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_DECREF(self->tag); + self->tag = value; + return 0; +} + +static int +element_text_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_DECREF(JOIN_OBJ(self->text)); + self->text = value; + return 0; +} + +static int +element_tail_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + Py_INCREF(value); + Py_DECREF(JOIN_OBJ(self->tail)); + self->tail = value; + return 0; +} + +static int +element_attrib_setter(ElementObject *self, PyObject *value, void *closure) +{ + _VALIDATE_ATTR_VALUE(value); + if (!self->extra) { + if (create_extra(self, NULL) < 0) + return -1; } - if (PyUnicode_Check(nameobj)) - name = _PyUnicode_AsString(nameobj); - if (name == NULL) - return -1; - - if (strcmp(name, "tag") == 0) { - Py_DECREF(self->tag); - self->tag = value; - Py_INCREF(self->tag); - } else if (strcmp(name, "text") == 0) { - Py_DECREF(JOIN_OBJ(self->text)); - self->text = value; - Py_INCREF(self->text); - } else if (strcmp(name, "tail") == 0) { - Py_DECREF(JOIN_OBJ(self->tail)); - self->tail = value; - Py_INCREF(self->tail); - } else if (strcmp(name, "attrib") == 0) { - if (!self->extra) { - if (create_extra(self, NULL) < 0) - return -1; - } - Py_DECREF(self->extra->attrib); - self->extra->attrib = value; - Py_INCREF(self->extra->attrib); - } else { - PyErr_SetString(PyExc_AttributeError, - "Can't set arbitrary attributes on Element"); - return -1; - } - + Py_INCREF(value); + Py_DECREF(self->extra->attrib); + self->extra->attrib = value; return 0; } @@ -3770,6 +3768,26 @@ (objobjargproc) element_ass_subscr, }; +static PyGetSetDef element_getsetlist[] = { + {"tag", + (getter)element_tag_getter, + (setter)element_tag_setter, + "A string identifying what kind of data this element represents"}, + {"text", + (getter)element_text_getter, + (setter)element_text_setter, + "A string of text directly after the start tag, or None"}, + {"tail", + (getter)element_tail_getter, + (setter)element_tail_setter, + "A string of text directly after the end tag, or None"}, + {"attrib", + (getter)element_attrib_getter, + (setter)element_attrib_setter, + "A dictionary containing the element's attributes"}, + {NULL}, +}; + static PyTypeObject Element_Type = { PyVarObject_HEAD_INIT(NULL, 0) "xml.etree.ElementTree.Element", sizeof(ElementObject), 0, @@ -3786,8 +3804,8 @@ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - (getattrofunc)element_getattro, /* tp_getattro */ - (setattrofunc)element_setattro, /* tp_setattro */ + PyObject_GenericGetAttr, /* tp_getattro */ + 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /* tp_flags */ @@ -3800,7 +3818,7 @@ 0, /* tp_iternext */ element_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ + element_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:56:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:56:47 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0NzMx?= =?utf-8?q?=3A_Fixed_crash_on_converting_objects_with_special_methods?= Message-ID: <20151125135647.22384.60246@psf.io> https://hg.python.org/cpython/rev/d8e0b54ece62 changeset: 99343:d8e0b54ece62 branch: 3.4 parent: 99338:c85eca74f3a5 user: Serhiy Storchaka date: Wed Nov 25 15:47:01 2015 +0200 summary: Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. files: Lib/test/test_bytes.py | 11 +++++++++++ Lib/test/test_float.py | 15 +++++++++++++++ Lib/test/test_int.py | 7 +++++++ Lib/test/test_unicode.py | 11 +++++++---- Misc/NEWS | 4 ++++ Objects/bytesobject.c | 8 ++++---- Objects/floatobject.c | 2 +- Objects/longobject.c | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -744,6 +744,14 @@ def __index__(self): return 42 self.assertEqual(bytes(A()), b'a') + # Issue #24731 + class A: + def __bytes__(self): + return OtherBytesSubclass(b'abc') + self.assertEqual(bytes(A()), b'abc') + self.assertIs(type(bytes(A())), OtherBytesSubclass) + self.assertEqual(BytesSubclass(A()), b'abc') + self.assertIs(type(BytesSubclass(A())), BytesSubclass) # Test PyBytes_FromFormat() def test_from_format(self): @@ -1465,6 +1473,9 @@ class BytesSubclass(bytes): pass +class OtherBytesSubclass(bytes): + pass + class ByteArraySubclassTest(SubclassTest, unittest.TestCase): type2test = bytearray subclass2test = ByteArraySubclass diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -25,6 +25,12 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +class FloatSubclass(float): + pass + +class OtherFloatSubclass(float): + pass + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -167,6 +173,15 @@ return "" self.assertRaises(TypeError, time.sleep, Foo5()) + # Issue #24731 + class F: + def __float__(self): + return OtherFloatSubclass(42.) + self.assertAlmostEqual(float(F()), 42.) + self.assertIs(type(float(F())), OtherFloatSubclass) + self.assertAlmostEqual(FloatSubclass(F()), 42.) + self.assertIs(type(FloatSubclass(F())), FloatSubclass) + def test_is_integer(self): self.assertFalse((1.1).is_integer()) self.assertTrue((1.).is_integer()) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -24,6 +24,9 @@ ("\u0200", ValueError) ] +class IntSubclass(int): + pass + class IntTestCases(unittest.TestCase): def test_basic(self): @@ -441,6 +444,10 @@ good_int = TruncReturnsIntSubclass() n = int(good_int) self.assertEqual(n, 1) + self.assertIs(type(n), bool) + n = IntSubclass(good_int) + self.assertEqual(n, 1) + self.assertIs(type(n), IntSubclass) def test_error_message(self): def check(s, base=None): diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -42,6 +42,9 @@ """ return text.encode().decode() +class StrSubclass(str): + pass + class UnicodeTest(string_tests.CommonTest, string_tests.MixinStrUnicodeUserStringTest, string_tests.MixinStrUnicodeTest, @@ -1412,11 +1415,8 @@ 'unicode remains unicode' ) - class UnicodeSubclass(str): - pass - for text in ('ascii', '\xe9', '\u20ac', '\U0010FFFF'): - subclass = UnicodeSubclass(text) + subclass = StrSubclass(text) self.assertEqual(str(subclass), text) self.assertEqual(len(subclass), len(text)) if text == 'ascii': @@ -2169,6 +2169,9 @@ s = str(StrSubclassToStrSubclass("foo")) self.assertEqual(s, "foofoo") self.assertIs(type(s), StrSubclassToStrSubclass) + s = StrSubclass(StrSubclassToStrSubclass("foo")) + self.assertEqual(s, "foofoo") + self.assertIs(type(s), StrSubclass) def test_unicode_repr(self): class s1: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24731: Fixed crash on converting objects with special methods + __bytes__, __trunc__, and __float__ returning instances of subclasses of + bytes, int, and float to subclasses of bytes, int, and float correspondingly. + - Issue #25388: Fixed tokenizer crash when processing undecodable source code with a null byte. diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -2445,7 +2445,7 @@ }; static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -2460,7 +2460,7 @@ _Py_IDENTIFIER(__bytes__); if (type != &PyBytes_Type) - return str_subtype_new(type, args, kwds); + return bytes_subtype_new(type, args, kwds); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, &encoding, &errors)) return NULL; @@ -2687,7 +2687,7 @@ } static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *tmp, *pnew; Py_ssize_t n; @@ -2696,7 +2696,7 @@ tmp = bytes_new(&PyBytes_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyBytes_CheckExact(tmp)); + assert(PyBytes_Check(tmp)); n = PyBytes_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); if (pnew != NULL) { diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1567,7 +1567,7 @@ tmp = float_new(&PyFloat_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyFloat_CheckExact(tmp)); + assert(PyFloat_Check(tmp)); newobj = type->tp_alloc(type, 0); if (newobj == NULL) { Py_DECREF(tmp); diff --git a/Objects/longobject.c b/Objects/longobject.c --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4405,7 +4405,7 @@ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyLong_CheckExact(tmp)); + assert(PyLong_Check(tmp)); n = Py_SIZE(tmp); if (n < 0) n = -n; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:56:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:56:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324731=3A_Fixed_crash_on_converting_objects_with?= =?utf-8?q?_special_methods?= Message-ID: <20151125135647.22392.89805@psf.io> https://hg.python.org/cpython/rev/1c4d256cc370 changeset: 99345:1c4d256cc370 parent: 99342:fef7f041c1a7 parent: 99344:80efe5cc8934 user: Serhiy Storchaka date: Wed Nov 25 15:53:19 2015 +0200 summary: Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. files: Lib/test/test_bytes.py | 11 +++++++++++ Lib/test/test_float.py | 15 +++++++++++++++ Lib/test/test_int.py | 7 +++++++ Lib/test/test_unicode.py | 11 +++++++---- Misc/NEWS | 4 ++++ Objects/bytesobject.c | 8 ++++---- Objects/floatobject.c | 2 +- Objects/longobject.c | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -793,6 +793,14 @@ def __index__(self): return 42 self.assertEqual(bytes(A()), b'a') + # Issue #24731 + class A: + def __bytes__(self): + return OtherBytesSubclass(b'abc') + self.assertEqual(bytes(A()), b'abc') + self.assertIs(type(bytes(A())), OtherBytesSubclass) + self.assertEqual(BytesSubclass(A()), b'abc') + self.assertIs(type(BytesSubclass(A())), BytesSubclass) # Test PyBytes_FromFormat() def test_from_format(self): @@ -1647,6 +1655,9 @@ class BytesSubclass(bytes): pass +class OtherBytesSubclass(bytes): + pass + class ByteArraySubclassTest(SubclassTest, unittest.TestCase): type2test = bytearray subclass2test = ByteArraySubclass diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -25,6 +25,12 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +class FloatSubclass(float): + pass + +class OtherFloatSubclass(float): + pass + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -167,6 +173,15 @@ return "" self.assertRaises(TypeError, time.sleep, Foo5()) + # Issue #24731 + class F: + def __float__(self): + return OtherFloatSubclass(42.) + self.assertAlmostEqual(float(F()), 42.) + self.assertIs(type(float(F())), OtherFloatSubclass) + self.assertAlmostEqual(FloatSubclass(F()), 42.) + self.assertIs(type(FloatSubclass(F())), FloatSubclass) + def test_is_integer(self): self.assertFalse((1.1).is_integer()) self.assertTrue((1.).is_integer()) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -24,6 +24,9 @@ ("\u0200", ValueError) ] +class IntSubclass(int): + pass + class IntTestCases(unittest.TestCase): def test_basic(self): @@ -441,6 +444,10 @@ good_int = TruncReturnsIntSubclass() n = int(good_int) self.assertEqual(n, 1) + self.assertIs(type(n), bool) + n = IntSubclass(good_int) + self.assertEqual(n, 1) + self.assertIs(type(n), IntSubclass) def test_error_message(self): def check(s, base=None): diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -43,6 +43,9 @@ """ return text.encode().decode() +class StrSubclass(str): + pass + class UnicodeTest(string_tests.CommonTest, string_tests.MixinStrUnicodeUserStringTest, string_tests.MixinStrUnicodeTest, @@ -1441,11 +1444,8 @@ 'unicode remains unicode' ) - class UnicodeSubclass(str): - pass - for text in ('ascii', '\xe9', '\u20ac', '\U0010FFFF'): - subclass = UnicodeSubclass(text) + subclass = StrSubclass(text) self.assertEqual(str(subclass), text) self.assertEqual(len(subclass), len(text)) if text == 'ascii': @@ -2199,6 +2199,9 @@ s = str(StrSubclassToStrSubclass("foo")) self.assertEqual(s, "foofoo") self.assertIs(type(s), StrSubclassToStrSubclass) + s = StrSubclass(StrSubclassToStrSubclass("foo")) + self.assertEqual(s, "foofoo") + self.assertIs(type(s), StrSubclass) def test_unicode_repr(self): class s1: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24731: Fixed crash on converting objects with special methods + __bytes__, __trunc__, and __float__ returning instances of subclasses of + bytes, int, and float to subclasses of bytes, int, and float correspondingly. + - Issue #25630: Fix a possible segfault during argument parsing in functions that accept filesystem paths. diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3291,7 +3291,7 @@ }; static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -3306,7 +3306,7 @@ _Py_IDENTIFIER(__bytes__); if (type != &PyBytes_Type) - return str_subtype_new(type, args, kwds); + return bytes_subtype_new(type, args, kwds); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, &encoding, &errors)) return NULL; @@ -3556,7 +3556,7 @@ } static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *tmp, *pnew; Py_ssize_t n; @@ -3565,7 +3565,7 @@ tmp = bytes_new(&PyBytes_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyBytes_CheckExact(tmp)); + assert(PyBytes_Check(tmp)); n = PyBytes_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); if (pnew != NULL) { diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1568,7 +1568,7 @@ tmp = float_new(&PyFloat_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyFloat_CheckExact(tmp)); + assert(PyFloat_Check(tmp)); newobj = type->tp_alloc(type, 0); if (newobj == NULL) { Py_DECREF(tmp); diff --git a/Objects/longobject.c b/Objects/longobject.c --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4675,7 +4675,7 @@ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyLong_CheckExact(tmp)); + assert(PyLong_Check(tmp)); n = Py_SIZE(tmp); if (n < 0) n = -n; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:56:56 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:56:56 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2324731=3A_Fixed_crash_on_converting_objects_with_speci?= =?utf-8?q?al_methods?= Message-ID: <20151125135647.59393.12184@psf.io> https://hg.python.org/cpython/rev/80efe5cc8934 changeset: 99344:80efe5cc8934 branch: 3.5 parent: 99339:88ad2b8480b1 parent: 99343:d8e0b54ece62 user: Serhiy Storchaka date: Wed Nov 25 15:52:04 2015 +0200 summary: Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. files: Lib/test/test_bytes.py | 11 +++++++++++ Lib/test/test_float.py | 15 +++++++++++++++ Lib/test/test_int.py | 7 +++++++ Lib/test/test_unicode.py | 11 +++++++---- Misc/NEWS | 4 ++++ Objects/bytesobject.c | 8 ++++---- Objects/floatobject.c | 2 +- Objects/longobject.c | 2 +- 8 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -779,6 +779,14 @@ def __index__(self): return 42 self.assertEqual(bytes(A()), b'a') + # Issue #24731 + class A: + def __bytes__(self): + return OtherBytesSubclass(b'abc') + self.assertEqual(bytes(A()), b'abc') + self.assertIs(type(bytes(A())), OtherBytesSubclass) + self.assertEqual(BytesSubclass(A()), b'abc') + self.assertIs(type(BytesSubclass(A())), BytesSubclass) # Test PyBytes_FromFormat() def test_from_format(self): @@ -1552,6 +1560,9 @@ class BytesSubclass(bytes): pass +class OtherBytesSubclass(bytes): + pass + class ByteArraySubclassTest(SubclassTest, unittest.TestCase): type2test = bytearray subclass2test = ByteArraySubclass diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -25,6 +25,12 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +class FloatSubclass(float): + pass + +class OtherFloatSubclass(float): + pass + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -167,6 +173,15 @@ return "" self.assertRaises(TypeError, time.sleep, Foo5()) + # Issue #24731 + class F: + def __float__(self): + return OtherFloatSubclass(42.) + self.assertAlmostEqual(float(F()), 42.) + self.assertIs(type(float(F())), OtherFloatSubclass) + self.assertAlmostEqual(FloatSubclass(F()), 42.) + self.assertIs(type(FloatSubclass(F())), FloatSubclass) + def test_is_integer(self): self.assertFalse((1.1).is_integer()) self.assertTrue((1.).is_integer()) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -24,6 +24,9 @@ ("\u0200", ValueError) ] +class IntSubclass(int): + pass + class IntTestCases(unittest.TestCase): def test_basic(self): @@ -441,6 +444,10 @@ good_int = TruncReturnsIntSubclass() n = int(good_int) self.assertEqual(n, 1) + self.assertIs(type(n), bool) + n = IntSubclass(good_int) + self.assertEqual(n, 1) + self.assertIs(type(n), IntSubclass) def test_error_message(self): def check(s, base=None): diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -43,6 +43,9 @@ """ return text.encode().decode() +class StrSubclass(str): + pass + class UnicodeTest(string_tests.CommonTest, string_tests.MixinStrUnicodeUserStringTest, string_tests.MixinStrUnicodeTest, @@ -1441,11 +1444,8 @@ 'unicode remains unicode' ) - class UnicodeSubclass(str): - pass - for text in ('ascii', '\xe9', '\u20ac', '\U0010FFFF'): - subclass = UnicodeSubclass(text) + subclass = StrSubclass(text) self.assertEqual(str(subclass), text) self.assertEqual(len(subclass), len(text)) if text == 'ascii': @@ -2199,6 +2199,9 @@ s = str(StrSubclassToStrSubclass("foo")) self.assertEqual(s, "foofoo") self.assertIs(type(s), StrSubclassToStrSubclass) + s = StrSubclass(StrSubclassToStrSubclass("foo")) + self.assertEqual(s, "foofoo") + self.assertIs(type(s), StrSubclass) def test_unicode_repr(self): class s1: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24731: Fixed crash on converting objects with special methods + __bytes__, __trunc__, and __float__ returning instances of subclasses of + bytes, int, and float to subclasses of bytes, int, and float correspondingly. + Library ------- diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3146,7 +3146,7 @@ }; static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); static PyObject * bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) @@ -3161,7 +3161,7 @@ _Py_IDENTIFIER(__bytes__); if (type != &PyBytes_Type) - return str_subtype_new(type, args, kwds); + return bytes_subtype_new(type, args, kwds); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x, &encoding, &errors)) return NULL; @@ -3388,7 +3388,7 @@ } static PyObject * -str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *tmp, *pnew; Py_ssize_t n; @@ -3397,7 +3397,7 @@ tmp = bytes_new(&PyBytes_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyBytes_CheckExact(tmp)); + assert(PyBytes_Check(tmp)); n = PyBytes_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); if (pnew != NULL) { diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1568,7 +1568,7 @@ tmp = float_new(&PyFloat_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyFloat_CheckExact(tmp)); + assert(PyFloat_Check(tmp)); newobj = type->tp_alloc(type, 0); if (newobj == NULL) { Py_DECREF(tmp); diff --git a/Objects/longobject.c b/Objects/longobject.c --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4611,7 +4611,7 @@ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyLong_CheckExact(tmp)); + assert(PyLong_Check(tmp)); n = Py_SIZE(tmp); if (n < 0) n = -n; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 08:56:56 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 13:56:56 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI0NzMx?= =?utf-8?q?=3A_Fixed_crash_on_converting_objects_with_special_methods?= Message-ID: <20151125135647.87859.51444@psf.io> https://hg.python.org/cpython/rev/37158c067b25 changeset: 99346:37158c067b25 branch: 2.7 parent: 99341:9a4db1ac5e10 user: Serhiy Storchaka date: Wed Nov 25 15:55:54 2015 +0200 summary: Issue #24731: Fixed crash on converting objects with special methods __str__, __trunc__, and __float__ returning instances of subclasses of str, long, and float to subclasses of str, long, and float correspondingly. files: Lib/test/test_float.py | 15 +++++++++++++++ Lib/test/test_int.py | 15 +++++++++++++++ Lib/test/test_long.py | 17 +++++++++++++++++ Lib/test/test_str.py | 6 ++++++ Lib/test/test_unicode.py | 9 ++++++--- Misc/NEWS | 4 ++++ Objects/floatobject.c | 2 +- Objects/longobject.c | 2 +- Objects/stringobject.c | 2 +- 9 files changed, 66 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -27,6 +27,12 @@ test_dir = os.path.dirname(__file__) or os.curdir format_testfile = os.path.join(test_dir, 'formatfloat_testcases.txt') +class FloatSubclass(float): + pass + +class OtherFloatSubclass(float): + pass + class GeneralFloatCases(unittest.TestCase): def test_float(self): @@ -200,6 +206,15 @@ return "" self.assertRaises(TypeError, time.sleep, Foo5()) + # Issue #24731 + class F: + def __float__(self): + return OtherFloatSubclass(42.) + self.assertAlmostEqual(float(F()), 42.) + self.assertIs(type(float(F())), OtherFloatSubclass) + self.assertAlmostEqual(FloatSubclass(F()), 42.) + self.assertIs(type(FloatSubclass(F())), FloatSubclass) + def test_is_integer(self): self.assertFalse((1.1).is_integer()) self.assertTrue((1.).is_integer()) diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -45,6 +45,9 @@ (unichr(0x200), ValueError), ] +class IntSubclass(int): + pass + class IntLongCommonTests(object): """Mixin of test cases to share between both test_int and test_long.""" @@ -477,6 +480,18 @@ self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) + class TruncReturnsIntSubclass(base): + def __trunc__(self): + return True + good_int = TruncReturnsIntSubclass() + n = int(good_int) + self.assertEqual(n, 1) + self.assertIs(type(n), bool) + n = IntSubclass(good_int) + self.assertEqual(n, 1) + self.assertIs(type(n), IntSubclass) + + def test_main(): run_unittest(IntTestCases) diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -79,6 +79,12 @@ (unichr(0x200), ValueError), ] +class LongSubclass(long): + pass + +class OtherLongSubclass(long): + pass + class LongTest(test_int.IntLongCommonTests, unittest.TestCase): ntype = long @@ -539,6 +545,17 @@ self.fail("Failed to raise TypeError with %s" % ((base, trunc_result_base),)) + class TruncReturnsLongSubclass(base): + def __long__(self): + return OtherLongSubclass(42L) + good_int = TruncReturnsLongSubclass() + n = long(good_int) + self.assertEqual(n, 42L) + self.assertIs(type(n), OtherLongSubclass) + n = LongSubclass(good_int) + self.assertEqual(n, 42L) + self.assertIs(type(n), LongSubclass) + def test_misc(self): # check the extremes in int<->long conversion diff --git a/Lib/test/test_str.py b/Lib/test/test_str.py --- a/Lib/test/test_str.py +++ b/Lib/test/test_str.py @@ -4,6 +4,9 @@ from test import test_support, string_tests +class StrSubclass(str): + pass + class StrTest( string_tests.CommonTest, string_tests.MixinStrUnicodeUserStringTest, @@ -107,6 +110,9 @@ self.assertEqual(str(Foo6("bar")), "foos") self.assertEqual(str(Foo7("bar")), "foos") self.assertEqual(str(Foo8("foo")), "foofoo") + self.assertIs(type(str(Foo8("foo"))), Foo8) + self.assertEqual(StrSubclass(Foo8("foo")), "foofoo") + self.assertIs(type(StrSubclass(Foo8("foo"))), StrSubclass) self.assertEqual(str(Foo9("foo")), "string") self.assertEqual(unicode(Foo9("foo")), u"not unicode") diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py --- a/Lib/test/test_unicode.py +++ b/Lib/test/test_unicode.py @@ -33,6 +33,9 @@ return None codecs.register(search_function) +class UnicodeSubclass(unicode): + pass + class UnicodeTest( string_tests.CommonTest, string_tests.MixinStrUnicodeUserStringTest, @@ -685,9 +688,6 @@ u'unicode remains unicode' ) - class UnicodeSubclass(unicode): - pass - self.assertEqual( unicode(UnicodeSubclass('unicode subclass becomes unicode')), u'unicode subclass becomes unicode' @@ -1269,6 +1269,9 @@ self.assertEqual(unicode(Foo6("bar")), u"foou") self.assertEqual(unicode(Foo7("bar")), u"foou") self.assertEqual(unicode(Foo8("foo")), u"foofoo") + self.assertIs(type(unicode(Foo8("foo"))), Foo8) + self.assertEqual(UnicodeSubclass(Foo8("foo")), u"foofoo") + self.assertIs(type(UnicodeSubclass(Foo8("foo"))), UnicodeSubclass) self.assertEqual(str(Foo9("foo")), "string") self.assertEqual(unicode(Foo9("foo")), u"not unicode") diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,10 @@ Core and Builtins ----------------- +- Issue #24731: Fixed crash on converting objects with special methods + __str__, __trunc__, and __float__ returning instances of subclasses of + str, long, and float to subclasses of str, long, and float correspondingly. + Library ------- diff --git a/Objects/floatobject.c b/Objects/floatobject.c --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1839,7 +1839,7 @@ tmp = float_new(&PyFloat_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyFloat_CheckExact(tmp)); + assert(PyFloat_Check(tmp)); newobj = type->tp_alloc(type, 0); if (newobj == NULL) { Py_DECREF(tmp); diff --git a/Objects/longobject.c b/Objects/longobject.c --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -4068,7 +4068,7 @@ tmp = (PyLongObject *)long_new(&PyLong_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyLong_CheckExact(tmp)); + assert(PyLong_Check(tmp)); n = Py_SIZE(tmp); if (n < 0) n = -n; diff --git a/Objects/stringobject.c b/Objects/stringobject.c --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -3719,7 +3719,7 @@ tmp = string_new(&PyString_Type, args, kwds); if (tmp == NULL) return NULL; - assert(PyString_CheckExact(tmp)); + assert(PyString_Check(tmp)); n = PyString_GET_SIZE(tmp); pnew = type->tp_alloc(type, n); if (pnew != NULL) { -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 09:14:21 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 14:14:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325697=3A_Fixed_rough_alphabetical_order_in_Misc/ACKS?= =?utf-8?q?=2E?= Message-ID: <20151125141421.31407.36505@psf.io> https://hg.python.org/cpython/rev/9925fb41c1d9 changeset: 99348:9925fb41c1d9 branch: 3.5 parent: 99344:80efe5cc8934 parent: 99347:68c7c6ac82d9 user: Serhiy Storchaka date: Wed Nov 25 16:12:30 2015 +0200 summary: Issue #25697: Fixed rough alphabetical order in Misc/ACKS. files: Misc/ACKS | 45 +++++++++++++++++++++--------------------- 1 files changed, 22 insertions(+), 23 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -50,8 +50,8 @@ Juancarlo A?ez Chris Angelico J?r?my Anger +Jon Anglin Ankur Ankan -Jon Anglin Heidi Annexstad Ramchandra Apte ?ric Araujo @@ -172,8 +172,8 @@ Georg Brandl Christopher Brannon Terrence Brannon +Sven Brauch Germ?n M. Bravo -Sven Brauch Erik Bray Brian Brazil Demian Brecht @@ -210,6 +210,7 @@ Lee Busby Katherine Busch Ralph Butler +Laurent De Buyst Zach Byrne Nicolas Cadou Jp Calderone @@ -289,8 +290,8 @@ Jason R. Coombs Garrett Cooper Greg Copeland +Ian Cordasco Aldo Cortesi -Ian Cordasco David Costanzo Scott Cotton Greg Couch @@ -372,8 +373,8 @@ Bruno Dupuis Andy Dustman Gary Duzan +Eugene Dvurechenski Karmen Dykstra -Eugene Dvurechenski Josip Dzolonga Maxim Dzumanenko Walter D?rwald @@ -676,8 +677,8 @@ Philip H. Jensen Philip Jenvey MunSic Jeong +Chris Jerdonek Joe Jevnik -Chris Jerdonek Jim Jewett Pedro Diaz Jimenez Orjan Johansen @@ -764,9 +765,9 @@ Vajrasky Kok Guido Kollerie Jacek Konieczny -???? ????????? Arkady Koplyarov Peter A. Koren +???? ????????? Vlad Korolev Joseph Koshy Daniel Kozan @@ -867,6 +868,7 @@ Nick Lockwood Stephanie Lockwood Hugo Lopes Tavares +Guillermo L?pez-Anglada Anne Lord Tom Loredo Justin Love @@ -874,6 +876,7 @@ Peter Lovett Chalmer Lowe Jason Lowe +Martin von L?wis Tony Lownds Ray Loyzaga Kang-Hao (Kenny) Lu @@ -885,8 +888,6 @@ Taras Lyapun Jim Lynch Mikael Lyngvig -Martin von L?wis -Guillermo L?pez-Anglada Jeff MacDonald John Machin Andrew I MacIntyre @@ -911,9 +912,9 @@ Alex Martelli Anthony Martin Owen Martin +Sidney San Mart?n Westley Mart?nez S?bastien Martini -Sidney San Mart?n Roger Masse Nick Mathewson Simon Mathieu @@ -950,16 +951,16 @@ Ezio Melotti Doug Mennella Brian Merrell +Alexis M?taireau Luke Mewburn Carl Meyer Mike Meyer Piotr Meyer -Alexis M?taireau Steven Miale -Trent Mick Jason Michalski Franck Michea Vincent Michel +Trent Mick Tom Middleton Thomas Miedema Stan Mihai @@ -1060,7 +1061,7 @@ Denis S. Otkidach Peter Otten Michael Otteneder -R. M. Oudkerk +Richard Oudkerk Russel Owen Joonas Paalasmaa Martin Packman @@ -1069,6 +1070,7 @@ Mike Pall Todd R. Palmer Juan David Ib??ez Palomar +Nicola Palumbo Jan Palus Yongzhi Pan Martin Panter @@ -1120,8 +1122,8 @@ Fran?ois Pinard Tom Pinckney Zach Pincus +Michael Piotrowski Zero Piraeus -Michael Piotrowski Antoine Pitrou Jean-Fran?ois Pi?ronne Oleg Plakhotnyuk @@ -1149,9 +1151,9 @@ Steve Purcell Eduardo P?rez Fernando P?rez +Kevin Jing Qiu Pierre Quentel Brian Quinlan -Kevin Jing Qiu Anders Qvist Thomas Rachel Ram Rachum @@ -1187,9 +1189,9 @@ Fl?vio Ribeiro Francesco Ricciardi Tim Rice +Martin Richard Jan Pieter Riegel Armin Rigo -Martin Richard Arc Riley Nicholas Riley Jean-Claude Rimbault @@ -1221,6 +1223,7 @@ Josh Rosenberg Jim Roskind Brian Rosner +Ignacio Rossi Guido van Rossum Just van Rossum Hugo van Rossum @@ -1266,7 +1269,6 @@ Bob Savage Dave Sawyer Ben Sayer -sbt Luca Sbardella Marco Scataglini Andrew Schaaf @@ -1307,8 +1309,8 @@ Ian Seyer Dmitry Shachnev Daniel Shahaf +Mark Shannon Ha Shao -Mark Shannon Richard Shapiro Varun Sharma Vlad Shcherbina @@ -1507,9 +1509,10 @@ Michael Vogt Radu Voicilas Alex Volkov +Guido Vranken Martijn Vries Sjoerd de Vries -Guido Vranken +Jonas Wagner Daniel Wagner-Hall Niki W. Waibel Wojtek Walczak @@ -1523,7 +1526,6 @@ Greg Ward Tom Wardill Zachary Ware -Jonas Wagner Barry Warsaw Steve Waterbury Bob Watson @@ -1592,8 +1594,8 @@ Xiang Zhang Robert Xiao Florent Xicluna +Arnon Yaari Hirokazu Yamamoto -Arnon Yaari Ka-Ping Yee Jason Yeo EungJun Yi @@ -1620,7 +1622,4 @@ Gennadiy Zlobin Doug Zongker Peter ?strand -Ignacio Rossi -Laurent De Buyst -Nicola Palumbo evilzero -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 09:14:21 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 14:14:21 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325697=3A_Fixed_rough_alphabetical_order_in_Misc?= =?utf-8?q?/ACKS=2E?= Message-ID: <20151125141421.22404.63334@psf.io> https://hg.python.org/cpython/rev/e61a864b703c changeset: 99349:e61a864b703c parent: 99345:1c4d256cc370 parent: 99348:9925fb41c1d9 user: Serhiy Storchaka date: Wed Nov 25 16:13:29 2015 +0200 summary: Issue #25697: Fixed rough alphabetical order in Misc/ACKS. files: Misc/ACKS | 47 +++++++++++++++++++++--------------------- 1 files changed, 23 insertions(+), 24 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -50,8 +50,8 @@ Juancarlo A?ez Chris Angelico J?r?my Anger +Jon Anglin Ankur Ankan -Jon Anglin Heidi Annexstad Ramchandra Apte ?ric Araujo @@ -173,8 +173,8 @@ Georg Brandl Christopher Brannon Terrence Brannon +Sven Brauch Germ?n M. Bravo -Sven Brauch Erik Bray Brian Brazil Demian Brecht @@ -211,6 +211,7 @@ Lee Busby Katherine Busch Ralph Butler +Laurent De Buyst Zach Byrne Nicolas Cadou Jp Calderone @@ -290,8 +291,8 @@ Jason R. Coombs Garrett Cooper Greg Copeland +Ian Cordasco Aldo Cortesi -Ian Cordasco David Costanzo Scott Cotton Greg Couch @@ -350,6 +351,7 @@ Yves Dionne Daniel Dittmar Josip Djolonga +Walter D?rwald Jaromir Dolecek Ismail Donmez Robert Donohue @@ -373,11 +375,10 @@ Bruno Dupuis Andy Dustman Gary Duzan +Eugene Dvurechenski Karmen Dykstra -Eugene Dvurechenski Josip Dzolonga Maxim Dzumanenko -Walter D?rwald Hans Eckardt Rodolpho Eckhardt Ulrich Eckhardt @@ -677,8 +678,8 @@ Philip H. Jensen Philip Jenvey MunSic Jeong +Chris Jerdonek Joe Jevnik -Chris Jerdonek Jim Jewett Pedro Diaz Jimenez Orjan Johansen @@ -766,9 +767,9 @@ Guido Kollerie Jacek Ko?odziej Jacek Konieczny -???? ????????? Arkady Koplyarov Peter A. Koren +???? ????????? Vlad Korolev Joseph Koshy Daniel Kozan @@ -868,7 +869,9 @@ Mirko Liss Nick Lockwood Stephanie Lockwood +Martin von L?wis Hugo Lopes Tavares +Guillermo L?pez-Anglada Anne Lord Tom Loredo Justin Love @@ -888,8 +891,6 @@ Taras Lyapun Jim Lynch Mikael Lyngvig -Martin von L?wis -Guillermo L?pez-Anglada Jeff MacDonald John Machin Andrew I MacIntyre @@ -914,9 +915,9 @@ Alex Martelli Anthony Martin Owen Martin +Sidney San Mart?n Westley Mart?nez S?bastien Martini -Sidney San Mart?n Roger Masse Nick Mathewson Simon Mathieu @@ -953,16 +954,16 @@ Ezio Melotti Doug Mennella Brian Merrell +Alexis M?taireau Luke Mewburn Carl Meyer Mike Meyer Piotr Meyer -Alexis M?taireau Steven Miale -Trent Mick Jason Michalski Franck Michea Vincent Michel +Trent Mick Tom Middleton Thomas Miedema Stan Mihai @@ -1063,7 +1064,7 @@ Denis S. Otkidach Peter Otten Michael Otteneder -R. M. Oudkerk +Richard Oudkerk Russel Owen Joonas Paalasmaa Martin Packman @@ -1072,6 +1073,7 @@ Mike Pall Todd R. Palmer Juan David Ib??ez Palomar +Nicola Palumbo Jan Palus Yongzhi Pan Martin Panter @@ -1123,8 +1125,8 @@ Fran?ois Pinard Tom Pinckney Zach Pincus +Michael Piotrowski Zero Piraeus -Michael Piotrowski Antoine Pitrou Jean-Fran?ois Pi?ronne Oleg Plakhotnyuk @@ -1152,9 +1154,9 @@ Steve Purcell Eduardo P?rez Fernando P?rez +Kevin Jing Qiu Pierre Quentel Brian Quinlan -Kevin Jing Qiu Anders Qvist Thomas Rachel Ram Rachum @@ -1190,9 +1192,9 @@ Fl?vio Ribeiro Francesco Ricciardi Tim Rice +Martin Richard Jan Pieter Riegel Armin Rigo -Martin Richard Arc Riley Nicholas Riley Jean-Claude Rimbault @@ -1224,6 +1226,7 @@ Josh Rosenberg Jim Roskind Brian Rosner +Ignacio Rossi Guido van Rossum Just van Rossum Hugo van Rossum @@ -1269,7 +1272,6 @@ Bob Savage Dave Sawyer Ben Sayer -sbt Luca Sbardella Marco Scataglini Andrew Schaaf @@ -1310,8 +1312,8 @@ Ian Seyer Dmitry Shachnev Daniel Shahaf +Mark Shannon Ha Shao -Mark Shannon Richard Shapiro Varun Sharma Vlad Shcherbina @@ -1511,9 +1513,10 @@ Michael Vogt Radu Voicilas Alex Volkov +Guido Vranken Martijn Vries Sjoerd de Vries -Guido Vranken +Jonas Wagner Daniel Wagner-Hall Niki W. Waibel Wojtek Walczak @@ -1527,7 +1530,6 @@ Greg Ward Tom Wardill Zachary Ware -Jonas Wagner Barry Warsaw Steve Waterbury Bob Watson @@ -1596,8 +1598,8 @@ Xiang Zhang Robert Xiao Florent Xicluna +Arnon Yaari Hirokazu Yamamoto -Arnon Yaari Ka-Ping Yee Jason Yeo EungJun Yi @@ -1624,7 +1626,4 @@ Gennadiy Zlobin Doug Zongker Peter ?strand -Ignacio Rossi -Laurent De Buyst -Nicola Palumbo evilzero -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 09:14:21 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 14:14:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1Njk3?= =?utf-8?q?=3A_Fixed_rough_alphabetical_order_in_Misc/ACKS=2E?= Message-ID: <20151125141421.22378.64606@psf.io> https://hg.python.org/cpython/rev/68c7c6ac82d9 changeset: 99347:68c7c6ac82d9 branch: 3.4 parent: 99343:d8e0b54ece62 user: Serhiy Storchaka date: Wed Nov 25 16:11:29 2015 +0200 summary: Issue #25697: Fixed rough alphabetical order in Misc/ACKS. files: Misc/ACKS | 41 ++++++++++++++++++++--------------------- 1 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -49,8 +49,8 @@ Juancarlo A?ez Chris Angelico J?r?my Anger +Jon Anglin Ankur Ankan -Jon Anglin Heidi Annexstad Ramchandra Apte ?ric Araujo @@ -167,8 +167,8 @@ Georg Brandl Christopher Brannon Terrence Brannon +Sven Brauch Germ?n M. Bravo -Sven Brauch Erik Bray Brian Brazil Demian Brecht @@ -205,6 +205,7 @@ Lee Busby Katherine Busch Ralph Butler +Laurent De Buyst Zach Byrne Nicolas Cadou Jp Calderone @@ -282,8 +283,8 @@ Jason R. Coombs Garrett Cooper Greg Copeland +Ian Cordasco Aldo Cortesi -Ian Cordasco David Costanzo Scott Cotton Greg Couch @@ -342,6 +343,7 @@ Yves Dionne Daniel Dittmar Josip Djolonga +Walter D?rwald Jaromir Dolecek Ismail Donmez Robert Donohue @@ -365,11 +367,10 @@ Bruno Dupuis Andy Dustman Gary Duzan +Eugene Dvurechenski Karmen Dykstra -Eugene Dvurechenski Josip Dzolonga Maxim Dzumanenko -Walter D?rwald Hans Eckardt Rodolpho Eckhardt Ulrich Eckhardt @@ -742,9 +743,9 @@ Vajrasky Kok Guido Kollerie Jacek Konieczny -???? ????????? Arkady Koplyarov Peter A. Koren +???? ????????? Vlad Korolev Joseph Koshy Daniel Kozan @@ -841,7 +842,9 @@ Mirko Liss Nick Lockwood Stephanie Lockwood +Martin von L?wis Hugo Lopes Tavares +Guillermo L?pez-Anglada Anne Lord Tom Loredo Justin Love @@ -859,8 +862,6 @@ Taras Lyapun Jim Lynch Mikael Lyngvig -Martin von L?wis -Guillermo L?pez-Anglada Jeff MacDonald John Machin Andrew I MacIntyre @@ -885,9 +886,9 @@ Alex Martelli Anthony Martin Owen Martin +Sidney San Mart?n Westley Mart?nez S?bastien Martini -Sidney San Mart?n Roger Masse Nick Mathewson Simon Mathieu @@ -922,16 +923,16 @@ Ezio Melotti Doug Mennella Brian Merrell +Alexis M?taireau Luke Mewburn Carl Meyer Mike Meyer Piotr Meyer -Alexis M?taireau Steven Miale -Trent Mick Jason Michalski Franck Michea Vincent Michel +Trent Mick Tom Middleton Thomas Miedema Stan Mihai @@ -1031,7 +1032,7 @@ Denis S. Otkidach Peter Otten Michael Otteneder -R. M. Oudkerk +Richard Oudkerk Russel Owen Joonas Paalasmaa Martin Packman @@ -1040,6 +1041,7 @@ Mike Pall Todd R. Palmer Juan David Ib??ez Palomar +Nicola Palumbo Jan Palus Yongzhi Pan Martin Panter @@ -1089,8 +1091,8 @@ Fran?ois Pinard Tom Pinckney Zach Pincus +Michael Piotrowski Zero Piraeus -Michael Piotrowski Antoine Pitrou Jean-Fran?ois Pi?ronne Oleg Plakhotnyuk @@ -1118,9 +1120,9 @@ Steve Purcell Eduardo P?rez Fernando P?rez +Kevin Jing Qiu Pierre Quentel Brian Quinlan -Kevin Jing Qiu Anders Qvist Thomas Rachel Ram Rachum @@ -1154,9 +1156,9 @@ Fl?vio Ribeiro Francesco Ricciardi Tim Rice +Martin Richard Jan Pieter Riegel Armin Rigo -Martin Richard Arc Riley Nicholas Riley Jean-Claude Rimbault @@ -1229,7 +1231,6 @@ Bob Savage Dave Sawyer Ben Sayer -sbt Luca Sbardella Marco Scataglini Andrew Schaaf @@ -1270,8 +1271,8 @@ Ian Seyer Dmitry Shachnev Daniel Shahaf +Mark Shannon Ha Shao -Mark Shannon Richard Shapiro Varun Sharma Vlad Shcherbina @@ -1461,9 +1462,10 @@ Frank Visser Johannes Vogel Alex Volkov +Guido Vranken Martijn Vries Sjoerd de Vries -Guido Vranken +Jonas Wagner Niki W. Waibel Wojtek Walczak Charles Waldman @@ -1476,7 +1478,6 @@ Greg Ward Tom Wardill Zachary Ware -Jonas Wagner Barry Warsaw Steve Waterbury Bob Watson @@ -1569,6 +1570,4 @@ Gennadiy Zlobin Doug Zongker Peter ?strand -Laurent De Buyst -Nicola Palumbo evilzero -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 09:14:21 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 14:14:21 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1Njk3?= =?utf-8?q?=3A_Fixed_rough_alphabetical_order_in_Misc/ACKS=2E?= Message-ID: <20151125141421.22388.19848@psf.io> https://hg.python.org/cpython/rev/8bdf8e7dd085 changeset: 99350:8bdf8e7dd085 branch: 2.7 parent: 99346:37158c067b25 user: Serhiy Storchaka date: Wed Nov 25 16:13:56 2015 +0200 summary: Issue #25697: Fixed rough alphabetical order in Misc/ACKS. files: Misc/ACKS | 29 ++++++++++++++--------------- 1 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -45,8 +45,8 @@ Juancarlo A?ez Chris Angelico J?r?my Anger +Jon Anglin Ankur Ankan -Jon Anglin Heidi Annexstad Ramchandra Apte ?ric Araujo @@ -163,8 +163,8 @@ Georg Brandl Christopher Brannon Terrence Brannon +Sven Brauch Germ?n M. Bravo -Sven Brauch Erik Bray Brian Brazil Demian Brecht @@ -336,6 +336,7 @@ Yves Dionne Daniel Dittmar Josip Djolonga +Walter D?rwald Jaromir Dolecek Ismail Donmez Robert Donohue @@ -362,7 +363,6 @@ Eugene Dvurechenski Josip Dzolonga Maxim Dzumanenko -Walter D?rwald Hans Eckardt Rodolpho Eckhardt Ulrich Eckhardt @@ -732,9 +732,9 @@ Vajrasky Kok Guido Kollerie Jacek Konieczny -???? ????????? Arkady Koplyarov Peter A. Koren +???? ????????? Vlad Korolev Joseph Koshy Daniel Kozan @@ -826,7 +826,9 @@ Mirko Liss Nick Lockwood Stephanie Lockwood +Martin von L?wis Hugo Lopes Tavares +Guillermo L?pez-Anglada Anne Lord Tom Loredo Justin Love @@ -843,8 +845,6 @@ Taras Lyapun Jim Lynch Mikael Lyngvig -Martin von L?wis -Guillermo L?pez-Anglada Jeff MacDonald John Machin Andrew I MacIntyre @@ -869,9 +869,9 @@ Alex Martelli Anthony Martin Owen Martin +Sidney San Mart?n Westley Mart?nez S?bastien Martini -Sidney San Mart?n Roger Masse Nick Mathewson Simon Mathieu @@ -906,15 +906,15 @@ Ezio Melotti Doug Mennella Brian Merrell +Alexis M?taireau Luke Mewburn Carl Meyer Mike Meyer Piotr Meyer -Alexis M?taireau Steven Miale -Trent Mick Jason Michalski Franck Michea +Trent Mick Tom Middleton Thomas Miedema Stan Mihai @@ -1013,7 +1013,7 @@ Denis S. Otkidach Peter Otten Michael Otteneder -R. M. Oudkerk +Richard Oudkerk Russel Owen Joonas Paalasmaa Martin Packman @@ -1071,8 +1071,8 @@ Fran?ois Pinard Tom Pinckney Zach Pincus +Michael Piotrowski Zero Piraeus -Michael Piotrowski Antoine Pitrou Jean-Fran?ois Pi?ronne Oleg Plakhotnyuk @@ -1100,9 +1100,9 @@ Steve Purcell Eduardo P?rez Fernando P?rez +Kevin Jing Qiu Pierre Quentel Brian Quinlan -Kevin Jing Qiu Anders Qvist Thomas Rachel Ram Rachum @@ -1209,7 +1209,6 @@ Hugh Sasse Bob Savage Ben Sayer -sbt Luca Sbardella Marco Scataglini Andrew Schaaf @@ -1248,8 +1247,8 @@ Denis Severson Ian Seyer Daniel Shahaf +Mark Shannon Ha Shao -Mark Shannon Richard Shapiro Varun Sharma Vlad Shcherbina @@ -1436,6 +1435,7 @@ Guido Vranken Martijn Vries Sjoerd de Vries +Jonas Wagner Niki W. Waibel Wojtek Walczak Charles Waldman @@ -1448,7 +1448,6 @@ Greg Ward Tom Wardill Zachary Ware -Jonas Wagner Barry Warsaw Steve Waterbury Bob Watson -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 09:20:34 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 14:20:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NzAz?= =?utf-8?q?=3A_Skip_test=5F43581_if_one_of_stdout_or_stderr_is_redirected?= =?utf-8?q?=2E?= Message-ID: <20151125142023.69552.57097@psf.io> https://hg.python.org/cpython/rev/eb9d2e5bc8dc changeset: 99351:eb9d2e5bc8dc branch: 2.7 user: Serhiy Storchaka date: Wed Nov 25 16:20:04 2015 +0200 summary: Issue #25703: Skip test_43581 if one of stdout or stderr is redirected. files: Lib/test/test_sys.py | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -412,7 +412,10 @@ def test_43581(self): # Can't use sys.stdout, as this is a cStringIO object when # the test runs under regrtest. - self.assertTrue(sys.__stdout__.encoding == sys.__stderr__.encoding) + if not (os.environ.get('PYTHONIOENCODING') or + (sys.__stdout__.isatty() and sys.__stderr__.isatty())): + self.skipTest('stdout/stderr encoding is not set') + self.assertEqual(sys.__stdout__.encoding, sys.__stderr__.encoding) def test_sys_flags(self): self.assertTrue(sys.flags) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 10:19:54 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 15:19:54 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjE2?= =?utf-8?q?=3A_Tests_for_OrderedDict_are_extracted_from_test=5Fcollections?= Message-ID: <20151125151954.22390.12874@psf.io> https://hg.python.org/cpython/rev/8d9a0540adf9 changeset: 99352:8d9a0540adf9 branch: 3.4 parent: 99347:68c7c6ac82d9 user: Serhiy Storchaka date: Wed Nov 25 17:09:01 2015 +0200 summary: Issue #25616: Tests for OrderedDict are extracted from test_collections into separate file test_ordered_dict. files: Lib/test/test_collections.py | 322 +---- Lib/test/test_ordered_dict.py | 1310 +-------------------- Misc/NEWS | 3 + 3 files changed, 27 insertions(+), 1608 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,16 +1,19 @@ """Unit tests for collections.py.""" -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink -import inspect +import collections +import copy +import doctest +import keyword +import operator +import pickle +from random import choice, randrange +import re +import string +import sys from test import support +import unittest + from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys from collections import UserDict from collections import ChainMap from collections.abc import Hashable, Iterable, Iterator @@ -281,8 +284,7 @@ # n = 5000 n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) + names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) Big = namedtuple('Big', names) @@ -1281,309 +1283,13 @@ ################################################################################ -### OrderedDict -################################################################################ - -class TestOrderedDict(unittest.TestCase): - - def test_init(self): - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input - self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input - self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input - self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], - c=3, e=5).items()), pairs) # mixed input - - # make sure no positional args conflict with possible kwdargs - self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) - self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) - self.assertRaises(TypeError, OrderedDict, 42) - self.assertRaises(TypeError, OrderedDict, (), ()) - self.assertRaises(TypeError, OrderedDict.__init__) - - # Make sure that direct calls to __init__ do not clear previous contents - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.__init__([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - def test_update(self): - with self.assertRaises(TypeError): - OrderedDict().update([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict() - od.update(dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # dict input - od = OrderedDict() - od.update(**dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # kwds input - od = OrderedDict() - od.update(pairs) - self.assertEqual(list(od.items()), pairs) # pairs input - od = OrderedDict() - od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) - self.assertEqual(list(od.items()), pairs) # mixed input - - # Issue 9137: Named argument called 'other' or 'self' - # shouldn't be treated specially. - od = OrderedDict() - od.update(self=23) - self.assertEqual(list(od.items()), [('self', 23)]) - od = OrderedDict() - od.update(other={}) - self.assertEqual(list(od.items()), [('other', {})]) - od = OrderedDict() - od.update(red=5, blue=6, other=7, self=8) - self.assertEqual(sorted(list(od.items())), - [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) - - # Make sure that direct calls to update do not clear previous contents - # add that updates items are not moved to the end - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.update([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - def test_abc(self): - self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) - - def test_clear(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(len(od), len(pairs)) - od.clear() - self.assertEqual(len(od), 0) - - def test_delitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - del od['a'] - self.assertNotIn('a', od) - with self.assertRaises(KeyError): - del od['a'] - self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) - - def test_setitem(self): - od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) - od['c'] = 10 # existing element - od['f'] = 20 # new element - self.assertEqual(list(od.items()), - [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) - - def test_iterators(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(list(od), [t[0] for t in pairs]) - self.assertEqual(list(od.keys()), [t[0] for t in pairs]) - self.assertEqual(list(od.values()), [t[1] for t in pairs]) - self.assertEqual(list(od.items()), pairs) - self.assertEqual(list(reversed(od)), - [t[0] for t in reversed(pairs)]) - - def test_popitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - while pairs: - self.assertEqual(od.popitem(), pairs.pop()) - with self.assertRaises(KeyError): - od.popitem() - self.assertEqual(len(od), 0) - - def test_pop(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - shuffle(pairs) - while pairs: - k, v = pairs.pop() - self.assertEqual(od.pop(k), v) - with self.assertRaises(KeyError): - od.pop('xyz') - self.assertEqual(len(od), 0) - self.assertEqual(od.pop(k, 12345), 12345) - - # make sure pop still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - m = Missing(a=1) - self.assertEqual(m.pop('b', 5), 5) - self.assertEqual(m.pop('a', 6), 1) - self.assertEqual(m.pop('a', 6), 6) - with self.assertRaises(KeyError): - m.pop('a') - - def test_equality(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od1 = OrderedDict(pairs) - od2 = OrderedDict(pairs) - self.assertEqual(od1, od2) # same order implies equality - pairs = pairs[2:] + pairs[:2] - od2 = OrderedDict(pairs) - self.assertNotEqual(od1, od2) # different order implies inequality - # comparison to regular dict is not order sensitive - self.assertEqual(od1, dict(od2)) - self.assertEqual(dict(od2), od1) - # different length implied inequality - self.assertNotEqual(od1, OrderedDict(pairs[:-1])) - - def test_copying(self): - # Check that ordered dicts are copyable, deepcopyable, picklable, - # and have a repr/eval round-trip - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - def check(dup): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) - check(od.copy()) - check(copy.copy(od)) - check(copy.deepcopy(od)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(od, proto))) - check(eval(repr(od))) - update_test = OrderedDict() - update_test.update(od) - check(update_test) - check(OrderedDict(od)) - - def test_yaml_linkage(self): - # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. - # In yaml, lists are native but tuples are not. - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - # yaml.dump(od) --> - # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) - - def test_reduce_not_too_fat(self): - # do not save instance dictionary if not needed - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - self.assertIsNone(od.__reduce__()[2]) - od.x = 10 - self.assertIsNotNone(od.__reduce__()[2]) - - def test_pickle_recursive(self): - od = OrderedDict() - od[1] = od - for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1): - dup = pickle.loads(pickle.dumps(od, proto)) - self.assertIsNot(dup, od) - self.assertEqual(list(dup.keys()), [1]) - self.assertIs(dup[1], dup) - - def test_repr(self): - od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") - self.assertEqual(eval(repr(od)), od) - self.assertEqual(repr(OrderedDict()), "OrderedDict()") - - def test_repr_recursive(self): - # See issue #9826 - od = OrderedDict.fromkeys('abc') - od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") - - def test_setdefault(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - pair_order = list(od.items()) - self.assertEqual(od.setdefault('a', 10), 3) - # make sure order didn't change - self.assertEqual(list(od.items()), pair_order) - self.assertEqual(od.setdefault('x', 10), 10) - # make sure 'x' is added to the end - self.assertEqual(list(od.items())[-1], ('x', 10)) - - # make sure setdefault still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - self.assertEqual(Missing().setdefault(5, 9), 9) - - def test_reinsert(self): - # Given insert a, insert b, delete a, re-insert a, - # verify that a is now later than b. - od = OrderedDict() - od['a'] = 1 - od['b'] = 2 - del od['a'] - od['a'] = 1 - self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) - - def test_move_to_end(self): - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - od.move_to_end('c') - self.assertEqual(list(od), list('abdec')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('e') - self.assertEqual(list(od), list('cabde')) - with self.assertRaises(KeyError): - od.move_to_end('x') - - def test_sizeof(self): - # Wimpy test: Just verify the reported size is larger than a regular dict - d = dict(a=1) - od = OrderedDict(**d) - self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) - - def test_override_update(self): - # Verify that subclasses can override update() without breaking __init__() - class MyOD(OrderedDict): - def update(self, *args, **kwds): - raise Exception() - items = [('a', 1), ('c', 3), ('b', 2)] - self.assertEqual(list(MyOD(items).items()), items) - -class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - -class MyOrderedDict(OrderedDict): - pass - -class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - -################################################################################ ### Run tests ################################################################################ -import doctest, collections - def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, TestChainMap, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + TestCollectionABCs, TestCounter, TestChainMap] support.run_unittest(*test_classes) support.run_doctest(collections, verbose) diff --git a/Lib/test/test_collections.py b/Lib/test/test_ordered_dict.py copy from Lib/test/test_collections.py copy to Lib/test/test_ordered_dict.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_ordered_dict.py @@ -1,1288 +1,13 @@ -"""Unit tests for collections.py.""" +import contextlib +import copy +import pickle +from random import shuffle +import sys +import unittest +from collections import OrderedDict +from collections.abc import MutableMapping +from test import mapping_tests, support -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink -import inspect -from test import support -from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -from collections import UserDict -from collections import ChainMap -from collections.abc import Hashable, Iterable, Iterator -from collections.abc import Sized, Container, Callable -from collections.abc import Set, MutableSet -from collections.abc import Mapping, MutableMapping, KeysView, ItemsView -from collections.abc import Sequence, MutableSequence -from collections.abc import ByteString - - -################################################################################ -### ChainMap (helper class for configparser and the string module) -################################################################################ - -class TestChainMap(unittest.TestCase): - - def test_basics(self): - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - d = c.new_child() - d['b'] = 20 - d['c'] = 30 - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - del d['b'] # unmask a value - self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - self.assertIn(repr(d), [ # check repr - type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", - type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" - ]) - - for e in d.copy(), copy.copy(d): # check shallow copies - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - self.assertIsNot(d.maps[0], e.maps[0]) - for m1, m2 in zip(d.maps[1:], e.maps[1:]): - self.assertIs(m1, m2) - - # check deep copies - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - e = pickle.loads(pickle.dumps(d, proto)) - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - for e in [copy.deepcopy(d), - eval(repr(d)) - ]: - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - - f = d.new_child() - f['b'] = 5 - self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) - self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents - self.assertEqual(f['b'], 5) # find first in chain - self.assertEqual(f.parents['b'], 2) # look beyond maps[0] - - def test_contructor(self): - self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict - self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list - - def test_bool(self): - self.assertFalse(ChainMap()) - self.assertFalse(ChainMap({}, {})) - self.assertTrue(ChainMap({1:2}, {})) - self.assertTrue(ChainMap({}, {1:2})) - - def test_missing(self): - class DefaultChainMap(ChainMap): - def __missing__(self, key): - return 999 - d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) - for k, v in dict(a=1, b=2, c=30, d=999).items(): - self.assertEqual(d[k], v) # check __getitem__ w/missing - for k, v in dict(a=1, b=2, c=30, d=77).items(): - self.assertEqual(d.get(k, 77), v) # check get() w/ missing - for k, v in dict(a=True, b=True, c=True, d=False).items(): - self.assertEqual(k in d, v) # check __contains__ w/missing - self.assertEqual(d.pop('a', 1001), 1, d) - self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing - self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing - with self.assertRaises(KeyError): - d.popitem() - - def test_dict_coercion(self): - d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) - self.assertEqual(dict(d), dict(a=1, b=2, c=30)) - self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) - - def test_new_child(self): - 'Tests for changes for issue #16613.' - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = {'b':20, 'c': 30} - d = c.new_child(m) - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertIs(m, d.maps[0]) - - # Use a different map than a dict - class lowerdict(dict): - def __getitem__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__getitem__(self, key) - def __contains__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__contains__(self, key) - - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = lowerdict(b=20, c=30) - d = c.new_child(m) - self.assertIs(m, d.maps[0]) - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - -################################################################################ -### Named Tuples -################################################################################ - -TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests - -class TestNamedTuple(unittest.TestCase): - - def test_factory(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__name__, 'Point') - self.assertEqual(Point.__slots__, ()) - self.assertEqual(Point.__module__, __name__) - self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertEqual(Point._fields, ('x', 'y')) - self.assertIn('class Point(tuple)', Point._source) - - self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char - self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword - self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit - - self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char - self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword - self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit - self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore - self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field - - namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names - namedtuple('_', 'a b c') # Test leading underscores in a typename - - nt = namedtuple('nt', 'the quick brown fox') # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - nt = namedtuple('nt', ('the', 'quick')) # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - - self.assertRaises(TypeError, Point._make, [11]) # catch too few args - self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_factory_doc_attr(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__doc__, 'Point(x, y)') - - def test_name_fixer(self): - for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char - [('abc', 'class'), ('abc', '_1')], # field has keyword - [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit - [('abc', '_efg'), ('abc', '_1')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space - ]: - self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) - - def test_instance(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertEqual(p, Point(x=11, y=22)) - self.assertEqual(p, Point(11, y=22)) - self.assertEqual(p, Point(y=22, x=11)) - self.assertEqual(p, Point(*(11, 22))) - self.assertEqual(p, Point(**dict(x=11, y=22))) - self.assertRaises(TypeError, Point, 1) # too few args - self.assertRaises(TypeError, Point, 1, 2, 3) # too many args - self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument - self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument - self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__weakref__', dir(p)) - self.assertEqual(p, Point._make([11, 22])) # test _make classmethod - self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute - self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method - self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - - try: - p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') - - # verify that field string can have commas - Point = namedtuple('Point', 'x, y') - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - # verify that fieldspec can be a non-string sequence - Point = namedtuple('Point', ('x', 'y')) - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - def test_tupleness(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - - self.assertIsInstance(p, tuple) - self.assertEqual(p, (11, 22)) # matches a real tuple - self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple - self.assertEqual(list(p), [11, 22]) # coercable to a list - self.assertEqual(max(p), 22) # iterable - self.assertEqual(max(*p), 22) # star-able - x, y = p - self.assertEqual(p, (x, y)) # unpacks like a tuple - self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple - self.assertRaises(IndexError, p.__getitem__, 3) - - self.assertEqual(p.x, x) - self.assertEqual(p.y, y) - self.assertRaises(AttributeError, eval, 'p.z', locals()) - - def test_odd_sizes(self): - Zero = namedtuple('Zero', '') - self.assertEqual(Zero(), ()) - self.assertEqual(Zero._make([]), ()) - self.assertEqual(repr(Zero()), 'Zero()') - self.assertEqual(Zero()._asdict(), {}) - self.assertEqual(Zero()._fields, ()) - - Dot = namedtuple('Dot', 'd') - self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._make([1]), (1,)) - self.assertEqual(Dot(1).d, 1) - self.assertEqual(repr(Dot(1)), 'Dot(d=1)') - self.assertEqual(Dot(1)._asdict(), {'d':1}) - self.assertEqual(Dot(1)._replace(d=999), (999,)) - self.assertEqual(Dot(1)._fields, ('d',)) - - # n = 5000 - n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) - for j in range(10)]) for i in range(n))) - n = len(names) - Big = namedtuple('Big', names) - b = Big(*range(n)) - self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._make(range(n)), tuple(range(n))) - for pos, name in enumerate(names): - self.assertEqual(getattr(b, name), pos) - repr(b) # make sure repr() doesn't blow-up - d = b._asdict() - d_expected = dict(zip(names, range(n))) - self.assertEqual(d, d_expected) - b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) - b2_expected = list(range(n)) - b2_expected[1] = 999 - b2_expected[-5] = 42 - self.assertEqual(b2, tuple(b2_expected)) - self.assertEqual(b._fields, tuple(names)) - - def test_pickle(self): - p = TestNT(x=10, y=20, z=30) - for module in (pickle,): - loads = getattr(module, 'loads') - dumps = getattr(module, 'dumps') - for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): - q = loads(dumps(p, protocol)) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - self.assertNotIn(b'OrderedDict', dumps(p, protocol)) - - def test_copy(self): - p = TestNT(x=10, y=20, z=30) - for copier in copy.copy, copy.deepcopy: - q = copier(p) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_name_conflicts(self): - # Some names like "self", "cls", "tuple", "itemgetter", and "property" - # failed when used as field names. Test to make sure these now work. - T = namedtuple('T', 'itemgetter property self cls tuple') - t = T(1, 2, 3, 4, 5) - self.assertEqual(t, (1,2,3,4,5)) - newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) - self.assertEqual(newt, (10,20,30,40,50)) - - # Broader test of all interesting names in a template - with support.captured_stdout() as template: - T = namedtuple('T', 'x', verbose=True) - words = set(re.findall('[A-Za-z]+', template.getvalue())) - words -= set(keyword.kwlist) - T = namedtuple('T', words) - # test __new__ - values = tuple(range(len(words))) - t = T(*values) - self.assertEqual(t, values) - t = T(**dict(zip(T._fields, values))) - self.assertEqual(t, values) - # test _make - t = T._make(values) - self.assertEqual(t, values) - # exercise __repr__ - repr(t) - # test _asdict - self.assertEqual(t._asdict(), dict(zip(T._fields, values))) - # test _replace - t = T._make(values) - newvalues = tuple(v*10 for v in values) - newt = t._replace(**dict(zip(T._fields, newvalues))) - self.assertEqual(newt, newvalues) - # test _fields - self.assertEqual(T._fields, tuple(words)) - # test __getnewargs__ - self.assertEqual(t.__getnewargs__(), values) - - def test_repr(self): - with support.captured_stdout() as template: - A = namedtuple('A', 'x', verbose=True) - self.assertEqual(repr(A(1)), 'A(x=1)') - # repr should show the name of the subclass - class B(A): - pass - self.assertEqual(repr(B(1)), 'B(x=1)') - - def test_source(self): - # verify that _source can be run through exec() - tmp = namedtuple('NTColor', 'red green blue') - globals().pop('NTColor', None) # remove artifacts from other tests - exec(tmp._source, globals()) - self.assertIn('NTColor', globals()) - c = NTColor(10, 20, 30) - self.assertEqual((c.red, c.green, c.blue), (10, 20, 30)) - self.assertEqual(NTColor._fields, ('red', 'green', 'blue')) - globals().pop('NTColor', None) # clean-up after this test - - - def test_namedtuple_subclass_issue_24931(self): - class Point(namedtuple('_Point', ['x', 'y'])): - pass - - a = Point(3, 4) - self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) - - a.w = 5 - self.assertEqual(a.__dict__, {'w': 5}) - - -################################################################################ -### Abstract Base Classes -################################################################################ - -class ABCTestCase(unittest.TestCase): - - def validate_abstract_methods(self, abc, *names): - methodstubs = dict.fromkeys(names, lambda s, *args: 0) - - # everything should work will all required methods are present - C = type('C', (abc,), methodstubs) - C() - - # instantiation should fail if a required method is missing - for name in names: - stubs = methodstubs.copy() - del stubs[name] - C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) - - def validate_isinstance(self, abc, name): - stub = lambda s, *args: 0 - - C = type('C', (object,), {'__hash__': None}) - setattr(C, name, stub) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - - C = type('C', (object,), {'__hash__': None}) - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - - def validate_comparison(self, instance): - ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] - operators = {} - for op in ops: - name = '__' + op + '__' - operators[name] = getattr(operator, name) - - class Other: - def __init__(self): - self.right_side = False - def __eq__(self, other): - self.right_side = True - return True - __lt__ = __eq__ - __gt__ = __eq__ - __le__ = __eq__ - __ge__ = __eq__ - __ne__ = __eq__ - __ror__ = __eq__ - __rand__ = __eq__ - __rxor__ = __eq__ - __rsub__ = __eq__ - - for name, op in operators.items(): - if not hasattr(instance, name): - continue - other = Other() - op(instance, other) - self.assertTrue(other.right_side,'Right side not called for %s.%s' - % (type(instance), name)) - -class TestOneTrickPonyABCs(ABCTestCase): - - def test_Hashable(self): - # Check some non-hashables - non_samples = [bytearray(), list(), set(), dict()] - for x in non_samples: - self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) - # Check some hashables - samples = [None, - int(), float(), complex(), - str(), - tuple(), frozenset(), - int, list, object, type, bytes() - ] - for x in samples: - self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) - self.assertRaises(TypeError, Hashable) - # Check direct subclassing - class H(Hashable): - def __hash__(self): - return super().__hash__() - self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) - self.validate_abstract_methods(Hashable, '__hash__') - self.validate_isinstance(Hashable, '__hash__') - - def test_Iterable(self): - # Check some non-iterables - non_samples = [None, 42, 3.14, 1j] - for x in non_samples: - self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) - # Check some iterables - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) - # Check direct subclassing - class I(Iterable): - def __iter__(self): - return super().__iter__() - self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) - self.validate_abstract_methods(Iterable, '__iter__') - self.validate_isinstance(Iterable, '__iter__') - - def test_Iterator(self): - non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] - for x in non_samples: - self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) - samples = [iter(bytes()), iter(str()), - iter(tuple()), iter(list()), iter(dict()), - iter(set()), iter(frozenset()), - iter(dict().keys()), iter(dict().items()), - iter(dict().values()), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) - self.validate_abstract_methods(Iterator, '__next__', '__iter__') - - # Issue 10565 - class NextOnly: - def __next__(self): - yield 1 - raise StopIteration - self.assertNotIsInstance(NextOnly(), Iterator) - - def test_Sized(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - ] - for x in samples: - self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) - self.validate_abstract_methods(Sized, '__len__') - self.validate_isinstance(Sized, '__len__') - - def test_Container(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), - ] - for x in samples: - self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) - self.validate_abstract_methods(Container, '__contains__') - self.validate_isinstance(Container, '__contains__') - - def test_Callable(self): - non_samples = [None, 42, 3.14, 1j, - "", b"", (), [], {}, set(), - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) - samples = [lambda: None, - type, int, object, - len, - list.append, [].append, - ] - for x in samples: - self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) - self.validate_abstract_methods(Callable, '__call__') - self.validate_isinstance(Callable, '__call__') - - def test_direct_subclassing(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C(B): - pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) - - def test_registration(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C: - __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) - B.register(C) - self.assertTrue(issubclass(C, B)) - -class WithSet(MutableSet): - - def __init__(self, it=()): - self.data = set(it) - - def __len__(self): - return len(self.data) - - def __iter__(self): - return iter(self.data) - - def __contains__(self, item): - return item in self.data - - def add(self, item): - self.data.add(item) - - def discard(self, item): - self.data.discard(item) - -class TestCollectionABCs(ABCTestCase): - - # XXX For now, we only test some virtual inheritance properties. - # We should also test the proper behavior of the collection ABCs - # as real base classes or mix-in classes. - - def test_Set(self): - for sample in [set, frozenset]: - self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) - self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') - class MySet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - self.validate_comparison(MySet()) - - def test_hash_Set(self): - class OneTwoThreeSet(Set): - def __init__(self): - self.contents = [1, 2, 3] - def __contains__(self, x): - return x in self.contents - def __len__(self): - return len(self.contents) - def __iter__(self): - return iter(self.contents) - def __hash__(self): - return self._hash() - a, b = OneTwoThreeSet(), OneTwoThreeSet() - self.assertTrue(hash(a) == hash(b)) - - def test_MutableSet(self): - self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) - self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) - self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', - 'add', 'discard') - - def test_issue_5647(self): - # MutableSet.__iand__ mutated the set during iteration - s = WithSet('abcd') - s &= WithSet('cdef') # This used to fail - self.assertEqual(set(s), set('cd')) - - def test_issue_4920(self): - # MutableSet.pop() method did not work - class MySet(MutableSet): - __slots__=['__s'] - def __init__(self,items=None): - if items is None: - items=[] - self.__s=set(items) - def __contains__(self,v): - return v in self.__s - def __iter__(self): - return iter(self.__s) - def __len__(self): - return len(self.__s) - def add(self,v): - result=v not in self.__s - self.__s.add(v) - return result - def discard(self,v): - result=v in self.__s - self.__s.discard(v) - return result - def __repr__(self): - return "MySet(%s)" % repr(list(self)) - s = MySet([5,43,2,1]) - self.assertEqual(s.pop(), 1) - - def test_issue8750(self): - empty = WithSet() - full = WithSet(range(10)) - s = WithSet(full) - s -= s - self.assertEqual(s, empty) - s = WithSet(full) - s ^= s - self.assertEqual(s, empty) - s = WithSet(full) - s &= s - self.assertEqual(s, full) - s |= s - self.assertEqual(s, full) - - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - self.assertFalse(ncs < cs) - self.assertTrue(ncs <= cs) - self.assertFalse(ncs > cs) - self.assertTrue(ncs >= cs) - - def assertSameSet(self, s1, s2): - # coerce both to a real set then check equality - self.assertSetEqual(set(s1), set(s2)) - - def test_Set_interoperability_with_real_sets(self): - # Issue: 8743 - class ListSet(Set): - def __init__(self, elements=()): - self.data = [] - for elem in elements: - if elem not in self.data: - self.data.append(elem) - def __contains__(self, elem): - return elem in self.data - def __iter__(self): - return iter(self.data) - def __len__(self): - return len(self.data) - def __repr__(self): - return 'Set({!r})'.format(self.data) - - r1 = set('abc') - r2 = set('bcd') - r3 = set('abcde') - f1 = ListSet('abc') - f2 = ListSet('bcd') - f3 = ListSet('abcde') - l1 = list('abccba') - l2 = list('bcddcb') - l3 = list('abcdeedcba') - - target = r1 & r2 - self.assertSameSet(f1 & f2, target) - self.assertSameSet(f1 & r2, target) - self.assertSameSet(r2 & f1, target) - self.assertSameSet(f1 & l2, target) - - target = r1 | r2 - self.assertSameSet(f1 | f2, target) - self.assertSameSet(f1 | r2, target) - self.assertSameSet(r2 | f1, target) - self.assertSameSet(f1 | l2, target) - - fwd_target = r1 - r2 - rev_target = r2 - r1 - self.assertSameSet(f1 - f2, fwd_target) - self.assertSameSet(f2 - f1, rev_target) - self.assertSameSet(f1 - r2, fwd_target) - self.assertSameSet(f2 - r1, rev_target) - self.assertSameSet(r1 - f2, fwd_target) - self.assertSameSet(r2 - f1, rev_target) - self.assertSameSet(f1 - l2, fwd_target) - self.assertSameSet(f2 - l1, rev_target) - - target = r1 ^ r2 - self.assertSameSet(f1 ^ f2, target) - self.assertSameSet(f1 ^ r2, target) - self.assertSameSet(r2 ^ f1, target) - self.assertSameSet(f1 ^ l2, target) - - # Don't change the following to use assertLess or other - # "more specific" unittest assertions. The current - # assertTrue/assertFalse style makes the pattern of test - # case combinations clear and allows us to know for sure - # the exact operator being invoked. - - # proper subset - self.assertTrue(f1 < f3) - self.assertFalse(f1 < f1) - self.assertFalse(f1 < f2) - self.assertTrue(r1 < f3) - self.assertFalse(r1 < f1) - self.assertFalse(r1 < f2) - self.assertTrue(r1 < r3) - self.assertFalse(r1 < r1) - self.assertFalse(r1 < r2) - with self.assertRaises(TypeError): - f1 < l3 - with self.assertRaises(TypeError): - f1 < l1 - with self.assertRaises(TypeError): - f1 < l2 - - # any subset - self.assertTrue(f1 <= f3) - self.assertTrue(f1 <= f1) - self.assertFalse(f1 <= f2) - self.assertTrue(r1 <= f3) - self.assertTrue(r1 <= f1) - self.assertFalse(r1 <= f2) - self.assertTrue(r1 <= r3) - self.assertTrue(r1 <= r1) - self.assertFalse(r1 <= r2) - with self.assertRaises(TypeError): - f1 <= l3 - with self.assertRaises(TypeError): - f1 <= l1 - with self.assertRaises(TypeError): - f1 <= l2 - - # proper superset - self.assertTrue(f3 > f1) - self.assertFalse(f1 > f1) - self.assertFalse(f2 > f1) - self.assertTrue(r3 > r1) - self.assertFalse(f1 > r1) - self.assertFalse(f2 > r1) - self.assertTrue(r3 > r1) - self.assertFalse(r1 > r1) - self.assertFalse(r2 > r1) - with self.assertRaises(TypeError): - f1 > l3 - with self.assertRaises(TypeError): - f1 > l1 - with self.assertRaises(TypeError): - f1 > l2 - - # any superset - self.assertTrue(f3 >= f1) - self.assertTrue(f1 >= f1) - self.assertFalse(f2 >= f1) - self.assertTrue(r3 >= r1) - self.assertTrue(f1 >= r1) - self.assertFalse(f2 >= r1) - self.assertTrue(r3 >= r1) - self.assertTrue(r1 >= r1) - self.assertFalse(r2 >= r1) - with self.assertRaises(TypeError): - f1 >= l3 - with self.assertRaises(TypeError): - f1 >=l1 - with self.assertRaises(TypeError): - f1 >= l2 - - # equality - self.assertTrue(f1 == f1) - self.assertTrue(r1 == f1) - self.assertTrue(f1 == r1) - self.assertFalse(f1 == f3) - self.assertFalse(r1 == f3) - self.assertFalse(f1 == r3) - self.assertFalse(f1 == l3) - self.assertFalse(f1 == l1) - self.assertFalse(f1 == l2) - - # inequality - self.assertFalse(f1 != f1) - self.assertFalse(r1 != f1) - self.assertFalse(f1 != r1) - self.assertTrue(f1 != f3) - self.assertTrue(r1 != f3) - self.assertTrue(f1 != r3) - self.assertTrue(f1 != l3) - self.assertTrue(f1 != l1) - self.assertTrue(f1 != l2) - - def test_Mapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') - class MyMapping(Mapping): - def __len__(self): - return 0 - def __getitem__(self, i): - raise IndexError - def __iter__(self): - return iter(()) - self.validate_comparison(MyMapping()) - - def test_MutableMapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', - '__getitem__', '__setitem__', '__delitem__') - - def test_MutableMapping_subclass(self): - # Test issue 9214 - mymap = UserDict() - mymap['red'] = 5 - self.assertIsInstance(mymap.keys(), Set) - self.assertIsInstance(mymap.keys(), KeysView) - self.assertIsInstance(mymap.items(), Set) - self.assertIsInstance(mymap.items(), ItemsView) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.keys() | {'orange'} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), ['orange', 'red']) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.items() | {('orange', 3)} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), [('orange', 3), ('red', 5)]) - - def test_Sequence(self): - for sample in [tuple, list, bytes, str]: - self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) - self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(range, Sequence)) - self.assertIsInstance(memoryview(b""), Sequence) - self.assertTrue(issubclass(memoryview, Sequence)) - self.assertTrue(issubclass(str, Sequence)) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') - - def test_ByteString(self): - for sample in [bytes, bytearray]: - self.assertIsInstance(sample(), ByteString) - self.assertTrue(issubclass(sample, ByteString)) - for sample in [str, list, tuple]: - self.assertNotIsInstance(sample(), ByteString) - self.assertFalse(issubclass(sample, ByteString)) - self.assertNotIsInstance(memoryview(b""), ByteString) - self.assertFalse(issubclass(memoryview, ByteString)) - - def test_MutableSequence(self): - for sample in [tuple, str, bytes]: - self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list, bytearray]: - self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(str, MutableSequence)) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') - - def test_MutableSequence_mixins(self): - # Test the mixins of MutableSequence by creating a miminal concrete - # class inherited from it. - class MutableSequenceSubclass(MutableSequence): - def __init__(self): - self.lst = [] - - def __setitem__(self, index, value): - self.lst[index] = value - - def __getitem__(self, index): - return self.lst[index] - - def __len__(self): - return len(self.lst) - - def __delitem__(self, index): - del self.lst[index] - - def insert(self, index, value): - self.lst.insert(index, value) - - mss = MutableSequenceSubclass() - mss.append(0) - mss.extend((1, 2, 3, 4)) - self.assertEqual(len(mss), 5) - self.assertEqual(mss[3], 3) - mss.reverse() - self.assertEqual(mss[3], 1) - mss.pop() - self.assertEqual(len(mss), 4) - mss.remove(3) - self.assertEqual(len(mss), 3) - mss += (10, 20, 30) - self.assertEqual(len(mss), 6) - self.assertEqual(mss[-1], 30) - mss.clear() - self.assertEqual(len(mss), 0) - -################################################################################ -### Counter -################################################################################ - -class CounterSubclassWithSetItem(Counter): - # Test a counter subclass that overrides __setitem__ - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def __setitem__(self, key, value): - self.called = True - Counter.__setitem__(self, key, value) - -class CounterSubclassWithGet(Counter): - # Test a counter subclass that overrides get() - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def get(self, key, default): - self.called = True - return Counter.get(self, key, default) - -class TestCounter(unittest.TestCase): - - def test_basics(self): - c = Counter('abcaba') - self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) - self.assertEqual(c, Counter(a=3, b=2, c=1)) - self.assertIsInstance(c, dict) - self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) - self.assertEqual(len(c), 3) - self.assertEqual(sum(c.values()), 6) - self.assertEqual(sorted(c.values()), [1, 2, 3]) - self.assertEqual(sorted(c.keys()), ['a', 'b', 'c']) - self.assertEqual(sorted(c), ['a', 'b', 'c']) - self.assertEqual(sorted(c.items()), - [('a', 3), ('b', 2), ('c', 1)]) - self.assertEqual(c['b'], 2) - self.assertEqual(c['z'], 0) - self.assertEqual(c.__contains__('c'), True) - self.assertEqual(c.__contains__('z'), False) - self.assertEqual(c.get('b', 10), 2) - self.assertEqual(c.get('z', 10), 10) - self.assertEqual(c, dict(a=3, b=2, c=1)) - self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") - self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) - for i in range(5): - self.assertEqual(c.most_common(i), - [('a', 3), ('b', 2), ('c', 1)][:i]) - self.assertEqual(''.join(sorted(c.elements())), 'aaabbc') - c['a'] += 1 # increment an existing value - c['b'] -= 2 # sub existing value to zero - del c['c'] # remove an entry - del c['c'] # make sure that del doesn't raise KeyError - c['d'] -= 2 # sub from a missing value - c['e'] = -5 # directly assign a missing value - c['f'] += 4 # add to a missing value - self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) - self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff') - self.assertEqual(c.pop('f'), 4) - self.assertNotIn('f', c) - for i in range(3): - elem, cnt = c.popitem() - self.assertNotIn(elem, c) - c.clear() - self.assertEqual(c, {}) - self.assertEqual(repr(c), 'Counter()') - self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') - self.assertRaises(TypeError, hash, c) - c.update(dict(a=5, b=3)) - c.update(c=1) - c.update(Counter('a' * 50 + 'b' * 30)) - c.update() # test case with no args - c.__init__('a' * 500 + 'b' * 300) - c.__init__('cdc') - c.__init__() - self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) - self.assertEqual(c.setdefault('d', 5), 1) - self.assertEqual(c['d'], 1) - self.assertEqual(c.setdefault('e', 5), 5) - self.assertEqual(c['e'], 5) - - def test_init(self): - self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) - self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) - self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter, 42) - self.assertRaises(TypeError, Counter, (), ()) - self.assertRaises(TypeError, Counter.__init__) - - def test_update(self): - c = Counter() - c.update(self=42) - self.assertEqual(list(c.items()), [('self', 42)]) - c = Counter() - c.update(iterable=42) - self.assertEqual(list(c.items()), [('iterable', 42)]) - c = Counter() - c.update(iterable=None) - self.assertEqual(list(c.items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter().update, 42) - self.assertRaises(TypeError, Counter().update, {}, {}) - self.assertRaises(TypeError, Counter.update) - - def test_copying(self): - # Check that counters are copyable, deepcopyable, picklable, and - #have a repr/eval round-trip - words = Counter('which witch had which witches wrist watch'.split()) - def check(dup): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) - check(words.copy()) - check(copy.copy(words)) - check(copy.deepcopy(words)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(words, proto))) - check(eval(repr(words))) - update_test = Counter() - update_test.update(words) - check(update_test) - check(Counter(words)) - - def test_copy_subclass(self): - class MyCounter(Counter): - pass - c = MyCounter('slartibartfast') - d = c.copy() - self.assertEqual(d, c) - self.assertEqual(len(d), len(c)) - self.assertEqual(type(d), type(c)) - - def test_conversions(self): - # Convert to: set, list, dict - s = 'she sells sea shells by the sea shore' - self.assertEqual(sorted(Counter(s).elements()), sorted(s)) - self.assertEqual(sorted(Counter(s)), sorted(set(s))) - self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) - self.assertEqual(set(Counter(s)), set(s)) - - def test_invariant_for_the_in_operator(self): - c = Counter(a=10, b=-2, c=0) - for elem in c: - self.assertTrue(elem in c) - self.assertIn(elem, c) - - def test_multiset_operations(self): - # Verify that adding a zero counter will strip zeros and negatives - c = Counter(a=10, b=-2, c=0) + Counter() - self.assertEqual(dict(c), dict(a=10)) - - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for counterop, numberop in [ - (Counter.__add__, lambda x, y: max(0, x+y)), - (Counter.__sub__, lambda x, y: max(0, x-y)), - (Counter.__or__, lambda x, y: max(0,x,y)), - (Counter.__and__, lambda x, y: max(0, min(x,y))), - ]: - result = counterop(p, q) - for x in elements: - self.assertEqual(numberop(p[x], q[x]), result[x], - (counterop, x, p, q)) - # verify that results exclude non-positive counts - self.assertTrue(x>0 for x in result.values()) - - elements = 'abcdef' - for i in range(100): - # verify that random multisets with no repeats are exactly like sets - p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - for counterop, setop in [ - (Counter.__sub__, set.__sub__), - (Counter.__or__, set.__or__), - (Counter.__and__, set.__and__), - ]: - counter_result = counterop(p, q) - set_result = setop(set(p.elements()), set(q.elements())) - self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) - - def test_inplace_operations(self): - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for inplace_op, regular_op in [ - (Counter.__iadd__, Counter.__add__), - (Counter.__isub__, Counter.__sub__), - (Counter.__ior__, Counter.__or__), - (Counter.__iand__, Counter.__and__), - ]: - c = p.copy() - c_id = id(c) - regular_result = regular_op(c, q) - inplace_result = inplace_op(c, q) - self.assertEqual(inplace_result, regular_result) - self.assertEqual(id(inplace_result), c_id) - - def test_subtract(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter('aaabbcd') - c.subtract('aaaabbcce') - self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) - - c = Counter() - c.subtract(self=42) - self.assertEqual(list(c.items()), [('self', -42)]) - c = Counter() - c.subtract(iterable=42) - self.assertEqual(list(c.items()), [('iterable', -42)]) - self.assertRaises(TypeError, Counter().subtract, 42) - self.assertRaises(TypeError, Counter().subtract, {}, {}) - self.assertRaises(TypeError, Counter.subtract) - - def test_unary(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) - self.assertEqual(dict(-c), dict(a=5)) - - def test_repr_nonsortable(self): - c = Counter(a=2, b=None) - r = repr(c) - self.assertIn("'a': 2", r) - self.assertIn("'b': None", r) - - def test_helper_function(self): - # two paths, one for real dicts and one for other mappings - elems = list('abracadabra') - - d = dict() - _count_elements(d, elems) - self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) - - m = OrderedDict() - _count_elements(m, elems) - self.assertEqual(m, - OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) - - # test fidelity to the pure python version - c = CounterSubclassWithSetItem('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - c = CounterSubclassWithGet('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - - -################################################################################ -### OrderedDict -################################################################################ class TestOrderedDict(unittest.TestCase): @@ -1573,20 +298,5 @@ self.assertRaises(KeyError, d.popitem) -################################################################################ -### Run tests -################################################################################ - -import doctest, collections - -def test_main(verbose=None): - NamedTupleDocs = doctest.DocTestSuite(module=collections) - test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, TestChainMap, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] - support.run_unittest(*test_classes) - support.run_doctest(collections, verbose) - - if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -694,6 +694,9 @@ Tests ----- +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + - Issue #25099: Make test_compileall not fail when an entry on sys.path cannot be written to (commonly seen in administrative installs on Windows). -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 10:19:55 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 15:19:55 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjE2?= =?utf-8?q?=3A_Tests_for_OrderedDict_are_extracted_from_test=5Fcollections?= Message-ID: <20151125151955.31395.96326@psf.io> https://hg.python.org/cpython/rev/afaad8dc8edf changeset: 99355:afaad8dc8edf branch: 2.7 parent: 99351:eb9d2e5bc8dc user: Serhiy Storchaka date: Wed Nov 25 17:19:27 2015 +0200 summary: Issue #25616: Tests for OrderedDict are extracted from test_collections into separate file test_ordered_dict. files: Lib/test/test_collections.py | 311 +----- Lib/test/test_ordered_dict.py | 1052 +-------------------- Misc/NEWS | 6 + 3 files changed, 32 insertions(+), 1337 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,19 +1,24 @@ +import collections +import copy +import doctest +import keyword +import operator +import pickle +import cPickle +from random import choice, randrange +import re +import string +import sys +from test import test_support +import unittest -import unittest, doctest, operator -import inspect -from test import test_support from collections import namedtuple, Counter, OrderedDict -from test import mapping_tests -import pickle, cPickle, copy -from random import randrange, shuffle -import keyword -import re -import sys from collections import Hashable, Iterable, Iterator from collections import Sized, Container, Callable from collections import Set, MutableSet from collections import Mapping, MutableMapping from collections import Sequence, MutableSequence + # Silence deprecation warning sets = test_support.import_module('sets', deprecated=True) @@ -178,8 +183,7 @@ self.assertEqual(Dot(1)._fields, ('d',)) n = 5000 - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) + names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) Big = namedtuple('Big', names) @@ -556,7 +560,7 @@ def test_issue_4920(self): # MutableSet.pop() method did not work - class MySet(collections.MutableSet): + class MySet(MutableSet): __slots__=['__s'] def __init__(self,items=None): if items is None: @@ -802,7 +806,7 @@ self.assertTrue(issubclass(sample, Mapping)) self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', '__getitem__') - class MyMapping(collections.Mapping): + class MyMapping(Mapping): def __len__(self): return 0 def __getitem__(self, i): @@ -1038,290 +1042,11 @@ self.assertRaises(TypeError, Counter().subtract, {}, {}) self.assertRaises(TypeError, Counter.subtract) -class TestOrderedDict(unittest.TestCase): - - def test_init(self): - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input - self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input - self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input - self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], - c=3, e=5).items()), pairs) # mixed input - - # make sure no positional args conflict with possible kwdargs - self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) - self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) - self.assertRaises(TypeError, OrderedDict, 42) - self.assertRaises(TypeError, OrderedDict, (), ()) - self.assertRaises(TypeError, OrderedDict.__init__) - - # Make sure that direct calls to __init__ do not clear previous contents - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.__init__([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - def test_update(self): - with self.assertRaises(TypeError): - OrderedDict().update([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict() - od.update(dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # dict input - od = OrderedDict() - od.update(**dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # kwds input - od = OrderedDict() - od.update(pairs) - self.assertEqual(list(od.items()), pairs) # pairs input - od = OrderedDict() - od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) - self.assertEqual(list(od.items()), pairs) # mixed input - - # Issue 9137: Named argument called 'other' or 'self' - # shouldn't be treated specially. - od = OrderedDict() - od.update(self=23) - self.assertEqual(list(od.items()), [('self', 23)]) - od = OrderedDict() - od.update(other={}) - self.assertEqual(list(od.items()), [('other', {})]) - od = OrderedDict() - od.update(red=5, blue=6, other=7, self=8) - self.assertEqual(sorted(list(od.items())), - [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) - - # Make sure that direct calls to update do not clear previous contents - # add that updates items are not moved to the end - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.update([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - def test_abc(self): - self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) - - def test_clear(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(len(od), len(pairs)) - od.clear() - self.assertEqual(len(od), 0) - - def test_delitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - del od['a'] - self.assertNotIn('a', od) - with self.assertRaises(KeyError): - del od['a'] - self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) - - def test_setitem(self): - od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) - od['c'] = 10 # existing element - od['f'] = 20 # new element - self.assertEqual(list(od.items()), - [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) - - def test_iterators(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(list(od), [t[0] for t in pairs]) - self.assertEqual(od.keys()[:], [t[0] for t in pairs]) - self.assertEqual(od.values()[:], [t[1] for t in pairs]) - self.assertEqual(od.items()[:], pairs) - self.assertEqual(list(od.iterkeys()), [t[0] for t in pairs]) - self.assertEqual(list(od.itervalues()), [t[1] for t in pairs]) - self.assertEqual(list(od.iteritems()), pairs) - self.assertEqual(list(reversed(od)), - [t[0] for t in reversed(pairs)]) - - def test_popitem(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - while pairs: - self.assertEqual(od.popitem(), pairs.pop()) - with self.assertRaises(KeyError): - od.popitem() - self.assertEqual(len(od), 0) - - def test_pop(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - shuffle(pairs) - while pairs: - k, v = pairs.pop() - self.assertEqual(od.pop(k), v) - with self.assertRaises(KeyError): - od.pop('xyz') - self.assertEqual(len(od), 0) - self.assertEqual(od.pop(k, 12345), 12345) - - # make sure pop still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - m = Missing(a=1) - self.assertEqual(m.pop('b', 5), 5) - self.assertEqual(m.pop('a', 6), 1) - self.assertEqual(m.pop('a', 6), 6) - with self.assertRaises(KeyError): - m.pop('a') - - def test_equality(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od1 = OrderedDict(pairs) - od2 = OrderedDict(pairs) - self.assertEqual(od1, od2) # same order implies equality - pairs = pairs[2:] + pairs[:2] - od2 = OrderedDict(pairs) - self.assertNotEqual(od1, od2) # different order implies inequality - # comparison to regular dict is not order sensitive - self.assertEqual(od1, dict(od2)) - self.assertEqual(dict(od2), od1) - # different length implied inequality - self.assertNotEqual(od1, OrderedDict(pairs[:-1])) - - def test_copying(self): - # Check that ordered dicts are copyable, deepcopyable, picklable, - # and have a repr/eval round-trip - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - update_test = OrderedDict() - update_test.update(od) - for i, dup in enumerate([ - od.copy(), - copy.copy(od), - copy.deepcopy(od), - pickle.loads(pickle.dumps(od, 0)), - pickle.loads(pickle.dumps(od, 1)), - pickle.loads(pickle.dumps(od, 2)), - pickle.loads(pickle.dumps(od, -1)), - eval(repr(od)), - update_test, - OrderedDict(od), - ]): - self.assertTrue(dup is not od) - self.assertEqual(dup, od) - self.assertEqual(list(dup.items()), list(od.items())) - self.assertEqual(len(dup), len(od)) - self.assertEqual(type(dup), type(od)) - - def test_yaml_linkage(self): - # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. - # In yaml, lists are native but tuples are not. - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - # yaml.dump(od) --> - # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) - - def test_reduce_not_too_fat(self): - # do not save instance dictionary if not needed - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - self.assertEqual(len(od.__reduce__()), 2) - od.x = 10 - self.assertEqual(len(od.__reduce__()), 3) - - def test_repr(self): - od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") - self.assertEqual(eval(repr(od)), od) - self.assertEqual(repr(OrderedDict()), "OrderedDict()") - - def test_repr_recursive(self): - # See issue #9826 - od = OrderedDict.fromkeys('abc') - od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") - - def test_setdefault(self): - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - pair_order = list(od.items()) - self.assertEqual(od.setdefault('a', 10), 3) - # make sure order didn't change - self.assertEqual(list(od.items()), pair_order) - self.assertEqual(od.setdefault('x', 10), 10) - # make sure 'x' is added to the end - self.assertEqual(list(od.items())[-1], ('x', 10)) - - # make sure setdefault still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - self.assertEqual(Missing().setdefault(5, 9), 9) - - def test_reinsert(self): - # Given insert a, insert b, delete a, re-insert a, - # verify that a is now later than b. - od = OrderedDict() - od['a'] = 1 - od['b'] = 2 - del od['a'] - od['a'] = 1 - self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) - - def test_views(self): - s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split() - od = OrderedDict.fromkeys(s) - self.assertEqual(list(od.viewkeys()), s) - self.assertEqual(list(od.viewvalues()), [None for k in s]) - self.assertEqual(list(od.viewitems()), [(k, None) for k in s]) - - # See http://bugs.python.org/issue24286 - self.assertEqual(od.viewkeys(), dict(od).viewkeys()) - self.assertEqual(od.viewitems(), dict(od).viewitems()) - - def test_override_update(self): - # Verify that subclasses can override update() without breaking __init__() - class MyOD(OrderedDict): - def update(self, *args, **kwds): - raise Exception() - items = [('a', 1), ('c', 3), ('b', 2)] - self.assertEqual(list(MyOD(items).items()), items) - -class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - -class MyOrderedDict(OrderedDict): - pass - -class SubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - -import collections def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + TestCollectionABCs, TestCounter] test_support.run_unittest(*test_classes) test_support.run_doctest(collections, verbose) diff --git a/Lib/test/test_collections.py b/Lib/test/test_ordered_dict.py copy from Lib/test/test_collections.py copy to Lib/test/test_ordered_dict.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_ordered_dict.py @@ -1,1042 +1,11 @@ +import copy +import pickle +from random import shuffle +import unittest +from collections import OrderedDict +from collections import MutableMapping +from test import mapping_tests, test_support -import unittest, doctest, operator -import inspect -from test import test_support -from collections import namedtuple, Counter, OrderedDict -from test import mapping_tests -import pickle, cPickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -from collections import Hashable, Iterable, Iterator -from collections import Sized, Container, Callable -from collections import Set, MutableSet -from collections import Mapping, MutableMapping -from collections import Sequence, MutableSequence -# Silence deprecation warning -sets = test_support.import_module('sets', deprecated=True) - -TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests - -py273_named_tuple_pickle = '''\ -ccopy_reg -_reconstructor -p0 -(ctest.test_collections -TestNT -p1 -c__builtin__ -tuple -p2 -(I10 -I20 -I30 -tp3 -tp4 -Rp5 -ccollections -OrderedDict -p6 -((lp7 -(lp8 -S'x' -p9 -aI10 -aa(lp10 -S'y' -p11 -aI20 -aa(lp12 -S'z' -p13 -aI30 -aatp14 -Rp15 -b. -''' - -class TestNamedTuple(unittest.TestCase): - - def test_factory(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__name__, 'Point') - self.assertEqual(Point.__slots__, ()) - self.assertEqual(Point.__module__, __name__) - self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertEqual(Point._fields, ('x', 'y')) - - self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char - self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword - self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit - - self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char - self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword - self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit - self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore - self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field - - namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names - namedtuple('_', 'a b c') # Test leading underscores in a typename - - nt = namedtuple('nt', u'the quick brown fox') # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - nt = namedtuple('nt', (u'the', u'quick')) # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - - self.assertRaises(TypeError, Point._make, [11]) # catch too few args - self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_factory_doc_attr(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__doc__, 'Point(x, y)') - - def test_name_fixer(self): - for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char - [('abc', 'class'), ('abc', '_1')], # field has keyword - [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit - [('abc', '_efg'), ('abc', '_1')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space - ]: - self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) - - def test_instance(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertEqual(p, Point(x=11, y=22)) - self.assertEqual(p, Point(11, y=22)) - self.assertEqual(p, Point(y=22, x=11)) - self.assertEqual(p, Point(*(11, 22))) - self.assertEqual(p, Point(**dict(x=11, y=22))) - self.assertRaises(TypeError, Point, 1) # too few args - self.assertRaises(TypeError, Point, 1, 2, 3) # too many args - self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument - self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument - self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__weakref__', dir(p)) - self.assertEqual(p, Point._make([11, 22])) # test _make classmethod - self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute - self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method - self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - self.assertEqual(vars(p), p._asdict()) # verify that vars() works - - try: - p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') - - # verify that field string can have commas - Point = namedtuple('Point', 'x, y') - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - # verify that fieldspec can be a non-string sequence - Point = namedtuple('Point', ('x', 'y')) - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - def test_tupleness(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - - self.assertIsInstance(p, tuple) - self.assertEqual(p, (11, 22)) # matches a real tuple - self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple - self.assertEqual(list(p), [11, 22]) # coercable to a list - self.assertEqual(max(p), 22) # iterable - self.assertEqual(max(*p), 22) # star-able - x, y = p - self.assertEqual(p, (x, y)) # unpacks like a tuple - self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple - self.assertRaises(IndexError, p.__getitem__, 3) - - self.assertEqual(p.x, x) - self.assertEqual(p.y, y) - self.assertRaises(AttributeError, eval, 'p.z', locals()) - - def test_odd_sizes(self): - Zero = namedtuple('Zero', '') - self.assertEqual(Zero(), ()) - self.assertEqual(Zero._make([]), ()) - self.assertEqual(repr(Zero()), 'Zero()') - self.assertEqual(Zero()._asdict(), {}) - self.assertEqual(Zero()._fields, ()) - - Dot = namedtuple('Dot', 'd') - self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._make([1]), (1,)) - self.assertEqual(Dot(1).d, 1) - self.assertEqual(repr(Dot(1)), 'Dot(d=1)') - self.assertEqual(Dot(1)._asdict(), {'d':1}) - self.assertEqual(Dot(1)._replace(d=999), (999,)) - self.assertEqual(Dot(1)._fields, ('d',)) - - n = 5000 - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) - for j in range(10)]) for i in range(n))) - n = len(names) - Big = namedtuple('Big', names) - b = Big(*range(n)) - self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._make(range(n)), tuple(range(n))) - for pos, name in enumerate(names): - self.assertEqual(getattr(b, name), pos) - repr(b) # make sure repr() doesn't blow-up - d = b._asdict() - d_expected = dict(zip(names, range(n))) - self.assertEqual(d, d_expected) - b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) - b2_expected = range(n) - b2_expected[1] = 999 - b2_expected[-5] = 42 - self.assertEqual(b2, tuple(b2_expected)) - self.assertEqual(b._fields, tuple(names)) - - def test_pickle(self): - p = TestNT(x=10, y=20, z=30) - for module in pickle, cPickle: - loads = getattr(module, 'loads') - dumps = getattr(module, 'dumps') - for protocol in -1, 0, 1, 2: - q = loads(dumps(p, protocol)) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_copy(self): - p = TestNT(x=10, y=20, z=30) - for copier in copy.copy, copy.deepcopy: - q = copier(p) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_name_conflicts(self): - # Some names like "self", "cls", "tuple", "itemgetter", and "property" - # failed when used as field names. Test to make sure these now work. - T = namedtuple('T', 'itemgetter property self cls tuple') - t = T(1, 2, 3, 4, 5) - self.assertEqual(t, (1,2,3,4,5)) - newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) - self.assertEqual(newt, (10,20,30,40,50)) - - # Broader test of all interesting names in a template - with test_support.captured_stdout() as template: - T = namedtuple('T', 'x', verbose=True) - words = set(re.findall('[A-Za-z]+', template.getvalue())) - words -= set(keyword.kwlist) - T = namedtuple('T', words) - # test __new__ - values = tuple(range(len(words))) - t = T(*values) - self.assertEqual(t, values) - t = T(**dict(zip(T._fields, values))) - self.assertEqual(t, values) - # test _make - t = T._make(values) - self.assertEqual(t, values) - # exercise __repr__ - repr(t) - # test _asdict - self.assertEqual(t._asdict(), dict(zip(T._fields, values))) - # test _replace - t = T._make(values) - newvalues = tuple(v*10 for v in values) - newt = t._replace(**dict(zip(T._fields, newvalues))) - self.assertEqual(newt, newvalues) - # test _fields - self.assertEqual(T._fields, tuple(words)) - # test __getnewargs__ - self.assertEqual(t.__getnewargs__(), values) - - def test_pickling_bug_18015(self): - # http://bugs.python.org/issue18015 - pt = pickle.loads(py273_named_tuple_pickle) - self.assertEqual(pt.x, 10) - -class ABCTestCase(unittest.TestCase): - - def validate_abstract_methods(self, abc, *names): - methodstubs = dict.fromkeys(names, lambda s, *args: 0) - - # everything should work will all required methods are present - C = type('C', (abc,), methodstubs) - C() - - # instantiation should fail if a required method is missing - for name in names: - stubs = methodstubs.copy() - del stubs[name] - C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) - - def validate_isinstance(self, abc, name): - stub = lambda s, *args: 0 - - # new-style class - C = type('C', (object,), {name: stub}) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - # old-style class - class C: pass - setattr(C, name, stub) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - - # new-style class - C = type('C', (object,), {'__hash__': None}) - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - # old-style class - class C: pass - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - - def validate_comparison(self, instance): - ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] - operators = {} - for op in ops: - name = '__' + op + '__' - operators[name] = getattr(operator, name) - - class Other: - def __init__(self): - self.right_side = False - def __eq__(self, other): - self.right_side = True - return True - __lt__ = __eq__ - __gt__ = __eq__ - __le__ = __eq__ - __ge__ = __eq__ - __ne__ = __eq__ - __ror__ = __eq__ - __rand__ = __eq__ - __rxor__ = __eq__ - __rsub__ = __eq__ - - for name, op in operators.items(): - if not hasattr(instance, name): - continue - other = Other() - op(instance, other) - self.assertTrue(other.right_side,'Right side not called for %s.%s' - % (type(instance), name)) - -class TestOneTrickPonyABCs(ABCTestCase): - - def test_Hashable(self): - # Check some non-hashables - non_samples = [list(), set(), dict()] - for x in non_samples: - self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) - # Check some hashables - samples = [None, - int(), float(), complex(), - str(), - tuple(), frozenset(), - int, list, object, type, - ] - for x in samples: - self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) - self.assertRaises(TypeError, Hashable) - # Check direct subclassing - class H(Hashable): - def __hash__(self): - return super(H, self).__hash__() - __eq__ = Hashable.__eq__ # Silence Py3k warning - self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) - self.validate_abstract_methods(Hashable, '__hash__') - self.validate_isinstance(Hashable, '__hash__') - - def test_Iterable(self): - # Check some non-iterables - non_samples = [None, 42, 3.14, 1j] - for x in non_samples: - self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) - # Check some iterables - samples = [str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) - # Check direct subclassing - class I(Iterable): - def __iter__(self): - return super(I, self).__iter__() - self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) - self.validate_abstract_methods(Iterable, '__iter__') - self.validate_isinstance(Iterable, '__iter__') - - def test_Iterator(self): - non_samples = [None, 42, 3.14, 1j, "".encode('ascii'), "", (), [], - {}, set()] - for x in non_samples: - self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) - samples = [iter(str()), - iter(tuple()), iter(list()), iter(dict()), - iter(set()), iter(frozenset()), - iter(dict().keys()), iter(dict().items()), - iter(dict().values()), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) - self.validate_abstract_methods(Iterator, 'next', '__iter__') - - # Issue 10565 - class NextOnly: - def __next__(self): - yield 1 - raise StopIteration - self.assertNotIsInstance(NextOnly(), Iterator) - class NextOnlyNew(object): - def __next__(self): - yield 1 - raise StopIteration - self.assertNotIsInstance(NextOnlyNew(), Iterator) - - def test_Sized(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) - samples = [str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - ] - for x in samples: - self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) - self.validate_abstract_methods(Sized, '__len__') - self.validate_isinstance(Sized, '__len__') - - def test_Container(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) - samples = [str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), - ] - for x in samples: - self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) - self.validate_abstract_methods(Container, '__contains__') - self.validate_isinstance(Container, '__contains__') - - def test_Callable(self): - non_samples = [None, 42, 3.14, 1j, - "", "".encode('ascii'), (), [], {}, set(), - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) - samples = [lambda: None, - type, int, object, - len, - list.append, [].append, - ] - for x in samples: - self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) - self.validate_abstract_methods(Callable, '__call__') - self.validate_isinstance(Callable, '__call__') - - def test_direct_subclassing(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C(B): - pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) - - def test_registration(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C: - __metaclass__ = type - __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) - B.register(C) - self.assertTrue(issubclass(C, B)) - -class WithSet(MutableSet): - - def __init__(self, it=()): - self.data = set(it) - - def __len__(self): - return len(self.data) - - def __iter__(self): - return iter(self.data) - - def __contains__(self, item): - return item in self.data - - def add(self, item): - self.data.add(item) - - def discard(self, item): - self.data.discard(item) - -class TestCollectionABCs(ABCTestCase): - - # XXX For now, we only test some virtual inheritance properties. - # We should also test the proper behavior of the collection ABCs - # as real base classes or mix-in classes. - - def test_Set(self): - for sample in [set, frozenset]: - self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) - self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') - class MySet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - self.validate_comparison(MySet()) - - def test_hash_Set(self): - class OneTwoThreeSet(Set): - def __init__(self): - self.contents = [1, 2, 3] - def __contains__(self, x): - return x in self.contents - def __len__(self): - return len(self.contents) - def __iter__(self): - return iter(self.contents) - def __hash__(self): - return self._hash() - a, b = OneTwoThreeSet(), OneTwoThreeSet() - self.assertTrue(hash(a) == hash(b)) - - def test_MutableSet(self): - self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) - self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) - self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', - 'add', 'discard') - - def test_issue_5647(self): - # MutableSet.__iand__ mutated the set during iteration - s = WithSet('abcd') - s &= WithSet('cdef') # This used to fail - self.assertEqual(set(s), set('cd')) - - def test_issue_4920(self): - # MutableSet.pop() method did not work - class MySet(collections.MutableSet): - __slots__=['__s'] - def __init__(self,items=None): - if items is None: - items=[] - self.__s=set(items) - def __contains__(self,v): - return v in self.__s - def __iter__(self): - return iter(self.__s) - def __len__(self): - return len(self.__s) - def add(self,v): - result=v not in self.__s - self.__s.add(v) - return result - def discard(self,v): - result=v in self.__s - self.__s.discard(v) - return result - def __repr__(self): - return "MySet(%s)" % repr(list(self)) - s = MySet([5,43,2,1]) - self.assertEqual(s.pop(), 1) - - def test_issue8750(self): - empty = WithSet() - full = WithSet(range(10)) - s = WithSet(full) - s -= s - self.assertEqual(s, empty) - s = WithSet(full) - s ^= s - self.assertEqual(s, empty) - s = WithSet(full) - s &= s - self.assertEqual(s, full) - s |= s - self.assertEqual(s, full) - - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - - # Run all the variants to make sure they don't mutually recurse - ncs < cs - ncs <= cs - ncs > cs - ncs >= cs - cs < ncs - cs <= ncs - cs > ncs - cs >= ncs - - def assertSameSet(self, s1, s2): - # coerce both to a real set then check equality - self.assertEqual(set(s1), set(s2)) - - def test_Set_interoperability_with_real_sets(self): - # Issue: 8743 - class ListSet(Set): - def __init__(self, elements=()): - self.data = [] - for elem in elements: - if elem not in self.data: - self.data.append(elem) - def __contains__(self, elem): - return elem in self.data - def __iter__(self): - return iter(self.data) - def __len__(self): - return len(self.data) - def __repr__(self): - return 'Set({!r})'.format(self.data) - - r1 = set('abc') - r2 = set('bcd') - r3 = set('abcde') - f1 = ListSet('abc') - f2 = ListSet('bcd') - f3 = ListSet('abcde') - l1 = list('abccba') - l2 = list('bcddcb') - l3 = list('abcdeedcba') - p1 = sets.Set('abc') - p2 = sets.Set('bcd') - p3 = sets.Set('abcde') - - target = r1 & r2 - self.assertSameSet(f1 & f2, target) - self.assertSameSet(f1 & r2, target) - self.assertSameSet(r2 & f1, target) - self.assertSameSet(f1 & p2, target) - self.assertSameSet(p2 & f1, target) - self.assertSameSet(f1 & l2, target) - - target = r1 | r2 - self.assertSameSet(f1 | f2, target) - self.assertSameSet(f1 | r2, target) - self.assertSameSet(r2 | f1, target) - self.assertSameSet(f1 | p2, target) - self.assertSameSet(p2 | f1, target) - self.assertSameSet(f1 | l2, target) - - fwd_target = r1 - r2 - rev_target = r2 - r1 - self.assertSameSet(f1 - f2, fwd_target) - self.assertSameSet(f2 - f1, rev_target) - self.assertSameSet(f1 - r2, fwd_target) - self.assertSameSet(f2 - r1, rev_target) - self.assertSameSet(r1 - f2, fwd_target) - self.assertSameSet(r2 - f1, rev_target) - self.assertSameSet(f1 - p2, fwd_target) - self.assertSameSet(f2 - p1, rev_target) - self.assertSameSet(p1 - f2, fwd_target) - self.assertSameSet(p2 - f1, rev_target) - self.assertSameSet(f1 - l2, fwd_target) - self.assertSameSet(f2 - l1, rev_target) - - target = r1 ^ r2 - self.assertSameSet(f1 ^ f2, target) - self.assertSameSet(f1 ^ r2, target) - self.assertSameSet(r2 ^ f1, target) - self.assertSameSet(f1 ^ p2, target) - self.assertSameSet(p2 ^ f1, target) - self.assertSameSet(f1 ^ l2, target) - - # proper subset - self.assertTrue(f1 < f3) - self.assertFalse(f1 < f1) - self.assertFalse(f1 < f2) - self.assertTrue(r1 < f3) - self.assertFalse(r1 < f1) - self.assertFalse(r1 < f2) - self.assertTrue(r1 < r3) - self.assertFalse(r1 < r1) - self.assertFalse(r1 < r2) - - with test_support.check_py3k_warnings(): - # python 2 only, cross-type compares will succeed - f1 < l3 - f1 < l1 - f1 < l2 - - # any subset - self.assertTrue(f1 <= f3) - self.assertTrue(f1 <= f1) - self.assertFalse(f1 <= f2) - self.assertTrue(r1 <= f3) - self.assertTrue(r1 <= f1) - self.assertFalse(r1 <= f2) - self.assertTrue(r1 <= r3) - self.assertTrue(r1 <= r1) - self.assertFalse(r1 <= r2) - - with test_support.check_py3k_warnings(): - # python 2 only, cross-type compares will succeed - f1 <= l3 - f1 <= l1 - f1 <= l2 - - # proper superset - self.assertTrue(f3 > f1) - self.assertFalse(f1 > f1) - self.assertFalse(f2 > f1) - self.assertTrue(r3 > r1) - self.assertFalse(f1 > r1) - self.assertFalse(f2 > r1) - self.assertTrue(r3 > r1) - self.assertFalse(r1 > r1) - self.assertFalse(r2 > r1) - - with test_support.check_py3k_warnings(): - # python 2 only, cross-type compares will succeed - f1 > l3 - f1 > l1 - f1 > l2 - - # any superset - self.assertTrue(f3 >= f1) - self.assertTrue(f1 >= f1) - self.assertFalse(f2 >= f1) - self.assertTrue(r3 >= r1) - self.assertTrue(f1 >= r1) - self.assertFalse(f2 >= r1) - self.assertTrue(r3 >= r1) - self.assertTrue(r1 >= r1) - self.assertFalse(r2 >= r1) - - with test_support.check_py3k_warnings(): - # python 2 only, cross-type compares will succeed - f1 >= l3 - f1 >=l1 - f1 >= l2 - - # equality - self.assertTrue(f1 == f1) - self.assertTrue(r1 == f1) - self.assertTrue(f1 == r1) - self.assertFalse(f1 == f3) - self.assertFalse(r1 == f3) - self.assertFalse(f1 == r3) - # python 2 only, cross-type compares will succeed - f1 == l3 - f1 == l1 - f1 == l2 - - # inequality - self.assertFalse(f1 != f1) - self.assertFalse(r1 != f1) - self.assertFalse(f1 != r1) - self.assertTrue(f1 != f3) - self.assertTrue(r1 != f3) - self.assertTrue(f1 != r3) - # python 2 only, cross-type compares will succeed - f1 != l3 - f1 != l1 - f1 != l2 - - def test_Mapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') - class MyMapping(collections.Mapping): - def __len__(self): - return 0 - def __getitem__(self, i): - raise IndexError - def __iter__(self): - return iter(()) - self.validate_comparison(MyMapping()) - - def test_MutableMapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', - '__getitem__', '__setitem__', '__delitem__') - - def test_Sequence(self): - for sample in [tuple, list, str]: - self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) - self.assertTrue(issubclass(basestring, Sequence)) - self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(xrange, Sequence)) - self.assertTrue(issubclass(str, Sequence)) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') - - def test_MutableSequence(self): - for sample in [tuple, str]: - self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list]: - self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(basestring, MutableSequence)) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') - -class TestCounter(unittest.TestCase): - - def test_basics(self): - c = Counter('abcaba') - self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) - self.assertEqual(c, Counter(a=3, b=2, c=1)) - self.assertIsInstance(c, dict) - self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) - self.assertEqual(len(c), 3) - self.assertEqual(sum(c.values()), 6) - self.assertEqual(sorted(c.values()), [1, 2, 3]) - self.assertEqual(sorted(c.keys()), ['a', 'b', 'c']) - self.assertEqual(sorted(c), ['a', 'b', 'c']) - self.assertEqual(sorted(c.items()), - [('a', 3), ('b', 2), ('c', 1)]) - self.assertEqual(c['b'], 2) - self.assertEqual(c['z'], 0) - with test_support.check_py3k_warnings(): - self.assertEqual(c.has_key('c'), True) - self.assertEqual(c.has_key('z'), False) - self.assertEqual(c.__contains__('c'), True) - self.assertEqual(c.__contains__('z'), False) - self.assertEqual(c.get('b', 10), 2) - self.assertEqual(c.get('z', 10), 10) - self.assertEqual(c, dict(a=3, b=2, c=1)) - self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") - self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) - for i in range(5): - self.assertEqual(c.most_common(i), - [('a', 3), ('b', 2), ('c', 1)][:i]) - self.assertEqual(''.join(sorted(c.elements())), 'aaabbc') - c['a'] += 1 # increment an existing value - c['b'] -= 2 # sub existing value to zero - del c['c'] # remove an entry - del c['c'] # make sure that del doesn't raise KeyError - c['d'] -= 2 # sub from a missing value - c['e'] = -5 # directly assign a missing value - c['f'] += 4 # add to a missing value - self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) - self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff') - self.assertEqual(c.pop('f'), 4) - self.assertNotIn('f', c) - for i in range(3): - elem, cnt = c.popitem() - self.assertNotIn(elem, c) - c.clear() - self.assertEqual(c, {}) - self.assertEqual(repr(c), 'Counter()') - self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') - self.assertRaises(TypeError, hash, c) - c.update(dict(a=5, b=3)) - c.update(c=1) - c.update(Counter('a' * 50 + 'b' * 30)) - c.update() # test case with no args - c.__init__('a' * 500 + 'b' * 300) - c.__init__('cdc') - c.__init__() - self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) - self.assertEqual(c.setdefault('d', 5), 1) - self.assertEqual(c['d'], 1) - self.assertEqual(c.setdefault('e', 5), 5) - self.assertEqual(c['e'], 5) - - def test_init(self): - self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) - self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) - self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter, 42) - self.assertRaises(TypeError, Counter, (), ()) - self.assertRaises(TypeError, Counter.__init__) - - def test_update(self): - c = Counter() - c.update(self=42) - self.assertEqual(list(c.items()), [('self', 42)]) - c = Counter() - c.update(iterable=42) - self.assertEqual(list(c.items()), [('iterable', 42)]) - c = Counter() - c.update(iterable=None) - self.assertEqual(list(c.items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter().update, 42) - self.assertRaises(TypeError, Counter().update, {}, {}) - self.assertRaises(TypeError, Counter.update) - - def test_copying(self): - # Check that counters are copyable, deepcopyable, picklable, and - #have a repr/eval round-trip - words = Counter('which witch had which witches wrist watch'.split()) - update_test = Counter() - update_test.update(words) - for i, dup in enumerate([ - words.copy(), - copy.copy(words), - copy.deepcopy(words), - pickle.loads(pickle.dumps(words, 0)), - pickle.loads(pickle.dumps(words, 1)), - pickle.loads(pickle.dumps(words, 2)), - pickle.loads(pickle.dumps(words, -1)), - cPickle.loads(cPickle.dumps(words, 0)), - cPickle.loads(cPickle.dumps(words, 1)), - cPickle.loads(cPickle.dumps(words, 2)), - cPickle.loads(cPickle.dumps(words, -1)), - eval(repr(words)), - update_test, - Counter(words), - ]): - msg = (i, dup, words) - self.assertTrue(dup is not words) - self.assertEqual(dup, words) - self.assertEqual(len(dup), len(words)) - self.assertEqual(type(dup), type(words)) - - def test_copy_subclass(self): - class MyCounter(Counter): - pass - c = MyCounter('slartibartfast') - d = c.copy() - self.assertEqual(d, c) - self.assertEqual(len(d), len(c)) - self.assertEqual(type(d), type(c)) - - def test_conversions(self): - # Convert to: set, list, dict - s = 'she sells sea shells by the sea shore' - self.assertEqual(sorted(Counter(s).elements()), sorted(s)) - self.assertEqual(sorted(Counter(s)), sorted(set(s))) - self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) - self.assertEqual(set(Counter(s)), set(s)) - - def test_invariant_for_the_in_operator(self): - c = Counter(a=10, b=-2, c=0) - for elem in c: - self.assertTrue(elem in c) - self.assertIn(elem, c) - - def test_multiset_operations(self): - # Verify that adding a zero counter will strip zeros and negatives - c = Counter(a=10, b=-2, c=0) + Counter() - self.assertEqual(dict(c), dict(a=10)) - - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for counterop, numberop in [ - (Counter.__add__, lambda x, y: max(0, x+y)), - (Counter.__sub__, lambda x, y: max(0, x-y)), - (Counter.__or__, lambda x, y: max(0,x,y)), - (Counter.__and__, lambda x, y: max(0, min(x,y))), - ]: - result = counterop(p, q) - for x in elements: - self.assertEqual(numberop(p[x], q[x]), result[x], - (counterop, x, p, q)) - # verify that results exclude non-positive counts - self.assertTrue(x>0 for x in result.values()) - - elements = 'abcdef' - for i in range(100): - # verify that random multisets with no repeats are exactly like sets - p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - for counterop, setop in [ - (Counter.__sub__, set.__sub__), - (Counter.__or__, set.__or__), - (Counter.__and__, set.__and__), - ]: - counter_result = counterop(p, q) - set_result = setop(set(p.elements()), set(q.elements())) - self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) - - def test_subtract(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter('aaabbcd') - c.subtract('aaaabbcce') - self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) - - c = Counter() - c.subtract(self=42) - self.assertEqual(list(c.items()), [('self', -42)]) - c = Counter() - c.subtract(iterable=42) - self.assertEqual(list(c.items()), [('iterable', -42)]) - self.assertRaises(TypeError, Counter().subtract, 42) - self.assertRaises(TypeError, Counter().subtract, {}, {}) - self.assertRaises(TypeError, Counter.subtract) class TestOrderedDict(unittest.TestCase): @@ -1315,15 +284,10 @@ d = self._empty_mapping() self.assertRaises(KeyError, d.popitem) -import collections def test_main(verbose=None): - NamedTupleDocs = doctest.DocTestSuite(module=collections) - test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, - TestOrderedDict, GeneralMappingTests, SubclassMappingTests] + test_classes = [TestOrderedDict, GeneralMappingTests, SubclassMappingTests] test_support.run_unittest(*test_classes) - test_support.run_doctest(collections, verbose) if __name__ == "__main__": test_main(verbose=True) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -27,6 +27,12 @@ - Issue #23914: Fixed SystemError raised by CPickle unpickler on broken data. +Tests +----- + +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + What's New in Python 2.7.11? ============================ -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 10:19:55 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 15:19:55 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325616=3A_Tests_for_OrderedDict_are_extracted_fr?= =?utf-8?q?om_test=5Fcollections?= Message-ID: <20151125151955.658.98166@psf.io> https://hg.python.org/cpython/rev/81fa901162f9 changeset: 99354:81fa901162f9 parent: 99349:e61a864b703c parent: 99353:46e95e0eaae5 user: Serhiy Storchaka date: Wed Nov 25 17:18:57 2015 +0200 summary: Issue #25616: Tests for OrderedDict are extracted from test_collections into separate file test_ordered_dict. files: Lib/test/test_collections.py | 715 +-------- Lib/test/test_ordered_dict.py | 1660 +-------------------- Misc/NEWS | 3 + 3 files changed, 29 insertions(+), 2349 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,18 +1,21 @@ """Unit tests for collections.py.""" -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink, import_fresh_module -import contextlib +import collections +import copy +import doctest import inspect +import keyword +import operator +import pickle +from random import choice, randrange +import re +import string +import sys from test import support +import types +import unittest + from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -import types from collections import UserDict, UserString, UserList from collections import ChainMap from collections import deque @@ -313,8 +316,7 @@ # n = 5000 n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) + names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) Big = namedtuple('Big', names) @@ -1621,702 +1623,13 @@ ################################################################################ -### OrderedDict -################################################################################ - -py_coll = import_fresh_module('collections', blocked=['_collections']) -c_coll = import_fresh_module('collections', fresh=['_collections']) - - - at contextlib.contextmanager -def replaced_module(name, replacement): - original_module = sys.modules[name] - sys.modules[name] = replacement - try: - yield - finally: - sys.modules[name] = original_module - - -class OrderedDictTests: - - def test_init(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input - self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input - self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input - self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], - c=3, e=5).items()), pairs) # mixed input - - # make sure no positional args conflict with possible kwdargs - self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) - self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) - self.assertRaises(TypeError, OrderedDict, 42) - self.assertRaises(TypeError, OrderedDict, (), ()) - self.assertRaises(TypeError, OrderedDict.__init__) - - # Make sure that direct calls to __init__ do not clear previous contents - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.__init__([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - def test_update(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict().update([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict() - od.update(dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # dict input - od = OrderedDict() - od.update(**dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # kwds input - od = OrderedDict() - od.update(pairs) - self.assertEqual(list(od.items()), pairs) # pairs input - od = OrderedDict() - od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) - self.assertEqual(list(od.items()), pairs) # mixed input - - # Issue 9137: Named argument called 'other' or 'self' - # shouldn't be treated specially. - od = OrderedDict() - od.update(self=23) - self.assertEqual(list(od.items()), [('self', 23)]) - od = OrderedDict() - od.update(other={}) - self.assertEqual(list(od.items()), [('other', {})]) - od = OrderedDict() - od.update(red=5, blue=6, other=7, self=8) - self.assertEqual(sorted(list(od.items())), - [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) - - # Make sure that direct calls to update do not clear previous contents - # add that updates items are not moved to the end - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.update([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - def test_fromkeys(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) - od = OrderedDict.fromkeys('abc', value=None) - self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) - od = OrderedDict.fromkeys('abc', value=0) - self.assertEqual(list(od.items()), [(c, 0) for c in 'abc']) - - def test_abc(self): - OrderedDict = self.OrderedDict - self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) - - def test_clear(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(len(od), len(pairs)) - od.clear() - self.assertEqual(len(od), 0) - - def test_delitem(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - del od['a'] - self.assertNotIn('a', od) - with self.assertRaises(KeyError): - del od['a'] - self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) - - def test_setitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) - od['c'] = 10 # existing element - od['f'] = 20 # new element - self.assertEqual(list(od.items()), - [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) - - def test_iterators(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(list(od), [t[0] for t in pairs]) - self.assertEqual(list(od.keys()), [t[0] for t in pairs]) - self.assertEqual(list(od.values()), [t[1] for t in pairs]) - self.assertEqual(list(od.items()), pairs) - self.assertEqual(list(reversed(od)), - [t[0] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.keys())), - [t[0] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.values())), - [t[1] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) - - def test_detect_deletion_during_iteration(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - it = iter(od) - key = next(it) - del od[key] - with self.assertRaises(Exception): - # Note, the exact exception raised is not guaranteed - # The only guarantee that the next() will not succeed - next(it) - - def test_sorted_iterators(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict(pairs) - self.assertEqual(sorted(od), [t[0] for t in pairs]) - self.assertEqual(sorted(od.keys()), [t[0] for t in pairs]) - self.assertEqual(sorted(od.values()), [t[1] for t in pairs]) - self.assertEqual(sorted(od.items()), pairs) - self.assertEqual(sorted(reversed(od)), - sorted([t[0] for t in reversed(pairs)])) - - def test_iterators_empty(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - empty = [] - self.assertEqual(list(od), empty) - self.assertEqual(list(od.keys()), empty) - self.assertEqual(list(od.values()), empty) - self.assertEqual(list(od.items()), empty) - self.assertEqual(list(reversed(od)), empty) - self.assertEqual(list(reversed(od.keys())), empty) - self.assertEqual(list(reversed(od.values())), empty) - self.assertEqual(list(reversed(od.items())), empty) - - def test_popitem(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - while pairs: - self.assertEqual(od.popitem(), pairs.pop()) - with self.assertRaises(KeyError): - od.popitem() - self.assertEqual(len(od), 0) - - def test_popitem_last(self): - OrderedDict = self.OrderedDict - pairs = [(i, i) for i in range(30)] - - obj = OrderedDict(pairs) - for i in range(8): - obj.popitem(True) - obj.popitem(True) - obj.popitem(last=True) - self.assertEqual(len(obj), 20) - - def test_pop(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - shuffle(pairs) - while pairs: - k, v = pairs.pop() - self.assertEqual(od.pop(k), v) - with self.assertRaises(KeyError): - od.pop('xyz') - self.assertEqual(len(od), 0) - self.assertEqual(od.pop(k, 12345), 12345) - - # make sure pop still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - m = Missing(a=1) - self.assertEqual(m.pop('b', 5), 5) - self.assertEqual(m.pop('a', 6), 1) - self.assertEqual(m.pop('a', 6), 6) - self.assertEqual(m.pop('a', default=6), 6) - with self.assertRaises(KeyError): - m.pop('a') - - def test_equality(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od1 = OrderedDict(pairs) - od2 = OrderedDict(pairs) - self.assertEqual(od1, od2) # same order implies equality - pairs = pairs[2:] + pairs[:2] - od2 = OrderedDict(pairs) - self.assertNotEqual(od1, od2) # different order implies inequality - # comparison to regular dict is not order sensitive - self.assertEqual(od1, dict(od2)) - self.assertEqual(dict(od2), od1) - # different length implied inequality - self.assertNotEqual(od1, OrderedDict(pairs[:-1])) - - def test_copying(self): - OrderedDict = self.OrderedDict - # Check that ordered dicts are copyable, deepcopyable, picklable, - # and have a repr/eval round-trip - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - def check(dup): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) - self.assertEqual(list(dup.items()), list(od.items())) - self.assertEqual(len(dup), len(od)) - self.assertEqual(type(dup), type(od)) - check(od.copy()) - check(copy.copy(od)) - check(copy.deepcopy(od)) - # pickle directly pulls the module, so we have to fake it - with replaced_module('collections', self.module): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(od, proto))) - check(eval(repr(od))) - update_test = OrderedDict() - update_test.update(od) - check(update_test) - check(OrderedDict(od)) - - def test_yaml_linkage(self): - OrderedDict = self.OrderedDict - # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. - # In yaml, lists are native but tuples are not. - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - # yaml.dump(od) --> - # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) - - def test_reduce_not_too_fat(self): - OrderedDict = self.OrderedDict - # do not save instance dictionary if not needed - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - self.assertIsNone(od.__reduce__()[2]) - od.x = 10 - self.assertIsNotNone(od.__reduce__()[2]) - - def test_pickle_recursive(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od[1] = od - - # pickle directly pulls the module, so we have to fake it - with replaced_module('collections', self.module): - for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1): - dup = pickle.loads(pickle.dumps(od, proto)) - self.assertIsNot(dup, od) - self.assertEqual(list(dup.keys()), [1]) - self.assertIs(dup[1], dup) - - def test_repr(self): - OrderedDict = self.OrderedDict - od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") - self.assertEqual(eval(repr(od)), od) - self.assertEqual(repr(OrderedDict()), "OrderedDict()") - - def test_repr_recursive(self): - OrderedDict = self.OrderedDict - # See issue #9826 - od = OrderedDict.fromkeys('abc') - od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") - - def test_setdefault(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - pair_order = list(od.items()) - self.assertEqual(od.setdefault('a', 10), 3) - # make sure order didn't change - self.assertEqual(list(od.items()), pair_order) - self.assertEqual(od.setdefault('x', 10), 10) - # make sure 'x' is added to the end - self.assertEqual(list(od.items())[-1], ('x', 10)) - self.assertEqual(od.setdefault('g', default=9), 9) - - # make sure setdefault still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - self.assertEqual(Missing().setdefault(5, 9), 9) - - def test_reinsert(self): - OrderedDict = self.OrderedDict - # Given insert a, insert b, delete a, re-insert a, - # verify that a is now later than b. - od = OrderedDict() - od['a'] = 1 - od['b'] = 2 - del od['a'] - self.assertEqual(list(od.items()), [('b', 2)]) - od['a'] = 1 - self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) - - def test_move_to_end(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - od.move_to_end('c') - self.assertEqual(list(od), list('abdec')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('e') - self.assertEqual(list(od), list('cabde')) - od.move_to_end('b', last=False) - self.assertEqual(list(od), list('bcade')) - with self.assertRaises(KeyError): - od.move_to_end('x') - with self.assertRaises(KeyError): - od.move_to_end('x', 0) - - def test_move_to_end_issue25406(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - od.move_to_end('c', last=False) - self.assertEqual(list(od), list('cab')) - od.move_to_end('a', last=False) - self.assertEqual(list(od), list('acb')) - - od = OrderedDict.fromkeys('abc') - od.move_to_end('a') - self.assertEqual(list(od), list('bca')) - od.move_to_end('c') - self.assertEqual(list(od), list('bac')) - - def test_sizeof(self): - OrderedDict = self.OrderedDict - # Wimpy test: Just verify the reported size is larger than a regular dict - d = dict(a=1) - od = OrderedDict(**d) - self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) - - def test_views(self): - OrderedDict = self.OrderedDict - # See http://bugs.python.org/issue24286 - s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split() - od = OrderedDict.fromkeys(s) - self.assertEqual(od.keys(), dict(od).keys()) - self.assertEqual(od.items(), dict(od).items()) - - def test_override_update(self): - OrderedDict = self.OrderedDict - # Verify that subclasses can override update() without breaking __init__() - class MyOD(OrderedDict): - def update(self, *args, **kwds): - raise Exception() - items = [('a', 1), ('c', 3), ('b', 2)] - self.assertEqual(list(MyOD(items).items()), items) - - def test_highly_nested(self): - # Issue 25395: crashes during garbage collection - OrderedDict = self.OrderedDict - obj = None - for _ in range(1000): - obj = OrderedDict([(None, obj)]) - del obj - support.gc_collect() - - def test_highly_nested_subclass(self): - # Issue 25395: crashes during garbage collection - OrderedDict = self.OrderedDict - deleted = [] - class MyOD(OrderedDict): - def __del__(self): - deleted.append(self.i) - obj = None - for i in range(100): - obj = MyOD([(None, obj)]) - obj.i = i - del obj - support.gc_collect() - self.assertEqual(deleted, list(reversed(range(100)))) - - def test_delitem_hash_collision(self): - OrderedDict = self.OrderedDict - - class Key: - def __init__(self, hash): - self._hash = hash - self.value = str(id(self)) - def __hash__(self): - return self._hash - def __eq__(self, other): - try: - return self.value == other.value - except AttributeError: - return False - def __repr__(self): - return self.value - - def blocking_hash(hash): - # See the collision-handling in lookdict (in Objects/dictobject.c). - MINSIZE = 8 - i = (hash & MINSIZE-1) - return (i << 2) + i + hash + 1 - - COLLIDING = 1 - - key = Key(COLLIDING) - colliding = Key(COLLIDING) - blocking = Key(blocking_hash(COLLIDING)) - - od = OrderedDict() - od[key] = ... - od[blocking] = ... - od[colliding] = ... - od['after'] = ... - - del od[blocking] - del od[colliding] - self.assertEqual(list(od.items()), [(key, ...), ('after', ...)]) - - def test_issue24347(self): - OrderedDict = self.OrderedDict - - class Key: - def __hash__(self): - return randrange(100000) - - od = OrderedDict() - for i in range(100): - key = Key() - od[key] = i - - # These should not crash. - with self.assertRaises(KeyError): - list(od.values()) - with self.assertRaises(KeyError): - list(od.items()) - with self.assertRaises(KeyError): - repr(od) - with self.assertRaises(KeyError): - od.copy() - - def test_issue24348(self): - OrderedDict = self.OrderedDict - - class Key: - def __hash__(self): - return 1 - - od = OrderedDict() - od[Key()] = 0 - # This should not crash. - od.popitem() - - def test_issue24667(self): - """ - dict resizes after a certain number of insertion operations, - whether or not there were deletions that freed up slots in the - hash table. During fast node lookup, OrderedDict must correctly - respond to all resizes, even if the current "size" is the same - as the old one. We verify that here by forcing a dict resize - on a sparse odict and then perform an operation that should - trigger an odict resize (e.g. popitem). One key aspect here is - that we will keep the size of the odict the same at each popitem - call. This verifies that we handled the dict resize properly. - """ - OrderedDict = self.OrderedDict - - od = OrderedDict() - for c0 in '0123456789ABCDEF': - for c1 in '0123456789ABCDEF': - if len(od) == 4: - # This should not raise a KeyError. - od.popitem(last=False) - key = c0 + c1 - od[key] = key - - # Direct use of dict methods - - def test_dict_setitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - dict.__setitem__(od, 'spam', 1) - self.assertNotIn('NULL', repr(od)) - - def test_dict_delitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.__delitem__(od, 'spam') - with self.assertRaises(KeyError): - repr(od) - - def test_dict_clear(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.clear(od) - self.assertNotIn('NULL', repr(od)) - - def test_dict_pop(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.pop(od, 'spam') - with self.assertRaises(KeyError): - repr(od) - - def test_dict_popitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.popitem(od) - with self.assertRaises(KeyError): - repr(od) - - def test_dict_setdefault(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - dict.setdefault(od, 'spam', 1) - self.assertNotIn('NULL', repr(od)) - - def test_dict_update(self): - od = OrderedDict() - dict.update(od, [('spam', 1)]) - self.assertNotIn('NULL', repr(od)) - - -class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = py_coll - OrderedDict = py_coll.OrderedDict - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = c_coll - OrderedDict = c_coll.OrderedDict - - def test_key_change_during_iteration(self): - OrderedDict = self.OrderedDict - - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - with self.assertRaises(RuntimeError): - for i, k in enumerate(od): - od.move_to_end(k) - self.assertLess(i, 5) - with self.assertRaises(RuntimeError): - for k in od: - od['f'] = None - with self.assertRaises(RuntimeError): - for k in od: - del od['c'] - self.assertEqual(list(od), list('bdeaf')) - - -class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests): - - module = py_coll - class OrderedDict(py_coll.OrderedDict): - pass - - -class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests): - - module = c_coll - class OrderedDict(c_coll.OrderedDict): - pass - - -class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - cls.type2test = py_coll.OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - cls.type2test = c_coll.OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - -class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - class MyOrderedDict(py_coll.OrderedDict): - pass - cls.type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - class MyOrderedDict(c_coll.OrderedDict): - pass - cls.type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - -################################################################################ ### Run tests ################################################################################ -import doctest, collections - def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs, TestCounter, TestChainMap, - PurePythonOrderedDictTests, CPythonOrderedDictTests, - PurePythonOrderedDictSubclassTests, - CPythonOrderedDictSubclassTests, - PurePythonGeneralMappingTests, CPythonGeneralMappingTests, - PurePythonSubclassMappingTests, CPythonSubclassMappingTests, TestUserObjects, ] support.run_unittest(*test_classes) diff --git a/Lib/test/test_collections.py b/Lib/test/test_ordered_dict.py copy from Lib/test/test_collections.py copy to Lib/test/test_ordered_dict.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_ordered_dict.py @@ -1,1631 +1,15 @@ -"""Unit tests for collections.py.""" +import contextlib +import copy +import pickle +from random import randrange, shuffle +import sys +import unittest +from collections.abc import MutableMapping +from test import mapping_tests, support -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink, import_fresh_module -import contextlib -import inspect -from test import support -from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -import types -from collections import UserDict, UserString, UserList -from collections import ChainMap -from collections import deque -from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable -from collections.abc import Hashable, Iterable, Iterator, Generator -from collections.abc import Sized, Container, Callable -from collections.abc import Set, MutableSet -from collections.abc import Mapping, MutableMapping, KeysView, ItemsView -from collections.abc import Sequence, MutableSequence -from collections.abc import ByteString - -class TestUserObjects(unittest.TestCase): - def _superset_test(self, a, b): - self.assertGreaterEqual( - set(dir(a)), - set(dir(b)), - '{a} should have all the methods of {b}'.format( - a=a.__name__, - b=b.__name__, - ), - ) - def test_str_protocol(self): - self._superset_test(UserString, str) - - def test_list_protocol(self): - self._superset_test(UserList, list) - - def test_dict_protocol(self): - self._superset_test(UserDict, dict) - - -################################################################################ -### ChainMap (helper class for configparser and the string module) -################################################################################ - -class TestChainMap(unittest.TestCase): - - def test_basics(self): - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - d = c.new_child() - d['b'] = 20 - d['c'] = 30 - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - del d['b'] # unmask a value - self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - self.assertIn(repr(d), [ # check repr - type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", - type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" - ]) - - for e in d.copy(), copy.copy(d): # check shallow copies - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - self.assertIsNot(d.maps[0], e.maps[0]) - for m1, m2 in zip(d.maps[1:], e.maps[1:]): - self.assertIs(m1, m2) - - # check deep copies - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - e = pickle.loads(pickle.dumps(d, proto)) - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - for e in [copy.deepcopy(d), - eval(repr(d)) - ]: - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - - f = d.new_child() - f['b'] = 5 - self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) - self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents - self.assertEqual(f['b'], 5) # find first in chain - self.assertEqual(f.parents['b'], 2) # look beyond maps[0] - - def test_contructor(self): - self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict - self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list - - def test_bool(self): - self.assertFalse(ChainMap()) - self.assertFalse(ChainMap({}, {})) - self.assertTrue(ChainMap({1:2}, {})) - self.assertTrue(ChainMap({}, {1:2})) - - def test_missing(self): - class DefaultChainMap(ChainMap): - def __missing__(self, key): - return 999 - d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) - for k, v in dict(a=1, b=2, c=30, d=999).items(): - self.assertEqual(d[k], v) # check __getitem__ w/missing - for k, v in dict(a=1, b=2, c=30, d=77).items(): - self.assertEqual(d.get(k, 77), v) # check get() w/ missing - for k, v in dict(a=True, b=True, c=True, d=False).items(): - self.assertEqual(k in d, v) # check __contains__ w/missing - self.assertEqual(d.pop('a', 1001), 1, d) - self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing - self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing - with self.assertRaises(KeyError): - d.popitem() - - def test_dict_coercion(self): - d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) - self.assertEqual(dict(d), dict(a=1, b=2, c=30)) - self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) - - def test_new_child(self): - 'Tests for changes for issue #16613.' - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = {'b':20, 'c': 30} - d = c.new_child(m) - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertIs(m, d.maps[0]) - - # Use a different map than a dict - class lowerdict(dict): - def __getitem__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__getitem__(self, key) - def __contains__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__contains__(self, key) - - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = lowerdict(b=20, c=30) - d = c.new_child(m) - self.assertIs(m, d.maps[0]) - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - -################################################################################ -### Named Tuples -################################################################################ - -TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests - -class TestNamedTuple(unittest.TestCase): - - def test_factory(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__name__, 'Point') - self.assertEqual(Point.__slots__, ()) - self.assertEqual(Point.__module__, __name__) - self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertEqual(Point._fields, ('x', 'y')) - self.assertIn('class Point(tuple)', Point._source) - - self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char - self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword - self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit - - self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char - self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword - self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit - self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore - self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field - - namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names - namedtuple('_', 'a b c') # Test leading underscores in a typename - - nt = namedtuple('nt', 'the quick brown fox') # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - nt = namedtuple('nt', ('the', 'quick')) # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - - self.assertRaises(TypeError, Point._make, [11]) # catch too few args - self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_factory_doc_attr(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__doc__, 'Point(x, y)') - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_doc_writable(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.x.__doc__, 'Alias for field number 0') - Point.x.__doc__ = 'docstring for Point.x' - self.assertEqual(Point.x.__doc__, 'docstring for Point.x') - - def test_name_fixer(self): - for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char - [('abc', 'class'), ('abc', '_1')], # field has keyword - [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit - [('abc', '_efg'), ('abc', '_1')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space - ]: - self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) - - def test_instance(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertEqual(p, Point(x=11, y=22)) - self.assertEqual(p, Point(11, y=22)) - self.assertEqual(p, Point(y=22, x=11)) - self.assertEqual(p, Point(*(11, 22))) - self.assertEqual(p, Point(**dict(x=11, y=22))) - self.assertRaises(TypeError, Point, 1) # too few args - self.assertRaises(TypeError, Point, 1, 2, 3) # too many args - self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument - self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument - self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__weakref__', dir(p)) - self.assertEqual(p, Point._make([11, 22])) # test _make classmethod - self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute - self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method - self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - - try: - p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') - - # verify that field string can have commas - Point = namedtuple('Point', 'x, y') - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - # verify that fieldspec can be a non-string sequence - Point = namedtuple('Point', ('x', 'y')) - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - def test_tupleness(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - - self.assertIsInstance(p, tuple) - self.assertEqual(p, (11, 22)) # matches a real tuple - self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple - self.assertEqual(list(p), [11, 22]) # coercable to a list - self.assertEqual(max(p), 22) # iterable - self.assertEqual(max(*p), 22) # star-able - x, y = p - self.assertEqual(p, (x, y)) # unpacks like a tuple - self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple - self.assertRaises(IndexError, p.__getitem__, 3) - - self.assertEqual(p.x, x) - self.assertEqual(p.y, y) - self.assertRaises(AttributeError, eval, 'p.z', locals()) - - def test_odd_sizes(self): - Zero = namedtuple('Zero', '') - self.assertEqual(Zero(), ()) - self.assertEqual(Zero._make([]), ()) - self.assertEqual(repr(Zero()), 'Zero()') - self.assertEqual(Zero()._asdict(), {}) - self.assertEqual(Zero()._fields, ()) - - Dot = namedtuple('Dot', 'd') - self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._make([1]), (1,)) - self.assertEqual(Dot(1).d, 1) - self.assertEqual(repr(Dot(1)), 'Dot(d=1)') - self.assertEqual(Dot(1)._asdict(), {'d':1}) - self.assertEqual(Dot(1)._replace(d=999), (999,)) - self.assertEqual(Dot(1)._fields, ('d',)) - - # n = 5000 - n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) - for j in range(10)]) for i in range(n))) - n = len(names) - Big = namedtuple('Big', names) - b = Big(*range(n)) - self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._make(range(n)), tuple(range(n))) - for pos, name in enumerate(names): - self.assertEqual(getattr(b, name), pos) - repr(b) # make sure repr() doesn't blow-up - d = b._asdict() - d_expected = dict(zip(names, range(n))) - self.assertEqual(d, d_expected) - b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) - b2_expected = list(range(n)) - b2_expected[1] = 999 - b2_expected[-5] = 42 - self.assertEqual(b2, tuple(b2_expected)) - self.assertEqual(b._fields, tuple(names)) - - def test_pickle(self): - p = TestNT(x=10, y=20, z=30) - for module in (pickle,): - loads = getattr(module, 'loads') - dumps = getattr(module, 'dumps') - for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): - q = loads(dumps(p, protocol)) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - self.assertNotIn(b'OrderedDict', dumps(p, protocol)) - - def test_copy(self): - p = TestNT(x=10, y=20, z=30) - for copier in copy.copy, copy.deepcopy: - q = copier(p) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_name_conflicts(self): - # Some names like "self", "cls", "tuple", "itemgetter", and "property" - # failed when used as field names. Test to make sure these now work. - T = namedtuple('T', 'itemgetter property self cls tuple') - t = T(1, 2, 3, 4, 5) - self.assertEqual(t, (1,2,3,4,5)) - newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) - self.assertEqual(newt, (10,20,30,40,50)) - - # Broader test of all interesting names in a template - with support.captured_stdout() as template: - T = namedtuple('T', 'x', verbose=True) - words = set(re.findall('[A-Za-z]+', template.getvalue())) - words -= set(keyword.kwlist) - T = namedtuple('T', words) - # test __new__ - values = tuple(range(len(words))) - t = T(*values) - self.assertEqual(t, values) - t = T(**dict(zip(T._fields, values))) - self.assertEqual(t, values) - # test _make - t = T._make(values) - self.assertEqual(t, values) - # exercise __repr__ - repr(t) - # test _asdict - self.assertEqual(t._asdict(), dict(zip(T._fields, values))) - # test _replace - t = T._make(values) - newvalues = tuple(v*10 for v in values) - newt = t._replace(**dict(zip(T._fields, newvalues))) - self.assertEqual(newt, newvalues) - # test _fields - self.assertEqual(T._fields, tuple(words)) - # test __getnewargs__ - self.assertEqual(t.__getnewargs__(), values) - - def test_repr(self): - with support.captured_stdout() as template: - A = namedtuple('A', 'x', verbose=True) - self.assertEqual(repr(A(1)), 'A(x=1)') - # repr should show the name of the subclass - class B(A): - pass - self.assertEqual(repr(B(1)), 'B(x=1)') - - def test_source(self): - # verify that _source can be run through exec() - tmp = namedtuple('NTColor', 'red green blue') - globals().pop('NTColor', None) # remove artifacts from other tests - exec(tmp._source, globals()) - self.assertIn('NTColor', globals()) - c = NTColor(10, 20, 30) - self.assertEqual((c.red, c.green, c.blue), (10, 20, 30)) - self.assertEqual(NTColor._fields, ('red', 'green', 'blue')) - globals().pop('NTColor', None) # clean-up after this test - - - def test_namedtuple_subclass_issue_24931(self): - class Point(namedtuple('_Point', ['x', 'y'])): - pass - - a = Point(3, 4) - self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) - - a.w = 5 - self.assertEqual(a.__dict__, {'w': 5}) - - -################################################################################ -### Abstract Base Classes -################################################################################ - -class ABCTestCase(unittest.TestCase): - - def validate_abstract_methods(self, abc, *names): - methodstubs = dict.fromkeys(names, lambda s, *args: 0) - - # everything should work will all required methods are present - C = type('C', (abc,), methodstubs) - C() - - # instantiation should fail if a required method is missing - for name in names: - stubs = methodstubs.copy() - del stubs[name] - C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) - - def validate_isinstance(self, abc, name): - stub = lambda s, *args: 0 - - C = type('C', (object,), {'__hash__': None}) - setattr(C, name, stub) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - - C = type('C', (object,), {'__hash__': None}) - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - - def validate_comparison(self, instance): - ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] - operators = {} - for op in ops: - name = '__' + op + '__' - operators[name] = getattr(operator, name) - - class Other: - def __init__(self): - self.right_side = False - def __eq__(self, other): - self.right_side = True - return True - __lt__ = __eq__ - __gt__ = __eq__ - __le__ = __eq__ - __ge__ = __eq__ - __ne__ = __eq__ - __ror__ = __eq__ - __rand__ = __eq__ - __rxor__ = __eq__ - __rsub__ = __eq__ - - for name, op in operators.items(): - if not hasattr(instance, name): - continue - other = Other() - op(instance, other) - self.assertTrue(other.right_side,'Right side not called for %s.%s' - % (type(instance), name)) - -class TestOneTrickPonyABCs(ABCTestCase): - - def test_Awaitable(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object()] - for x in non_samples: - self.assertNotIsInstance(x, Awaitable) - self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) - - samples = [Bar(), MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Awaitable. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Awaitable) - - c = new_coro() - self.assertIsInstance(c, Awaitable) - c.close() # awoid RuntimeWarning that coro() was not awaited - - class CoroLike: pass - Coroutine.register(CoroLike) - self.assertTrue(isinstance(CoroLike(), Awaitable)) - self.assertTrue(issubclass(CoroLike, Awaitable)) - CoroLike = None - support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache - - def test_Coroutine(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object(), Bar()] - for x in non_samples: - self.assertNotIsInstance(x, Coroutine) - self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) - - samples = [MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Coroutine. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Coroutine) - - c = new_coro() - self.assertIsInstance(c, Coroutine) - c.close() # awoid RuntimeWarning that coro() was not awaited - - class CoroLike: - def send(self, value): - pass - def throw(self, typ, val=None, tb=None): - pass - def close(self): - pass - def __await__(self): - pass - self.assertTrue(isinstance(CoroLike(), Coroutine)) - self.assertTrue(issubclass(CoroLike, Coroutine)) - - class CoroLike: - def send(self, value): - pass - def close(self): - pass - def __await__(self): - pass - self.assertFalse(isinstance(CoroLike(), Coroutine)) - self.assertFalse(issubclass(CoroLike, Coroutine)) - - def test_Hashable(self): - # Check some non-hashables - non_samples = [bytearray(), list(), set(), dict()] - for x in non_samples: - self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) - # Check some hashables - samples = [None, - int(), float(), complex(), - str(), - tuple(), frozenset(), - int, list, object, type, bytes() - ] - for x in samples: - self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) - self.assertRaises(TypeError, Hashable) - # Check direct subclassing - class H(Hashable): - def __hash__(self): - return super().__hash__() - self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) - self.validate_abstract_methods(Hashable, '__hash__') - self.validate_isinstance(Hashable, '__hash__') - - def test_AsyncIterable(self): - class AI: - async def __aiter__(self): - return self - self.assertTrue(isinstance(AI(), AsyncIterable)) - self.assertTrue(issubclass(AI, AsyncIterable)) - # Check some non-iterables - non_samples = [None, object, []] - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterable) - self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) - self.validate_abstract_methods(AsyncIterable, '__aiter__') - self.validate_isinstance(AsyncIterable, '__aiter__') - - def test_AsyncIterator(self): - class AI: - async def __aiter__(self): - return self - async def __anext__(self): - raise StopAsyncIteration - self.assertTrue(isinstance(AI(), AsyncIterator)) - self.assertTrue(issubclass(AI, AsyncIterator)) - non_samples = [None, object, []] - # Check some non-iterables - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterator) - self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) - # Similarly to regular iterators (see issue 10565) - class AnextOnly: - async def __anext__(self): - raise StopAsyncIteration - self.assertNotIsInstance(AnextOnly(), AsyncIterator) - self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') - - def test_Iterable(self): - # Check some non-iterables - non_samples = [None, 42, 3.14, 1j] - for x in non_samples: - self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) - # Check some iterables - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) - # Check direct subclassing - class I(Iterable): - def __iter__(self): - return super().__iter__() - self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) - self.validate_abstract_methods(Iterable, '__iter__') - self.validate_isinstance(Iterable, '__iter__') - - def test_Iterator(self): - non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] - for x in non_samples: - self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) - samples = [iter(bytes()), iter(str()), - iter(tuple()), iter(list()), iter(dict()), - iter(set()), iter(frozenset()), - iter(dict().keys()), iter(dict().items()), - iter(dict().values()), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) - self.validate_abstract_methods(Iterator, '__next__', '__iter__') - - # Issue 10565 - class NextOnly: - def __next__(self): - yield 1 - return - self.assertNotIsInstance(NextOnly(), Iterator) - - def test_Generator(self): - class NonGen1: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def throw(self, typ, val=None, tb=None): pass - - class NonGen2: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - - class NonGen3: - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - non_samples = [ - None, 42, 3.14, 1j, b"", "", (), [], {}, set(), - iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] - for x in non_samples: - self.assertNotIsInstance(x, Generator) - self.assertFalse(issubclass(type(x), Generator), repr(type(x))) - - class Gen: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - class MinimalGen(Generator): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - - def gen(): - yield 1 - - samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertIsInstance(x, Generator) - self.assertTrue(issubclass(type(x), Generator), repr(type(x))) - self.validate_abstract_methods(Generator, 'send', 'throw') - - # mixin tests - mgen = MinimalGen() - self.assertIs(mgen, iter(mgen)) - self.assertIs(mgen.send(None), next(mgen)) - self.assertEqual(2, mgen.send(2)) - self.assertIsNone(mgen.close()) - self.assertRaises(ValueError, mgen.throw, ValueError) - self.assertRaisesRegex(ValueError, "^huhu$", - mgen.throw, ValueError, ValueError("huhu")) - self.assertRaises(StopIteration, mgen.throw, StopIteration()) - - class FailOnClose(Generator): - def send(self, value): return value - def throw(self, *args): raise ValueError - - self.assertRaises(ValueError, FailOnClose().close) - - class IgnoreGeneratorExit(Generator): - def send(self, value): return value - def throw(self, *args): pass - - self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) - - def test_Sized(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - ] - for x in samples: - self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) - self.validate_abstract_methods(Sized, '__len__') - self.validate_isinstance(Sized, '__len__') - - def test_Container(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), - ] - for x in samples: - self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) - self.validate_abstract_methods(Container, '__contains__') - self.validate_isinstance(Container, '__contains__') - - def test_Callable(self): - non_samples = [None, 42, 3.14, 1j, - "", b"", (), [], {}, set(), - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) - samples = [lambda: None, - type, int, object, - len, - list.append, [].append, - ] - for x in samples: - self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) - self.validate_abstract_methods(Callable, '__call__') - self.validate_isinstance(Callable, '__call__') - - def test_direct_subclassing(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C(B): - pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) - - def test_registration(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C: - __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) - B.register(C) - self.assertTrue(issubclass(C, B)) - -class WithSet(MutableSet): - - def __init__(self, it=()): - self.data = set(it) - - def __len__(self): - return len(self.data) - - def __iter__(self): - return iter(self.data) - - def __contains__(self, item): - return item in self.data - - def add(self, item): - self.data.add(item) - - def discard(self, item): - self.data.discard(item) - -class TestCollectionABCs(ABCTestCase): - - # XXX For now, we only test some virtual inheritance properties. - # We should also test the proper behavior of the collection ABCs - # as real base classes or mix-in classes. - - def test_Set(self): - for sample in [set, frozenset]: - self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) - self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') - class MySet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - self.validate_comparison(MySet()) - - def test_hash_Set(self): - class OneTwoThreeSet(Set): - def __init__(self): - self.contents = [1, 2, 3] - def __contains__(self, x): - return x in self.contents - def __len__(self): - return len(self.contents) - def __iter__(self): - return iter(self.contents) - def __hash__(self): - return self._hash() - a, b = OneTwoThreeSet(), OneTwoThreeSet() - self.assertTrue(hash(a) == hash(b)) - - def test_isdisjoint_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((4, 5, 6)) - s3 = MySet((1, 5, 6)) - self.assertTrue(s1.isdisjoint(s2)) - self.assertFalse(s1.isdisjoint(s3)) - - def test_equality_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1,)) - s2 = MySet((1, 2)) - s3 = MySet((3, 4)) - s4 = MySet((3, 4)) - self.assertTrue(s2 > s1) - self.assertTrue(s1 < s2) - self.assertFalse(s2 <= s1) - self.assertFalse(s2 <= s3) - self.assertFalse(s1 >= s2) - self.assertEqual(s3, s4) - self.assertNotEqual(s2, s3) - - def test_arithmetic_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((3, 4, 5)) - s3 = s1 & s2 - self.assertEqual(s3, MySet((3,))) - - def test_MutableSet(self): - self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) - self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) - self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', - 'add', 'discard') - - def test_issue_5647(self): - # MutableSet.__iand__ mutated the set during iteration - s = WithSet('abcd') - s &= WithSet('cdef') # This used to fail - self.assertEqual(set(s), set('cd')) - - def test_issue_4920(self): - # MutableSet.pop() method did not work - class MySet(MutableSet): - __slots__=['__s'] - def __init__(self,items=None): - if items is None: - items=[] - self.__s=set(items) - def __contains__(self,v): - return v in self.__s - def __iter__(self): - return iter(self.__s) - def __len__(self): - return len(self.__s) - def add(self,v): - result=v not in self.__s - self.__s.add(v) - return result - def discard(self,v): - result=v in self.__s - self.__s.discard(v) - return result - def __repr__(self): - return "MySet(%s)" % repr(list(self)) - s = MySet([5,43,2,1]) - self.assertEqual(s.pop(), 1) - - def test_issue8750(self): - empty = WithSet() - full = WithSet(range(10)) - s = WithSet(full) - s -= s - self.assertEqual(s, empty) - s = WithSet(full) - s ^= s - self.assertEqual(s, empty) - s = WithSet(full) - s &= s - self.assertEqual(s, full) - s |= s - self.assertEqual(s, full) - - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - self.assertFalse(ncs < cs) - self.assertTrue(ncs <= cs) - self.assertFalse(ncs > cs) - self.assertTrue(ncs >= cs) - - def assertSameSet(self, s1, s2): - # coerce both to a real set then check equality - self.assertSetEqual(set(s1), set(s2)) - - def test_Set_interoperability_with_real_sets(self): - # Issue: 8743 - class ListSet(Set): - def __init__(self, elements=()): - self.data = [] - for elem in elements: - if elem not in self.data: - self.data.append(elem) - def __contains__(self, elem): - return elem in self.data - def __iter__(self): - return iter(self.data) - def __len__(self): - return len(self.data) - def __repr__(self): - return 'Set({!r})'.format(self.data) - - r1 = set('abc') - r2 = set('bcd') - r3 = set('abcde') - f1 = ListSet('abc') - f2 = ListSet('bcd') - f3 = ListSet('abcde') - l1 = list('abccba') - l2 = list('bcddcb') - l3 = list('abcdeedcba') - - target = r1 & r2 - self.assertSameSet(f1 & f2, target) - self.assertSameSet(f1 & r2, target) - self.assertSameSet(r2 & f1, target) - self.assertSameSet(f1 & l2, target) - - target = r1 | r2 - self.assertSameSet(f1 | f2, target) - self.assertSameSet(f1 | r2, target) - self.assertSameSet(r2 | f1, target) - self.assertSameSet(f1 | l2, target) - - fwd_target = r1 - r2 - rev_target = r2 - r1 - self.assertSameSet(f1 - f2, fwd_target) - self.assertSameSet(f2 - f1, rev_target) - self.assertSameSet(f1 - r2, fwd_target) - self.assertSameSet(f2 - r1, rev_target) - self.assertSameSet(r1 - f2, fwd_target) - self.assertSameSet(r2 - f1, rev_target) - self.assertSameSet(f1 - l2, fwd_target) - self.assertSameSet(f2 - l1, rev_target) - - target = r1 ^ r2 - self.assertSameSet(f1 ^ f2, target) - self.assertSameSet(f1 ^ r2, target) - self.assertSameSet(r2 ^ f1, target) - self.assertSameSet(f1 ^ l2, target) - - # Don't change the following to use assertLess or other - # "more specific" unittest assertions. The current - # assertTrue/assertFalse style makes the pattern of test - # case combinations clear and allows us to know for sure - # the exact operator being invoked. - - # proper subset - self.assertTrue(f1 < f3) - self.assertFalse(f1 < f1) - self.assertFalse(f1 < f2) - self.assertTrue(r1 < f3) - self.assertFalse(r1 < f1) - self.assertFalse(r1 < f2) - self.assertTrue(r1 < r3) - self.assertFalse(r1 < r1) - self.assertFalse(r1 < r2) - with self.assertRaises(TypeError): - f1 < l3 - with self.assertRaises(TypeError): - f1 < l1 - with self.assertRaises(TypeError): - f1 < l2 - - # any subset - self.assertTrue(f1 <= f3) - self.assertTrue(f1 <= f1) - self.assertFalse(f1 <= f2) - self.assertTrue(r1 <= f3) - self.assertTrue(r1 <= f1) - self.assertFalse(r1 <= f2) - self.assertTrue(r1 <= r3) - self.assertTrue(r1 <= r1) - self.assertFalse(r1 <= r2) - with self.assertRaises(TypeError): - f1 <= l3 - with self.assertRaises(TypeError): - f1 <= l1 - with self.assertRaises(TypeError): - f1 <= l2 - - # proper superset - self.assertTrue(f3 > f1) - self.assertFalse(f1 > f1) - self.assertFalse(f2 > f1) - self.assertTrue(r3 > r1) - self.assertFalse(f1 > r1) - self.assertFalse(f2 > r1) - self.assertTrue(r3 > r1) - self.assertFalse(r1 > r1) - self.assertFalse(r2 > r1) - with self.assertRaises(TypeError): - f1 > l3 - with self.assertRaises(TypeError): - f1 > l1 - with self.assertRaises(TypeError): - f1 > l2 - - # any superset - self.assertTrue(f3 >= f1) - self.assertTrue(f1 >= f1) - self.assertFalse(f2 >= f1) - self.assertTrue(r3 >= r1) - self.assertTrue(f1 >= r1) - self.assertFalse(f2 >= r1) - self.assertTrue(r3 >= r1) - self.assertTrue(r1 >= r1) - self.assertFalse(r2 >= r1) - with self.assertRaises(TypeError): - f1 >= l3 - with self.assertRaises(TypeError): - f1 >=l1 - with self.assertRaises(TypeError): - f1 >= l2 - - # equality - self.assertTrue(f1 == f1) - self.assertTrue(r1 == f1) - self.assertTrue(f1 == r1) - self.assertFalse(f1 == f3) - self.assertFalse(r1 == f3) - self.assertFalse(f1 == r3) - self.assertFalse(f1 == l3) - self.assertFalse(f1 == l1) - self.assertFalse(f1 == l2) - - # inequality - self.assertFalse(f1 != f1) - self.assertFalse(r1 != f1) - self.assertFalse(f1 != r1) - self.assertTrue(f1 != f3) - self.assertTrue(r1 != f3) - self.assertTrue(f1 != r3) - self.assertTrue(f1 != l3) - self.assertTrue(f1 != l1) - self.assertTrue(f1 != l2) - - def test_Mapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') - class MyMapping(Mapping): - def __len__(self): - return 0 - def __getitem__(self, i): - raise IndexError - def __iter__(self): - return iter(()) - self.validate_comparison(MyMapping()) - - def test_MutableMapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', - '__getitem__', '__setitem__', '__delitem__') - - def test_MutableMapping_subclass(self): - # Test issue 9214 - mymap = UserDict() - mymap['red'] = 5 - self.assertIsInstance(mymap.keys(), Set) - self.assertIsInstance(mymap.keys(), KeysView) - self.assertIsInstance(mymap.items(), Set) - self.assertIsInstance(mymap.items(), ItemsView) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.keys() | {'orange'} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), ['orange', 'red']) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.items() | {('orange', 3)} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), [('orange', 3), ('red', 5)]) - - def test_Sequence(self): - for sample in [tuple, list, bytes, str]: - self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) - self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(range, Sequence)) - self.assertIsInstance(memoryview(b""), Sequence) - self.assertTrue(issubclass(memoryview, Sequence)) - self.assertTrue(issubclass(str, Sequence)) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') - - def test_Sequence_mixins(self): - class SequenceSubclass(Sequence): - def __init__(self, seq=()): - self.seq = seq - - def __getitem__(self, index): - return self.seq[index] - - def __len__(self): - return len(self.seq) - - # Compare Sequence.index() behavior to (list|str).index() behavior - def assert_index_same(seq1, seq2, index_args): - try: - expected = seq1.index(*index_args) - except ValueError: - with self.assertRaises(ValueError): - seq2.index(*index_args) - else: - actual = seq2.index(*index_args) - self.assertEqual( - actual, expected, '%r.index%s' % (seq1, index_args)) - - for ty in list, str: - nativeseq = ty('abracadabra') - indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) - seqseq = SequenceSubclass(nativeseq) - for letter in set(nativeseq) | {'z'}: - assert_index_same(nativeseq, seqseq, (letter,)) - for start in range(-3, len(nativeseq) + 3): - assert_index_same(nativeseq, seqseq, (letter, start)) - for stop in range(-3, len(nativeseq) + 3): - assert_index_same( - nativeseq, seqseq, (letter, start, stop)) - - def test_ByteString(self): - for sample in [bytes, bytearray]: - self.assertIsInstance(sample(), ByteString) - self.assertTrue(issubclass(sample, ByteString)) - for sample in [str, list, tuple]: - self.assertNotIsInstance(sample(), ByteString) - self.assertFalse(issubclass(sample, ByteString)) - self.assertNotIsInstance(memoryview(b""), ByteString) - self.assertFalse(issubclass(memoryview, ByteString)) - - def test_MutableSequence(self): - for sample in [tuple, str, bytes]: - self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list, bytearray, deque]: - self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(str, MutableSequence)) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') - - def test_MutableSequence_mixins(self): - # Test the mixins of MutableSequence by creating a miminal concrete - # class inherited from it. - class MutableSequenceSubclass(MutableSequence): - def __init__(self): - self.lst = [] - - def __setitem__(self, index, value): - self.lst[index] = value - - def __getitem__(self, index): - return self.lst[index] - - def __len__(self): - return len(self.lst) - - def __delitem__(self, index): - del self.lst[index] - - def insert(self, index, value): - self.lst.insert(index, value) - - mss = MutableSequenceSubclass() - mss.append(0) - mss.extend((1, 2, 3, 4)) - self.assertEqual(len(mss), 5) - self.assertEqual(mss[3], 3) - mss.reverse() - self.assertEqual(mss[3], 1) - mss.pop() - self.assertEqual(len(mss), 4) - mss.remove(3) - self.assertEqual(len(mss), 3) - mss += (10, 20, 30) - self.assertEqual(len(mss), 6) - self.assertEqual(mss[-1], 30) - mss.clear() - self.assertEqual(len(mss), 0) - -################################################################################ -### Counter -################################################################################ - -class CounterSubclassWithSetItem(Counter): - # Test a counter subclass that overrides __setitem__ - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def __setitem__(self, key, value): - self.called = True - Counter.__setitem__(self, key, value) - -class CounterSubclassWithGet(Counter): - # Test a counter subclass that overrides get() - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def get(self, key, default): - self.called = True - return Counter.get(self, key, default) - -class TestCounter(unittest.TestCase): - - def test_basics(self): - c = Counter('abcaba') - self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) - self.assertEqual(c, Counter(a=3, b=2, c=1)) - self.assertIsInstance(c, dict) - self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) - self.assertEqual(len(c), 3) - self.assertEqual(sum(c.values()), 6) - self.assertEqual(sorted(c.values()), [1, 2, 3]) - self.assertEqual(sorted(c.keys()), ['a', 'b', 'c']) - self.assertEqual(sorted(c), ['a', 'b', 'c']) - self.assertEqual(sorted(c.items()), - [('a', 3), ('b', 2), ('c', 1)]) - self.assertEqual(c['b'], 2) - self.assertEqual(c['z'], 0) - self.assertEqual(c.__contains__('c'), True) - self.assertEqual(c.__contains__('z'), False) - self.assertEqual(c.get('b', 10), 2) - self.assertEqual(c.get('z', 10), 10) - self.assertEqual(c, dict(a=3, b=2, c=1)) - self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") - self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) - for i in range(5): - self.assertEqual(c.most_common(i), - [('a', 3), ('b', 2), ('c', 1)][:i]) - self.assertEqual(''.join(sorted(c.elements())), 'aaabbc') - c['a'] += 1 # increment an existing value - c['b'] -= 2 # sub existing value to zero - del c['c'] # remove an entry - del c['c'] # make sure that del doesn't raise KeyError - c['d'] -= 2 # sub from a missing value - c['e'] = -5 # directly assign a missing value - c['f'] += 4 # add to a missing value - self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) - self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff') - self.assertEqual(c.pop('f'), 4) - self.assertNotIn('f', c) - for i in range(3): - elem, cnt = c.popitem() - self.assertNotIn(elem, c) - c.clear() - self.assertEqual(c, {}) - self.assertEqual(repr(c), 'Counter()') - self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') - self.assertRaises(TypeError, hash, c) - c.update(dict(a=5, b=3)) - c.update(c=1) - c.update(Counter('a' * 50 + 'b' * 30)) - c.update() # test case with no args - c.__init__('a' * 500 + 'b' * 300) - c.__init__('cdc') - c.__init__() - self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) - self.assertEqual(c.setdefault('d', 5), 1) - self.assertEqual(c['d'], 1) - self.assertEqual(c.setdefault('e', 5), 5) - self.assertEqual(c['e'], 5) - - def test_init(self): - self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) - self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) - self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter, 42) - self.assertRaises(TypeError, Counter, (), ()) - self.assertRaises(TypeError, Counter.__init__) - - def test_update(self): - c = Counter() - c.update(self=42) - self.assertEqual(list(c.items()), [('self', 42)]) - c = Counter() - c.update(iterable=42) - self.assertEqual(list(c.items()), [('iterable', 42)]) - c = Counter() - c.update(iterable=None) - self.assertEqual(list(c.items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter().update, 42) - self.assertRaises(TypeError, Counter().update, {}, {}) - self.assertRaises(TypeError, Counter.update) - - def test_copying(self): - # Check that counters are copyable, deepcopyable, picklable, and - #have a repr/eval round-trip - words = Counter('which witch had which witches wrist watch'.split()) - def check(dup): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) - check(words.copy()) - check(copy.copy(words)) - check(copy.deepcopy(words)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(words, proto))) - check(eval(repr(words))) - update_test = Counter() - update_test.update(words) - check(update_test) - check(Counter(words)) - - def test_copy_subclass(self): - class MyCounter(Counter): - pass - c = MyCounter('slartibartfast') - d = c.copy() - self.assertEqual(d, c) - self.assertEqual(len(d), len(c)) - self.assertEqual(type(d), type(c)) - - def test_conversions(self): - # Convert to: set, list, dict - s = 'she sells sea shells by the sea shore' - self.assertEqual(sorted(Counter(s).elements()), sorted(s)) - self.assertEqual(sorted(Counter(s)), sorted(set(s))) - self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) - self.assertEqual(set(Counter(s)), set(s)) - - def test_invariant_for_the_in_operator(self): - c = Counter(a=10, b=-2, c=0) - for elem in c: - self.assertTrue(elem in c) - self.assertIn(elem, c) - - def test_multiset_operations(self): - # Verify that adding a zero counter will strip zeros and negatives - c = Counter(a=10, b=-2, c=0) + Counter() - self.assertEqual(dict(c), dict(a=10)) - - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for counterop, numberop in [ - (Counter.__add__, lambda x, y: max(0, x+y)), - (Counter.__sub__, lambda x, y: max(0, x-y)), - (Counter.__or__, lambda x, y: max(0,x,y)), - (Counter.__and__, lambda x, y: max(0, min(x,y))), - ]: - result = counterop(p, q) - for x in elements: - self.assertEqual(numberop(p[x], q[x]), result[x], - (counterop, x, p, q)) - # verify that results exclude non-positive counts - self.assertTrue(x>0 for x in result.values()) - - elements = 'abcdef' - for i in range(100): - # verify that random multisets with no repeats are exactly like sets - p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - for counterop, setop in [ - (Counter.__sub__, set.__sub__), - (Counter.__or__, set.__or__), - (Counter.__and__, set.__and__), - ]: - counter_result = counterop(p, q) - set_result = setop(set(p.elements()), set(q.elements())) - self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) - - def test_inplace_operations(self): - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for inplace_op, regular_op in [ - (Counter.__iadd__, Counter.__add__), - (Counter.__isub__, Counter.__sub__), - (Counter.__ior__, Counter.__or__), - (Counter.__iand__, Counter.__and__), - ]: - c = p.copy() - c_id = id(c) - regular_result = regular_op(c, q) - inplace_result = inplace_op(c, q) - self.assertEqual(inplace_result, regular_result) - self.assertEqual(id(inplace_result), c_id) - - def test_subtract(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter('aaabbcd') - c.subtract('aaaabbcce') - self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) - - c = Counter() - c.subtract(self=42) - self.assertEqual(list(c.items()), [('self', -42)]) - c = Counter() - c.subtract(iterable=42) - self.assertEqual(list(c.items()), [('iterable', -42)]) - self.assertRaises(TypeError, Counter().subtract, 42) - self.assertRaises(TypeError, Counter().subtract, {}, {}) - self.assertRaises(TypeError, Counter.subtract) - - def test_unary(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) - self.assertEqual(dict(-c), dict(a=5)) - - def test_repr_nonsortable(self): - c = Counter(a=2, b=None) - r = repr(c) - self.assertIn("'a': 2", r) - self.assertIn("'b': None", r) - - def test_helper_function(self): - # two paths, one for real dicts and one for other mappings - elems = list('abracadabra') - - d = dict() - _count_elements(d, elems) - self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) - - m = OrderedDict() - _count_elements(m, elems) - self.assertEqual(m, - OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) - - # test fidelity to the pure python version - c = CounterSubclassWithSetItem('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - c = CounterSubclassWithGet('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - - -################################################################################ -### OrderedDict -################################################################################ - -py_coll = import_fresh_module('collections', blocked=['_collections']) -c_coll = import_fresh_module('collections', fresh=['_collections']) +py_coll = support.import_fresh_module('collections', blocked=['_collections']) +c_coll = support.import_fresh_module('collections', fresh=['_collections']) @contextlib.contextmanager @@ -2203,6 +587,7 @@ self.assertNotIn('NULL', repr(od)) def test_dict_update(self): + OrderedDict = self.OrderedDict od = OrderedDict() dict.update(od, [('spam', 1)]) self.assertNotIn('NULL', repr(od)) @@ -2302,26 +687,5 @@ self.assertRaises(KeyError, d.popitem) -################################################################################ -### Run tests -################################################################################ - -import doctest, collections - -def test_main(verbose=None): - NamedTupleDocs = doctest.DocTestSuite(module=collections) - test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, TestChainMap, - PurePythonOrderedDictTests, CPythonOrderedDictTests, - PurePythonOrderedDictSubclassTests, - CPythonOrderedDictSubclassTests, - PurePythonGeneralMappingTests, CPythonGeneralMappingTests, - PurePythonSubclassMappingTests, CPythonSubclassMappingTests, - TestUserObjects, - ] - support.run_unittest(*test_classes) - support.run_doctest(collections, verbose) - - if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -419,6 +419,9 @@ Tests ----- +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + - Issue #25449: Added tests for OrderedDict subclasses. - Issue #25188: Add -P/--pgo to test.regrtest to suppress error output when -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 10:20:08 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 15:20:08 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325616=3A_Tests_for_OrderedDict_are_extracted_from_tes?= =?utf-8?q?t=5Fcollections?= Message-ID: <20151125151954.13431.70909@psf.io> https://hg.python.org/cpython/rev/46e95e0eaae5 changeset: 99353:46e95e0eaae5 branch: 3.5 parent: 99348:9925fb41c1d9 parent: 99352:8d9a0540adf9 user: Serhiy Storchaka date: Wed Nov 25 17:12:02 2015 +0200 summary: Issue #25616: Tests for OrderedDict are extracted from test_collections into separate file test_ordered_dict. files: Lib/test/test_collections.py | 707 +-------- Lib/test/test_ordered_dict.py | 1660 +-------------------- Misc/NEWS | 6 + 3 files changed, 32 insertions(+), 2341 deletions(-) diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -1,18 +1,21 @@ """Unit tests for collections.py.""" -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink, import_fresh_module -import contextlib +import collections +import copy +import doctest import inspect +import keyword +import operator +import pickle +from random import choice, randrange +import re +import string +import sys from test import support +import types +import unittest + from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -import types from collections import UserDict, UserString, UserList from collections import ChainMap from collections import deque @@ -313,8 +316,7 @@ # n = 5000 n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) + names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) Big = namedtuple('Big', names) @@ -1621,694 +1623,13 @@ ################################################################################ -### OrderedDict -################################################################################ - -py_coll = import_fresh_module('collections', blocked=['_collections']) -c_coll = import_fresh_module('collections', fresh=['_collections']) - - - at contextlib.contextmanager -def replaced_module(name, replacement): - original_module = sys.modules[name] - sys.modules[name] = replacement - try: - yield - finally: - sys.modules[name] = original_module - - -class OrderedDictTests: - - def test_init(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - self.assertEqual(sorted(OrderedDict(dict(pairs)).items()), pairs) # dict input - self.assertEqual(sorted(OrderedDict(**dict(pairs)).items()), pairs) # kwds input - self.assertEqual(list(OrderedDict(pairs).items()), pairs) # pairs input - self.assertEqual(list(OrderedDict([('a', 1), ('b', 2), ('c', 9), ('d', 4)], - c=3, e=5).items()), pairs) # mixed input - - # make sure no positional args conflict with possible kwdargs - self.assertEqual(list(OrderedDict(self=42).items()), [('self', 42)]) - self.assertEqual(list(OrderedDict(other=42).items()), [('other', 42)]) - self.assertRaises(TypeError, OrderedDict, 42) - self.assertRaises(TypeError, OrderedDict, (), ()) - self.assertRaises(TypeError, OrderedDict.__init__) - - # Make sure that direct calls to __init__ do not clear previous contents - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.__init__([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - def test_update(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict().update([('a', 1), ('b', 2)], None) # too many args - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict() - od.update(dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # dict input - od = OrderedDict() - od.update(**dict(pairs)) - self.assertEqual(sorted(od.items()), pairs) # kwds input - od = OrderedDict() - od.update(pairs) - self.assertEqual(list(od.items()), pairs) # pairs input - od = OrderedDict() - od.update([('a', 1), ('b', 2), ('c', 9), ('d', 4)], c=3, e=5) - self.assertEqual(list(od.items()), pairs) # mixed input - - # Issue 9137: Named argument called 'other' or 'self' - # shouldn't be treated specially. - od = OrderedDict() - od.update(self=23) - self.assertEqual(list(od.items()), [('self', 23)]) - od = OrderedDict() - od.update(other={}) - self.assertEqual(list(od.items()), [('other', {})]) - od = OrderedDict() - od.update(red=5, blue=6, other=7, self=8) - self.assertEqual(sorted(list(od.items())), - [('blue', 6), ('other', 7), ('red', 5), ('self', 8)]) - - # Make sure that direct calls to update do not clear previous contents - # add that updates items are not moved to the end - d = OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 44), ('e', 55)]) - d.update([('e', 5), ('f', 6)], g=7, d=4) - self.assertEqual(list(d.items()), - [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('g', 7)]) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - self.assertRaises(TypeError, OrderedDict().update, 42) - self.assertRaises(TypeError, OrderedDict().update, (), ()) - self.assertRaises(TypeError, OrderedDict.update) - - def test_fromkeys(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) - od = OrderedDict.fromkeys('abc', value=None) - self.assertEqual(list(od.items()), [(c, None) for c in 'abc']) - od = OrderedDict.fromkeys('abc', value=0) - self.assertEqual(list(od.items()), [(c, 0) for c in 'abc']) - - def test_abc(self): - OrderedDict = self.OrderedDict - self.assertIsInstance(OrderedDict(), MutableMapping) - self.assertTrue(issubclass(OrderedDict, MutableMapping)) - - def test_clear(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(len(od), len(pairs)) - od.clear() - self.assertEqual(len(od), 0) - - def test_delitem(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - del od['a'] - self.assertNotIn('a', od) - with self.assertRaises(KeyError): - del od['a'] - self.assertEqual(list(od.items()), pairs[:2] + pairs[3:]) - - def test_setitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict([('d', 1), ('b', 2), ('c', 3), ('a', 4), ('e', 5)]) - od['c'] = 10 # existing element - od['f'] = 20 # new element - self.assertEqual(list(od.items()), - [('d', 1), ('b', 2), ('c', 10), ('a', 4), ('e', 5), ('f', 20)]) - - def test_iterators(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - self.assertEqual(list(od), [t[0] for t in pairs]) - self.assertEqual(list(od.keys()), [t[0] for t in pairs]) - self.assertEqual(list(od.values()), [t[1] for t in pairs]) - self.assertEqual(list(od.items()), pairs) - self.assertEqual(list(reversed(od)), - [t[0] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.keys())), - [t[0] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.values())), - [t[1] for t in reversed(pairs)]) - self.assertEqual(list(reversed(od.items())), list(reversed(pairs))) - - def test_detect_deletion_during_iteration(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - it = iter(od) - key = next(it) - del od[key] - with self.assertRaises(Exception): - # Note, the exact exception raised is not guaranteed - # The only guarantee that the next() will not succeed - next(it) - - def test_sorted_iterators(self): - OrderedDict = self.OrderedDict - with self.assertRaises(TypeError): - OrderedDict([('a', 1), ('b', 2)], None) - pairs = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)] - od = OrderedDict(pairs) - self.assertEqual(sorted(od), [t[0] for t in pairs]) - self.assertEqual(sorted(od.keys()), [t[0] for t in pairs]) - self.assertEqual(sorted(od.values()), [t[1] for t in pairs]) - self.assertEqual(sorted(od.items()), pairs) - self.assertEqual(sorted(reversed(od)), - sorted([t[0] for t in reversed(pairs)])) - - def test_iterators_empty(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - empty = [] - self.assertEqual(list(od), empty) - self.assertEqual(list(od.keys()), empty) - self.assertEqual(list(od.values()), empty) - self.assertEqual(list(od.items()), empty) - self.assertEqual(list(reversed(od)), empty) - self.assertEqual(list(reversed(od.keys())), empty) - self.assertEqual(list(reversed(od.values())), empty) - self.assertEqual(list(reversed(od.items())), empty) - - def test_popitem(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - while pairs: - self.assertEqual(od.popitem(), pairs.pop()) - with self.assertRaises(KeyError): - od.popitem() - self.assertEqual(len(od), 0) - - def test_popitem_last(self): - OrderedDict = self.OrderedDict - pairs = [(i, i) for i in range(30)] - - obj = OrderedDict(pairs) - for i in range(8): - obj.popitem(True) - obj.popitem(True) - obj.popitem(last=True) - self.assertEqual(len(obj), 20) - - def test_pop(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - shuffle(pairs) - while pairs: - k, v = pairs.pop() - self.assertEqual(od.pop(k), v) - with self.assertRaises(KeyError): - od.pop('xyz') - self.assertEqual(len(od), 0) - self.assertEqual(od.pop(k, 12345), 12345) - - # make sure pop still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - m = Missing(a=1) - self.assertEqual(m.pop('b', 5), 5) - self.assertEqual(m.pop('a', 6), 1) - self.assertEqual(m.pop('a', 6), 6) - self.assertEqual(m.pop('a', default=6), 6) - with self.assertRaises(KeyError): - m.pop('a') - - def test_equality(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od1 = OrderedDict(pairs) - od2 = OrderedDict(pairs) - self.assertEqual(od1, od2) # same order implies equality - pairs = pairs[2:] + pairs[:2] - od2 = OrderedDict(pairs) - self.assertNotEqual(od1, od2) # different order implies inequality - # comparison to regular dict is not order sensitive - self.assertEqual(od1, dict(od2)) - self.assertEqual(dict(od2), od1) - # different length implied inequality - self.assertNotEqual(od1, OrderedDict(pairs[:-1])) - - def test_copying(self): - OrderedDict = self.OrderedDict - # Check that ordered dicts are copyable, deepcopyable, picklable, - # and have a repr/eval round-trip - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - def check(dup): - msg = "\ncopy: %s\nod: %s" % (dup, od) - self.assertIsNot(dup, od, msg) - self.assertEqual(dup, od) - self.assertEqual(list(dup.items()), list(od.items())) - self.assertEqual(len(dup), len(od)) - self.assertEqual(type(dup), type(od)) - check(od.copy()) - check(copy.copy(od)) - check(copy.deepcopy(od)) - # pickle directly pulls the module, so we have to fake it - with replaced_module('collections', self.module): - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(od, proto))) - check(eval(repr(od))) - update_test = OrderedDict() - update_test.update(od) - check(update_test) - check(OrderedDict(od)) - - def test_yaml_linkage(self): - OrderedDict = self.OrderedDict - # Verify that __reduce__ is setup in a way that supports PyYAML's dump() feature. - # In yaml, lists are native but tuples are not. - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - # yaml.dump(od) --> - # '!!python/object/apply:__main__.OrderedDict\n- - [a, 1]\n - [b, 2]\n' - self.assertTrue(all(type(pair)==list for pair in od.__reduce__()[1])) - - def test_reduce_not_too_fat(self): - OrderedDict = self.OrderedDict - # do not save instance dictionary if not needed - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - od = OrderedDict(pairs) - self.assertIsNone(od.__reduce__()[2]) - od.x = 10 - self.assertIsNotNone(od.__reduce__()[2]) - - def test_pickle_recursive(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od[1] = od - - # pickle directly pulls the module, so we have to fake it - with replaced_module('collections', self.module): - for proto in range(-1, pickle.HIGHEST_PROTOCOL + 1): - dup = pickle.loads(pickle.dumps(od, proto)) - self.assertIsNot(dup, od) - self.assertEqual(list(dup.keys()), [1]) - self.assertIs(dup[1], dup) - - def test_repr(self): - OrderedDict = self.OrderedDict - od = OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]) - self.assertEqual(repr(od), - "OrderedDict([('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)])") - self.assertEqual(eval(repr(od)), od) - self.assertEqual(repr(OrderedDict()), "OrderedDict()") - - def test_repr_recursive(self): - OrderedDict = self.OrderedDict - # See issue #9826 - od = OrderedDict.fromkeys('abc') - od['x'] = od - self.assertEqual(repr(od), - "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])") - - def test_setdefault(self): - OrderedDict = self.OrderedDict - pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)] - shuffle(pairs) - od = OrderedDict(pairs) - pair_order = list(od.items()) - self.assertEqual(od.setdefault('a', 10), 3) - # make sure order didn't change - self.assertEqual(list(od.items()), pair_order) - self.assertEqual(od.setdefault('x', 10), 10) - # make sure 'x' is added to the end - self.assertEqual(list(od.items())[-1], ('x', 10)) - self.assertEqual(od.setdefault('g', default=9), 9) - - # make sure setdefault still works when __missing__ is defined - class Missing(OrderedDict): - def __missing__(self, key): - return 0 - self.assertEqual(Missing().setdefault(5, 9), 9) - - def test_reinsert(self): - OrderedDict = self.OrderedDict - # Given insert a, insert b, delete a, re-insert a, - # verify that a is now later than b. - od = OrderedDict() - od['a'] = 1 - od['b'] = 2 - del od['a'] - self.assertEqual(list(od.items()), [('b', 2)]) - od['a'] = 1 - self.assertEqual(list(od.items()), [('b', 2), ('a', 1)]) - - def test_move_to_end(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - od.move_to_end('c') - self.assertEqual(list(od), list('abdec')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('c', 0) - self.assertEqual(list(od), list('cabde')) - od.move_to_end('e') - self.assertEqual(list(od), list('cabde')) - od.move_to_end('b', last=False) - self.assertEqual(list(od), list('bcade')) - with self.assertRaises(KeyError): - od.move_to_end('x') - with self.assertRaises(KeyError): - od.move_to_end('x', 0) - - def test_move_to_end_issue25406(self): - OrderedDict = self.OrderedDict - od = OrderedDict.fromkeys('abc') - od.move_to_end('c', last=False) - self.assertEqual(list(od), list('cab')) - od.move_to_end('a', last=False) - self.assertEqual(list(od), list('acb')) - - od = OrderedDict.fromkeys('abc') - od.move_to_end('a') - self.assertEqual(list(od), list('bca')) - od.move_to_end('c') - self.assertEqual(list(od), list('bac')) - - def test_sizeof(self): - OrderedDict = self.OrderedDict - # Wimpy test: Just verify the reported size is larger than a regular dict - d = dict(a=1) - od = OrderedDict(**d) - self.assertGreater(sys.getsizeof(od), sys.getsizeof(d)) - - def test_override_update(self): - OrderedDict = self.OrderedDict - # Verify that subclasses can override update() without breaking __init__() - class MyOD(OrderedDict): - def update(self, *args, **kwds): - raise Exception() - items = [('a', 1), ('c', 3), ('b', 2)] - self.assertEqual(list(MyOD(items).items()), items) - - def test_highly_nested(self): - # Issue 25395: crashes during garbage collection - OrderedDict = self.OrderedDict - obj = None - for _ in range(1000): - obj = OrderedDict([(None, obj)]) - del obj - support.gc_collect() - - def test_highly_nested_subclass(self): - # Issue 25395: crashes during garbage collection - OrderedDict = self.OrderedDict - deleted = [] - class MyOD(OrderedDict): - def __del__(self): - deleted.append(self.i) - obj = None - for i in range(100): - obj = MyOD([(None, obj)]) - obj.i = i - del obj - support.gc_collect() - self.assertEqual(deleted, list(reversed(range(100)))) - - def test_delitem_hash_collision(self): - OrderedDict = self.OrderedDict - - class Key: - def __init__(self, hash): - self._hash = hash - self.value = str(id(self)) - def __hash__(self): - return self._hash - def __eq__(self, other): - try: - return self.value == other.value - except AttributeError: - return False - def __repr__(self): - return self.value - - def blocking_hash(hash): - # See the collision-handling in lookdict (in Objects/dictobject.c). - MINSIZE = 8 - i = (hash & MINSIZE-1) - return (i << 2) + i + hash + 1 - - COLLIDING = 1 - - key = Key(COLLIDING) - colliding = Key(COLLIDING) - blocking = Key(blocking_hash(COLLIDING)) - - od = OrderedDict() - od[key] = ... - od[blocking] = ... - od[colliding] = ... - od['after'] = ... - - del od[blocking] - del od[colliding] - self.assertEqual(list(od.items()), [(key, ...), ('after', ...)]) - - def test_issue24347(self): - OrderedDict = self.OrderedDict - - class Key: - def __hash__(self): - return randrange(100000) - - od = OrderedDict() - for i in range(100): - key = Key() - od[key] = i - - # These should not crash. - with self.assertRaises(KeyError): - list(od.values()) - with self.assertRaises(KeyError): - list(od.items()) - with self.assertRaises(KeyError): - repr(od) - with self.assertRaises(KeyError): - od.copy() - - def test_issue24348(self): - OrderedDict = self.OrderedDict - - class Key: - def __hash__(self): - return 1 - - od = OrderedDict() - od[Key()] = 0 - # This should not crash. - od.popitem() - - def test_issue24667(self): - """ - dict resizes after a certain number of insertion operations, - whether or not there were deletions that freed up slots in the - hash table. During fast node lookup, OrderedDict must correctly - respond to all resizes, even if the current "size" is the same - as the old one. We verify that here by forcing a dict resize - on a sparse odict and then perform an operation that should - trigger an odict resize (e.g. popitem). One key aspect here is - that we will keep the size of the odict the same at each popitem - call. This verifies that we handled the dict resize properly. - """ - OrderedDict = self.OrderedDict - - od = OrderedDict() - for c0 in '0123456789ABCDEF': - for c1 in '0123456789ABCDEF': - if len(od) == 4: - # This should not raise a KeyError. - od.popitem(last=False) - key = c0 + c1 - od[key] = key - - # Direct use of dict methods - - def test_dict_setitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - dict.__setitem__(od, 'spam', 1) - self.assertNotIn('NULL', repr(od)) - - def test_dict_delitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.__delitem__(od, 'spam') - with self.assertRaises(KeyError): - repr(od) - - def test_dict_clear(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.clear(od) - self.assertNotIn('NULL', repr(od)) - - def test_dict_pop(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.pop(od, 'spam') - with self.assertRaises(KeyError): - repr(od) - - def test_dict_popitem(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - od['spam'] = 1 - od['ham'] = 2 - dict.popitem(od) - with self.assertRaises(KeyError): - repr(od) - - def test_dict_setdefault(self): - OrderedDict = self.OrderedDict - od = OrderedDict() - dict.setdefault(od, 'spam', 1) - self.assertNotIn('NULL', repr(od)) - - def test_dict_update(self): - od = OrderedDict() - dict.update(od, [('spam', 1)]) - self.assertNotIn('NULL', repr(od)) - - -class PurePythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = py_coll - OrderedDict = py_coll.OrderedDict - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonOrderedDictTests(OrderedDictTests, unittest.TestCase): - - module = c_coll - OrderedDict = c_coll.OrderedDict - - def test_key_change_during_iteration(self): - OrderedDict = self.OrderedDict - - od = OrderedDict.fromkeys('abcde') - self.assertEqual(list(od), list('abcde')) - with self.assertRaises(RuntimeError): - for i, k in enumerate(od): - od.move_to_end(k) - self.assertLess(i, 5) - with self.assertRaises(RuntimeError): - for k in od: - od['f'] = None - with self.assertRaises(RuntimeError): - for k in od: - del od['c'] - self.assertEqual(list(od), list('bdeaf')) - - -class PurePythonOrderedDictSubclassTests(PurePythonOrderedDictTests): - - module = py_coll - class OrderedDict(py_coll.OrderedDict): - pass - - -class CPythonOrderedDictSubclassTests(CPythonOrderedDictTests): - - module = c_coll - class OrderedDict(c_coll.OrderedDict): - pass - - -class PurePythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - cls.type2test = py_coll.OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonGeneralMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - cls.type2test = c_coll.OrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - -class PurePythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - class MyOrderedDict(py_coll.OrderedDict): - pass - cls.type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - - at unittest.skipUnless(c_coll, 'requires the C version of the collections module') -class CPythonSubclassMappingTests(mapping_tests.BasicTestMappingProtocol): - - @classmethod - def setUpClass(cls): - class MyOrderedDict(c_coll.OrderedDict): - pass - cls.type2test = MyOrderedDict - - def test_popitem(self): - d = self._empty_mapping() - self.assertRaises(KeyError, d.popitem) - - -################################################################################ ### Run tests ################################################################################ -import doctest, collections - def test_main(verbose=None): NamedTupleDocs = doctest.DocTestSuite(module=collections) test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, TestCollectionABCs, TestCounter, TestChainMap, - PurePythonOrderedDictTests, CPythonOrderedDictTests, - PurePythonOrderedDictSubclassTests, - CPythonOrderedDictSubclassTests, - PurePythonGeneralMappingTests, CPythonGeneralMappingTests, - PurePythonSubclassMappingTests, CPythonSubclassMappingTests, TestUserObjects, ] support.run_unittest(*test_classes) diff --git a/Lib/test/test_collections.py b/Lib/test/test_ordered_dict.py copy from Lib/test/test_collections.py copy to Lib/test/test_ordered_dict.py --- a/Lib/test/test_collections.py +++ b/Lib/test/test_ordered_dict.py @@ -1,1631 +1,15 @@ -"""Unit tests for collections.py.""" +import contextlib +import copy +import pickle +from random import randrange, shuffle +import sys +import unittest +from collections.abc import MutableMapping +from test import mapping_tests, support -import unittest, doctest, operator -from test.support import TESTFN, forget, unlink, import_fresh_module -import contextlib -import inspect -from test import support -from collections import namedtuple, Counter, OrderedDict, _count_elements -from test import mapping_tests -import pickle, copy -from random import randrange, shuffle -import keyword -import re -import sys -import types -from collections import UserDict, UserString, UserList -from collections import ChainMap -from collections import deque -from collections.abc import Awaitable, Coroutine, AsyncIterator, AsyncIterable -from collections.abc import Hashable, Iterable, Iterator, Generator -from collections.abc import Sized, Container, Callable -from collections.abc import Set, MutableSet -from collections.abc import Mapping, MutableMapping, KeysView, ItemsView -from collections.abc import Sequence, MutableSequence -from collections.abc import ByteString - -class TestUserObjects(unittest.TestCase): - def _superset_test(self, a, b): - self.assertGreaterEqual( - set(dir(a)), - set(dir(b)), - '{a} should have all the methods of {b}'.format( - a=a.__name__, - b=b.__name__, - ), - ) - def test_str_protocol(self): - self._superset_test(UserString, str) - - def test_list_protocol(self): - self._superset_test(UserList, list) - - def test_dict_protocol(self): - self._superset_test(UserDict, dict) - - -################################################################################ -### ChainMap (helper class for configparser and the string module) -################################################################################ - -class TestChainMap(unittest.TestCase): - - def test_basics(self): - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - d = c.new_child() - d['b'] = 20 - d['c'] = 30 - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=20, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=20, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - del d['b'] # unmask a value - self.assertEqual(d.maps, [{'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertEqual(d.items(), dict(a=1, b=2, c=30).items()) # check items/iter/getitem - self.assertEqual(len(d), 3) # check len - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, b=2, c=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - self.assertIn(repr(d), [ # check repr - type(d).__name__ + "({'c': 30}, {'a': 1, 'b': 2})", - type(d).__name__ + "({'c': 30}, {'b': 2, 'a': 1})" - ]) - - for e in d.copy(), copy.copy(d): # check shallow copies - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - self.assertIsNot(d.maps[0], e.maps[0]) - for m1, m2 in zip(d.maps[1:], e.maps[1:]): - self.assertIs(m1, m2) - - # check deep copies - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - e = pickle.loads(pickle.dumps(d, proto)) - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - for e in [copy.deepcopy(d), - eval(repr(d)) - ]: - self.assertEqual(d, e) - self.assertEqual(d.maps, e.maps) - self.assertIsNot(d, e) - for m1, m2 in zip(d.maps, e.maps): - self.assertIsNot(m1, m2, e) - - f = d.new_child() - f['b'] = 5 - self.assertEqual(f.maps, [{'b': 5}, {'c':30}, {'a':1, 'b':2}]) - self.assertEqual(f.parents.maps, [{'c':30}, {'a':1, 'b':2}]) # check parents - self.assertEqual(f['b'], 5) # find first in chain - self.assertEqual(f.parents['b'], 2) # look beyond maps[0] - - def test_contructor(self): - self.assertEqual(ChainMap().maps, [{}]) # no-args --> one new dict - self.assertEqual(ChainMap({1:2}).maps, [{1:2}]) # 1 arg --> list - - def test_bool(self): - self.assertFalse(ChainMap()) - self.assertFalse(ChainMap({}, {})) - self.assertTrue(ChainMap({1:2}, {})) - self.assertTrue(ChainMap({}, {1:2})) - - def test_missing(self): - class DefaultChainMap(ChainMap): - def __missing__(self, key): - return 999 - d = DefaultChainMap(dict(a=1, b=2), dict(b=20, c=30)) - for k, v in dict(a=1, b=2, c=30, d=999).items(): - self.assertEqual(d[k], v) # check __getitem__ w/missing - for k, v in dict(a=1, b=2, c=30, d=77).items(): - self.assertEqual(d.get(k, 77), v) # check get() w/ missing - for k, v in dict(a=True, b=True, c=True, d=False).items(): - self.assertEqual(k in d, v) # check __contains__ w/missing - self.assertEqual(d.pop('a', 1001), 1, d) - self.assertEqual(d.pop('a', 1002), 1002) # check pop() w/missing - self.assertEqual(d.popitem(), ('b', 2)) # check popitem() w/missing - with self.assertRaises(KeyError): - d.popitem() - - def test_dict_coercion(self): - d = ChainMap(dict(a=1, b=2), dict(b=20, c=30)) - self.assertEqual(dict(d), dict(a=1, b=2, c=30)) - self.assertEqual(dict(d.items()), dict(a=1, b=2, c=30)) - - def test_new_child(self): - 'Tests for changes for issue #16613.' - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = {'b':20, 'c': 30} - d = c.new_child(m) - self.assertEqual(d.maps, [{'b':20, 'c':30}, {'a':1, 'b':2}]) # check internal state - self.assertIs(m, d.maps[0]) - - # Use a different map than a dict - class lowerdict(dict): - def __getitem__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__getitem__(self, key) - def __contains__(self, key): - if isinstance(key, str): - key = key.lower() - return dict.__contains__(self, key) - - c = ChainMap() - c['a'] = 1 - c['b'] = 2 - m = lowerdict(b=20, c=30) - d = c.new_child(m) - self.assertIs(m, d.maps[0]) - for key in 'abc': # check contains - self.assertIn(key, d) - for k, v in dict(a=1, B=20, C=30, z=100).items(): # check get - self.assertEqual(d.get(k, 100), v) - - -################################################################################ -### Named Tuples -################################################################################ - -TestNT = namedtuple('TestNT', 'x y z') # type used for pickle tests - -class TestNamedTuple(unittest.TestCase): - - def test_factory(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__name__, 'Point') - self.assertEqual(Point.__slots__, ()) - self.assertEqual(Point.__module__, __name__) - self.assertEqual(Point.__getitem__, tuple.__getitem__) - self.assertEqual(Point._fields, ('x', 'y')) - self.assertIn('class Point(tuple)', Point._source) - - self.assertRaises(ValueError, namedtuple, 'abc%', 'efg ghi') # type has non-alpha char - self.assertRaises(ValueError, namedtuple, 'class', 'efg ghi') # type has keyword - self.assertRaises(ValueError, namedtuple, '9abc', 'efg ghi') # type starts with digit - - self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char - self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword - self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit - self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore - self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field - - namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names - namedtuple('_', 'a b c') # Test leading underscores in a typename - - nt = namedtuple('nt', 'the quick brown fox') # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - nt = namedtuple('nt', ('the', 'quick')) # check unicode input - self.assertNotIn("u'", repr(nt._fields)) - - self.assertRaises(TypeError, Point._make, [11]) # catch too few args - self.assertRaises(TypeError, Point._make, [11, 22, 33]) # catch too many args - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_factory_doc_attr(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.__doc__, 'Point(x, y)') - - @unittest.skipIf(sys.flags.optimize >= 2, - "Docstrings are omitted with -O2 and above") - def test_doc_writable(self): - Point = namedtuple('Point', 'x y') - self.assertEqual(Point.x.__doc__, 'Alias for field number 0') - Point.x.__doc__ = 'docstring for Point.x' - self.assertEqual(Point.x.__doc__, 'docstring for Point.x') - - def test_name_fixer(self): - for spec, renamed in [ - [('efg', 'g%hi'), ('efg', '_1')], # field with non-alpha char - [('abc', 'class'), ('abc', '_1')], # field has keyword - [('8efg', '9ghi'), ('_0', '_1')], # field starts with digit - [('abc', '_efg'), ('abc', '_1')], # field with leading underscore - [('abc', 'efg', 'efg', 'ghi'), ('abc', 'efg', '_2', 'ghi')], # duplicate field - [('abc', '', 'x'), ('abc', '_1', 'x')], # fieldname is a space - ]: - self.assertEqual(namedtuple('NT', spec, rename=True)._fields, renamed) - - def test_instance(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - self.assertEqual(p, Point(x=11, y=22)) - self.assertEqual(p, Point(11, y=22)) - self.assertEqual(p, Point(y=22, x=11)) - self.assertEqual(p, Point(*(11, 22))) - self.assertEqual(p, Point(**dict(x=11, y=22))) - self.assertRaises(TypeError, Point, 1) # too few args - self.assertRaises(TypeError, Point, 1, 2, 3) # too many args - self.assertRaises(TypeError, eval, 'Point(XXX=1, y=2)', locals()) # wrong keyword argument - self.assertRaises(TypeError, eval, 'Point(x=1)', locals()) # missing keyword argument - self.assertEqual(repr(p), 'Point(x=11, y=22)') - self.assertNotIn('__weakref__', dir(p)) - self.assertEqual(p, Point._make([11, 22])) # test _make classmethod - self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute - self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method - self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method - - try: - p._replace(x=1, error=2) - except ValueError: - pass - else: - self._fail('Did not detect an incorrect fieldname') - - # verify that field string can have commas - Point = namedtuple('Point', 'x, y') - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - # verify that fieldspec can be a non-string sequence - Point = namedtuple('Point', ('x', 'y')) - p = Point(x=11, y=22) - self.assertEqual(repr(p), 'Point(x=11, y=22)') - - def test_tupleness(self): - Point = namedtuple('Point', 'x y') - p = Point(11, 22) - - self.assertIsInstance(p, tuple) - self.assertEqual(p, (11, 22)) # matches a real tuple - self.assertEqual(tuple(p), (11, 22)) # coercable to a real tuple - self.assertEqual(list(p), [11, 22]) # coercable to a list - self.assertEqual(max(p), 22) # iterable - self.assertEqual(max(*p), 22) # star-able - x, y = p - self.assertEqual(p, (x, y)) # unpacks like a tuple - self.assertEqual((p[0], p[1]), (11, 22)) # indexable like a tuple - self.assertRaises(IndexError, p.__getitem__, 3) - - self.assertEqual(p.x, x) - self.assertEqual(p.y, y) - self.assertRaises(AttributeError, eval, 'p.z', locals()) - - def test_odd_sizes(self): - Zero = namedtuple('Zero', '') - self.assertEqual(Zero(), ()) - self.assertEqual(Zero._make([]), ()) - self.assertEqual(repr(Zero()), 'Zero()') - self.assertEqual(Zero()._asdict(), {}) - self.assertEqual(Zero()._fields, ()) - - Dot = namedtuple('Dot', 'd') - self.assertEqual(Dot(1), (1,)) - self.assertEqual(Dot._make([1]), (1,)) - self.assertEqual(Dot(1).d, 1) - self.assertEqual(repr(Dot(1)), 'Dot(d=1)') - self.assertEqual(Dot(1)._asdict(), {'d':1}) - self.assertEqual(Dot(1)._replace(d=999), (999,)) - self.assertEqual(Dot(1)._fields, ('d',)) - - # n = 5000 - n = 254 # SyntaxError: more than 255 arguments: - import string, random - names = list(set(''.join([random.choice(string.ascii_letters) - for j in range(10)]) for i in range(n))) - n = len(names) - Big = namedtuple('Big', names) - b = Big(*range(n)) - self.assertEqual(b, tuple(range(n))) - self.assertEqual(Big._make(range(n)), tuple(range(n))) - for pos, name in enumerate(names): - self.assertEqual(getattr(b, name), pos) - repr(b) # make sure repr() doesn't blow-up - d = b._asdict() - d_expected = dict(zip(names, range(n))) - self.assertEqual(d, d_expected) - b2 = b._replace(**dict([(names[1], 999),(names[-5], 42)])) - b2_expected = list(range(n)) - b2_expected[1] = 999 - b2_expected[-5] = 42 - self.assertEqual(b2, tuple(b2_expected)) - self.assertEqual(b._fields, tuple(names)) - - def test_pickle(self): - p = TestNT(x=10, y=20, z=30) - for module in (pickle,): - loads = getattr(module, 'loads') - dumps = getattr(module, 'dumps') - for protocol in range(-1, module.HIGHEST_PROTOCOL + 1): - q = loads(dumps(p, protocol)) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - self.assertNotIn(b'OrderedDict', dumps(p, protocol)) - - def test_copy(self): - p = TestNT(x=10, y=20, z=30) - for copier in copy.copy, copy.deepcopy: - q = copier(p) - self.assertEqual(p, q) - self.assertEqual(p._fields, q._fields) - - def test_name_conflicts(self): - # Some names like "self", "cls", "tuple", "itemgetter", and "property" - # failed when used as field names. Test to make sure these now work. - T = namedtuple('T', 'itemgetter property self cls tuple') - t = T(1, 2, 3, 4, 5) - self.assertEqual(t, (1,2,3,4,5)) - newt = t._replace(itemgetter=10, property=20, self=30, cls=40, tuple=50) - self.assertEqual(newt, (10,20,30,40,50)) - - # Broader test of all interesting names in a template - with support.captured_stdout() as template: - T = namedtuple('T', 'x', verbose=True) - words = set(re.findall('[A-Za-z]+', template.getvalue())) - words -= set(keyword.kwlist) - T = namedtuple('T', words) - # test __new__ - values = tuple(range(len(words))) - t = T(*values) - self.assertEqual(t, values) - t = T(**dict(zip(T._fields, values))) - self.assertEqual(t, values) - # test _make - t = T._make(values) - self.assertEqual(t, values) - # exercise __repr__ - repr(t) - # test _asdict - self.assertEqual(t._asdict(), dict(zip(T._fields, values))) - # test _replace - t = T._make(values) - newvalues = tuple(v*10 for v in values) - newt = t._replace(**dict(zip(T._fields, newvalues))) - self.assertEqual(newt, newvalues) - # test _fields - self.assertEqual(T._fields, tuple(words)) - # test __getnewargs__ - self.assertEqual(t.__getnewargs__(), values) - - def test_repr(self): - with support.captured_stdout() as template: - A = namedtuple('A', 'x', verbose=True) - self.assertEqual(repr(A(1)), 'A(x=1)') - # repr should show the name of the subclass - class B(A): - pass - self.assertEqual(repr(B(1)), 'B(x=1)') - - def test_source(self): - # verify that _source can be run through exec() - tmp = namedtuple('NTColor', 'red green blue') - globals().pop('NTColor', None) # remove artifacts from other tests - exec(tmp._source, globals()) - self.assertIn('NTColor', globals()) - c = NTColor(10, 20, 30) - self.assertEqual((c.red, c.green, c.blue), (10, 20, 30)) - self.assertEqual(NTColor._fields, ('red', 'green', 'blue')) - globals().pop('NTColor', None) # clean-up after this test - - - def test_namedtuple_subclass_issue_24931(self): - class Point(namedtuple('_Point', ['x', 'y'])): - pass - - a = Point(3, 4) - self.assertEqual(a._asdict(), OrderedDict([('x', 3), ('y', 4)])) - - a.w = 5 - self.assertEqual(a.__dict__, {'w': 5}) - - -################################################################################ -### Abstract Base Classes -################################################################################ - -class ABCTestCase(unittest.TestCase): - - def validate_abstract_methods(self, abc, *names): - methodstubs = dict.fromkeys(names, lambda s, *args: 0) - - # everything should work will all required methods are present - C = type('C', (abc,), methodstubs) - C() - - # instantiation should fail if a required method is missing - for name in names: - stubs = methodstubs.copy() - del stubs[name] - C = type('C', (abc,), stubs) - self.assertRaises(TypeError, C, name) - - def validate_isinstance(self, abc, name): - stub = lambda s, *args: 0 - - C = type('C', (object,), {'__hash__': None}) - setattr(C, name, stub) - self.assertIsInstance(C(), abc) - self.assertTrue(issubclass(C, abc)) - - C = type('C', (object,), {'__hash__': None}) - self.assertNotIsInstance(C(), abc) - self.assertFalse(issubclass(C, abc)) - - def validate_comparison(self, instance): - ops = ['lt', 'gt', 'le', 'ge', 'ne', 'or', 'and', 'xor', 'sub'] - operators = {} - for op in ops: - name = '__' + op + '__' - operators[name] = getattr(operator, name) - - class Other: - def __init__(self): - self.right_side = False - def __eq__(self, other): - self.right_side = True - return True - __lt__ = __eq__ - __gt__ = __eq__ - __le__ = __eq__ - __ge__ = __eq__ - __ne__ = __eq__ - __ror__ = __eq__ - __rand__ = __eq__ - __rxor__ = __eq__ - __rsub__ = __eq__ - - for name, op in operators.items(): - if not hasattr(instance, name): - continue - other = Other() - op(instance, other) - self.assertTrue(other.right_side,'Right side not called for %s.%s' - % (type(instance), name)) - -class TestOneTrickPonyABCs(ABCTestCase): - - def test_Awaitable(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object()] - for x in non_samples: - self.assertNotIsInstance(x, Awaitable) - self.assertFalse(issubclass(type(x), Awaitable), repr(type(x))) - - samples = [Bar(), MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Awaitable. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Awaitable) - - c = new_coro() - self.assertIsInstance(c, Awaitable) - c.close() # awoid RuntimeWarning that coro() was not awaited - - class CoroLike: pass - Coroutine.register(CoroLike) - self.assertTrue(isinstance(CoroLike(), Awaitable)) - self.assertTrue(issubclass(CoroLike, Awaitable)) - CoroLike = None - support.gc_collect() # Kill CoroLike to clean-up ABCMeta cache - - def test_Coroutine(self): - def gen(): - yield - - @types.coroutine - def coro(): - yield - - async def new_coro(): - pass - - class Bar: - def __await__(self): - yield - - class MinimalCoro(Coroutine): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - def __await__(self): - yield - - non_samples = [None, int(), gen(), object(), Bar()] - for x in non_samples: - self.assertNotIsInstance(x, Coroutine) - self.assertFalse(issubclass(type(x), Coroutine), repr(type(x))) - - samples = [MinimalCoro()] - for x in samples: - self.assertIsInstance(x, Awaitable) - self.assertTrue(issubclass(type(x), Awaitable)) - - c = coro() - # Iterable coroutines (generators with CO_ITERABLE_COROUTINE - # flag don't have '__await__' method, hence can't be instances - # of Coroutine. Use inspect.isawaitable to detect them. - self.assertNotIsInstance(c, Coroutine) - - c = new_coro() - self.assertIsInstance(c, Coroutine) - c.close() # awoid RuntimeWarning that coro() was not awaited - - class CoroLike: - def send(self, value): - pass - def throw(self, typ, val=None, tb=None): - pass - def close(self): - pass - def __await__(self): - pass - self.assertTrue(isinstance(CoroLike(), Coroutine)) - self.assertTrue(issubclass(CoroLike, Coroutine)) - - class CoroLike: - def send(self, value): - pass - def close(self): - pass - def __await__(self): - pass - self.assertFalse(isinstance(CoroLike(), Coroutine)) - self.assertFalse(issubclass(CoroLike, Coroutine)) - - def test_Hashable(self): - # Check some non-hashables - non_samples = [bytearray(), list(), set(), dict()] - for x in non_samples: - self.assertNotIsInstance(x, Hashable) - self.assertFalse(issubclass(type(x), Hashable), repr(type(x))) - # Check some hashables - samples = [None, - int(), float(), complex(), - str(), - tuple(), frozenset(), - int, list, object, type, bytes() - ] - for x in samples: - self.assertIsInstance(x, Hashable) - self.assertTrue(issubclass(type(x), Hashable), repr(type(x))) - self.assertRaises(TypeError, Hashable) - # Check direct subclassing - class H(Hashable): - def __hash__(self): - return super().__hash__() - self.assertEqual(hash(H()), 0) - self.assertFalse(issubclass(int, H)) - self.validate_abstract_methods(Hashable, '__hash__') - self.validate_isinstance(Hashable, '__hash__') - - def test_AsyncIterable(self): - class AI: - async def __aiter__(self): - return self - self.assertTrue(isinstance(AI(), AsyncIterable)) - self.assertTrue(issubclass(AI, AsyncIterable)) - # Check some non-iterables - non_samples = [None, object, []] - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterable) - self.assertFalse(issubclass(type(x), AsyncIterable), repr(type(x))) - self.validate_abstract_methods(AsyncIterable, '__aiter__') - self.validate_isinstance(AsyncIterable, '__aiter__') - - def test_AsyncIterator(self): - class AI: - async def __aiter__(self): - return self - async def __anext__(self): - raise StopAsyncIteration - self.assertTrue(isinstance(AI(), AsyncIterator)) - self.assertTrue(issubclass(AI, AsyncIterator)) - non_samples = [None, object, []] - # Check some non-iterables - for x in non_samples: - self.assertNotIsInstance(x, AsyncIterator) - self.assertFalse(issubclass(type(x), AsyncIterator), repr(type(x))) - # Similarly to regular iterators (see issue 10565) - class AnextOnly: - async def __anext__(self): - raise StopAsyncIteration - self.assertNotIsInstance(AnextOnly(), AsyncIterator) - self.validate_abstract_methods(AsyncIterator, '__anext__', '__aiter__') - - def test_Iterable(self): - # Check some non-iterables - non_samples = [None, 42, 3.14, 1j] - for x in non_samples: - self.assertNotIsInstance(x, Iterable) - self.assertFalse(issubclass(type(x), Iterable), repr(type(x))) - # Check some iterables - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterable) - self.assertTrue(issubclass(type(x), Iterable), repr(type(x))) - # Check direct subclassing - class I(Iterable): - def __iter__(self): - return super().__iter__() - self.assertEqual(list(I()), []) - self.assertFalse(issubclass(str, I)) - self.validate_abstract_methods(Iterable, '__iter__') - self.validate_isinstance(Iterable, '__iter__') - - def test_Iterator(self): - non_samples = [None, 42, 3.14, 1j, b"", "", (), [], {}, set()] - for x in non_samples: - self.assertNotIsInstance(x, Iterator) - self.assertFalse(issubclass(type(x), Iterator), repr(type(x))) - samples = [iter(bytes()), iter(str()), - iter(tuple()), iter(list()), iter(dict()), - iter(set()), iter(frozenset()), - iter(dict().keys()), iter(dict().items()), - iter(dict().values()), - (lambda: (yield))(), - (x for x in []), - ] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertTrue(issubclass(type(x), Iterator), repr(type(x))) - self.validate_abstract_methods(Iterator, '__next__', '__iter__') - - # Issue 10565 - class NextOnly: - def __next__(self): - yield 1 - return - self.assertNotIsInstance(NextOnly(), Iterator) - - def test_Generator(self): - class NonGen1: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def throw(self, typ, val=None, tb=None): pass - - class NonGen2: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - - class NonGen3: - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - non_samples = [ - None, 42, 3.14, 1j, b"", "", (), [], {}, set(), - iter(()), iter([]), NonGen1(), NonGen2(), NonGen3()] - for x in non_samples: - self.assertNotIsInstance(x, Generator) - self.assertFalse(issubclass(type(x), Generator), repr(type(x))) - - class Gen: - def __iter__(self): return self - def __next__(self): return None - def close(self): pass - def send(self, value): return value - def throw(self, typ, val=None, tb=None): pass - - class MinimalGen(Generator): - def send(self, value): - return value - def throw(self, typ, val=None, tb=None): - super().throw(typ, val, tb) - - def gen(): - yield 1 - - samples = [gen(), (lambda: (yield))(), Gen(), MinimalGen()] - for x in samples: - self.assertIsInstance(x, Iterator) - self.assertIsInstance(x, Generator) - self.assertTrue(issubclass(type(x), Generator), repr(type(x))) - self.validate_abstract_methods(Generator, 'send', 'throw') - - # mixin tests - mgen = MinimalGen() - self.assertIs(mgen, iter(mgen)) - self.assertIs(mgen.send(None), next(mgen)) - self.assertEqual(2, mgen.send(2)) - self.assertIsNone(mgen.close()) - self.assertRaises(ValueError, mgen.throw, ValueError) - self.assertRaisesRegex(ValueError, "^huhu$", - mgen.throw, ValueError, ValueError("huhu")) - self.assertRaises(StopIteration, mgen.throw, StopIteration()) - - class FailOnClose(Generator): - def send(self, value): return value - def throw(self, *args): raise ValueError - - self.assertRaises(ValueError, FailOnClose().close) - - class IgnoreGeneratorExit(Generator): - def send(self, value): return value - def throw(self, *args): pass - - self.assertRaises(RuntimeError, IgnoreGeneratorExit().close) - - def test_Sized(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Sized) - self.assertFalse(issubclass(type(x), Sized), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), dict().values(), - ] - for x in samples: - self.assertIsInstance(x, Sized) - self.assertTrue(issubclass(type(x), Sized), repr(type(x))) - self.validate_abstract_methods(Sized, '__len__') - self.validate_isinstance(Sized, '__len__') - - def test_Container(self): - non_samples = [None, 42, 3.14, 1j, - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Container) - self.assertFalse(issubclass(type(x), Container), repr(type(x))) - samples = [bytes(), str(), - tuple(), list(), set(), frozenset(), dict(), - dict().keys(), dict().items(), - ] - for x in samples: - self.assertIsInstance(x, Container) - self.assertTrue(issubclass(type(x), Container), repr(type(x))) - self.validate_abstract_methods(Container, '__contains__') - self.validate_isinstance(Container, '__contains__') - - def test_Callable(self): - non_samples = [None, 42, 3.14, 1j, - "", b"", (), [], {}, set(), - (lambda: (yield))(), - (x for x in []), - ] - for x in non_samples: - self.assertNotIsInstance(x, Callable) - self.assertFalse(issubclass(type(x), Callable), repr(type(x))) - samples = [lambda: None, - type, int, object, - len, - list.append, [].append, - ] - for x in samples: - self.assertIsInstance(x, Callable) - self.assertTrue(issubclass(type(x), Callable), repr(type(x))) - self.validate_abstract_methods(Callable, '__call__') - self.validate_isinstance(Callable, '__call__') - - def test_direct_subclassing(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C(B): - pass - self.assertTrue(issubclass(C, B)) - self.assertFalse(issubclass(int, C)) - - def test_registration(self): - for B in Hashable, Iterable, Iterator, Sized, Container, Callable: - class C: - __hash__ = None # Make sure it isn't hashable by default - self.assertFalse(issubclass(C, B), B.__name__) - B.register(C) - self.assertTrue(issubclass(C, B)) - -class WithSet(MutableSet): - - def __init__(self, it=()): - self.data = set(it) - - def __len__(self): - return len(self.data) - - def __iter__(self): - return iter(self.data) - - def __contains__(self, item): - return item in self.data - - def add(self, item): - self.data.add(item) - - def discard(self, item): - self.data.discard(item) - -class TestCollectionABCs(ABCTestCase): - - # XXX For now, we only test some virtual inheritance properties. - # We should also test the proper behavior of the collection ABCs - # as real base classes or mix-in classes. - - def test_Set(self): - for sample in [set, frozenset]: - self.assertIsInstance(sample(), Set) - self.assertTrue(issubclass(sample, Set)) - self.validate_abstract_methods(Set, '__contains__', '__iter__', '__len__') - class MySet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - self.validate_comparison(MySet()) - - def test_hash_Set(self): - class OneTwoThreeSet(Set): - def __init__(self): - self.contents = [1, 2, 3] - def __contains__(self, x): - return x in self.contents - def __len__(self): - return len(self.contents) - def __iter__(self): - return iter(self.contents) - def __hash__(self): - return self._hash() - a, b = OneTwoThreeSet(), OneTwoThreeSet() - self.assertTrue(hash(a) == hash(b)) - - def test_isdisjoint_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((4, 5, 6)) - s3 = MySet((1, 5, 6)) - self.assertTrue(s1.isdisjoint(s2)) - self.assertFalse(s1.isdisjoint(s3)) - - def test_equality_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1,)) - s2 = MySet((1, 2)) - s3 = MySet((3, 4)) - s4 = MySet((3, 4)) - self.assertTrue(s2 > s1) - self.assertTrue(s1 < s2) - self.assertFalse(s2 <= s1) - self.assertFalse(s2 <= s3) - self.assertFalse(s1 >= s2) - self.assertEqual(s3, s4) - self.assertNotEqual(s2, s3) - - def test_arithmetic_Set(self): - class MySet(Set): - def __init__(self, itr): - self.contents = itr - def __contains__(self, x): - return x in self.contents - def __iter__(self): - return iter(self.contents) - def __len__(self): - return len([x for x in self.contents]) - s1 = MySet((1, 2, 3)) - s2 = MySet((3, 4, 5)) - s3 = s1 & s2 - self.assertEqual(s3, MySet((3,))) - - def test_MutableSet(self): - self.assertIsInstance(set(), MutableSet) - self.assertTrue(issubclass(set, MutableSet)) - self.assertNotIsInstance(frozenset(), MutableSet) - self.assertFalse(issubclass(frozenset, MutableSet)) - self.validate_abstract_methods(MutableSet, '__contains__', '__iter__', '__len__', - 'add', 'discard') - - def test_issue_5647(self): - # MutableSet.__iand__ mutated the set during iteration - s = WithSet('abcd') - s &= WithSet('cdef') # This used to fail - self.assertEqual(set(s), set('cd')) - - def test_issue_4920(self): - # MutableSet.pop() method did not work - class MySet(MutableSet): - __slots__=['__s'] - def __init__(self,items=None): - if items is None: - items=[] - self.__s=set(items) - def __contains__(self,v): - return v in self.__s - def __iter__(self): - return iter(self.__s) - def __len__(self): - return len(self.__s) - def add(self,v): - result=v not in self.__s - self.__s.add(v) - return result - def discard(self,v): - result=v in self.__s - self.__s.discard(v) - return result - def __repr__(self): - return "MySet(%s)" % repr(list(self)) - s = MySet([5,43,2,1]) - self.assertEqual(s.pop(), 1) - - def test_issue8750(self): - empty = WithSet() - full = WithSet(range(10)) - s = WithSet(full) - s -= s - self.assertEqual(s, empty) - s = WithSet(full) - s ^= s - self.assertEqual(s, empty) - s = WithSet(full) - s &= s - self.assertEqual(s, full) - s |= s - self.assertEqual(s, full) - - def test_issue16373(self): - # Recursion error comparing comparable and noncomparable - # Set instances - class MyComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - class MyNonComparableSet(Set): - def __contains__(self, x): - return False - def __len__(self): - return 0 - def __iter__(self): - return iter([]) - def __le__(self, x): - return NotImplemented - def __lt__(self, x): - return NotImplemented - - cs = MyComparableSet() - ncs = MyNonComparableSet() - self.assertFalse(ncs < cs) - self.assertTrue(ncs <= cs) - self.assertFalse(ncs > cs) - self.assertTrue(ncs >= cs) - - def assertSameSet(self, s1, s2): - # coerce both to a real set then check equality - self.assertSetEqual(set(s1), set(s2)) - - def test_Set_interoperability_with_real_sets(self): - # Issue: 8743 - class ListSet(Set): - def __init__(self, elements=()): - self.data = [] - for elem in elements: - if elem not in self.data: - self.data.append(elem) - def __contains__(self, elem): - return elem in self.data - def __iter__(self): - return iter(self.data) - def __len__(self): - return len(self.data) - def __repr__(self): - return 'Set({!r})'.format(self.data) - - r1 = set('abc') - r2 = set('bcd') - r3 = set('abcde') - f1 = ListSet('abc') - f2 = ListSet('bcd') - f3 = ListSet('abcde') - l1 = list('abccba') - l2 = list('bcddcb') - l3 = list('abcdeedcba') - - target = r1 & r2 - self.assertSameSet(f1 & f2, target) - self.assertSameSet(f1 & r2, target) - self.assertSameSet(r2 & f1, target) - self.assertSameSet(f1 & l2, target) - - target = r1 | r2 - self.assertSameSet(f1 | f2, target) - self.assertSameSet(f1 | r2, target) - self.assertSameSet(r2 | f1, target) - self.assertSameSet(f1 | l2, target) - - fwd_target = r1 - r2 - rev_target = r2 - r1 - self.assertSameSet(f1 - f2, fwd_target) - self.assertSameSet(f2 - f1, rev_target) - self.assertSameSet(f1 - r2, fwd_target) - self.assertSameSet(f2 - r1, rev_target) - self.assertSameSet(r1 - f2, fwd_target) - self.assertSameSet(r2 - f1, rev_target) - self.assertSameSet(f1 - l2, fwd_target) - self.assertSameSet(f2 - l1, rev_target) - - target = r1 ^ r2 - self.assertSameSet(f1 ^ f2, target) - self.assertSameSet(f1 ^ r2, target) - self.assertSameSet(r2 ^ f1, target) - self.assertSameSet(f1 ^ l2, target) - - # Don't change the following to use assertLess or other - # "more specific" unittest assertions. The current - # assertTrue/assertFalse style makes the pattern of test - # case combinations clear and allows us to know for sure - # the exact operator being invoked. - - # proper subset - self.assertTrue(f1 < f3) - self.assertFalse(f1 < f1) - self.assertFalse(f1 < f2) - self.assertTrue(r1 < f3) - self.assertFalse(r1 < f1) - self.assertFalse(r1 < f2) - self.assertTrue(r1 < r3) - self.assertFalse(r1 < r1) - self.assertFalse(r1 < r2) - with self.assertRaises(TypeError): - f1 < l3 - with self.assertRaises(TypeError): - f1 < l1 - with self.assertRaises(TypeError): - f1 < l2 - - # any subset - self.assertTrue(f1 <= f3) - self.assertTrue(f1 <= f1) - self.assertFalse(f1 <= f2) - self.assertTrue(r1 <= f3) - self.assertTrue(r1 <= f1) - self.assertFalse(r1 <= f2) - self.assertTrue(r1 <= r3) - self.assertTrue(r1 <= r1) - self.assertFalse(r1 <= r2) - with self.assertRaises(TypeError): - f1 <= l3 - with self.assertRaises(TypeError): - f1 <= l1 - with self.assertRaises(TypeError): - f1 <= l2 - - # proper superset - self.assertTrue(f3 > f1) - self.assertFalse(f1 > f1) - self.assertFalse(f2 > f1) - self.assertTrue(r3 > r1) - self.assertFalse(f1 > r1) - self.assertFalse(f2 > r1) - self.assertTrue(r3 > r1) - self.assertFalse(r1 > r1) - self.assertFalse(r2 > r1) - with self.assertRaises(TypeError): - f1 > l3 - with self.assertRaises(TypeError): - f1 > l1 - with self.assertRaises(TypeError): - f1 > l2 - - # any superset - self.assertTrue(f3 >= f1) - self.assertTrue(f1 >= f1) - self.assertFalse(f2 >= f1) - self.assertTrue(r3 >= r1) - self.assertTrue(f1 >= r1) - self.assertFalse(f2 >= r1) - self.assertTrue(r3 >= r1) - self.assertTrue(r1 >= r1) - self.assertFalse(r2 >= r1) - with self.assertRaises(TypeError): - f1 >= l3 - with self.assertRaises(TypeError): - f1 >=l1 - with self.assertRaises(TypeError): - f1 >= l2 - - # equality - self.assertTrue(f1 == f1) - self.assertTrue(r1 == f1) - self.assertTrue(f1 == r1) - self.assertFalse(f1 == f3) - self.assertFalse(r1 == f3) - self.assertFalse(f1 == r3) - self.assertFalse(f1 == l3) - self.assertFalse(f1 == l1) - self.assertFalse(f1 == l2) - - # inequality - self.assertFalse(f1 != f1) - self.assertFalse(r1 != f1) - self.assertFalse(f1 != r1) - self.assertTrue(f1 != f3) - self.assertTrue(r1 != f3) - self.assertTrue(f1 != r3) - self.assertTrue(f1 != l3) - self.assertTrue(f1 != l1) - self.assertTrue(f1 != l2) - - def test_Mapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), Mapping) - self.assertTrue(issubclass(sample, Mapping)) - self.validate_abstract_methods(Mapping, '__contains__', '__iter__', '__len__', - '__getitem__') - class MyMapping(Mapping): - def __len__(self): - return 0 - def __getitem__(self, i): - raise IndexError - def __iter__(self): - return iter(()) - self.validate_comparison(MyMapping()) - - def test_MutableMapping(self): - for sample in [dict]: - self.assertIsInstance(sample(), MutableMapping) - self.assertTrue(issubclass(sample, MutableMapping)) - self.validate_abstract_methods(MutableMapping, '__contains__', '__iter__', '__len__', - '__getitem__', '__setitem__', '__delitem__') - - def test_MutableMapping_subclass(self): - # Test issue 9214 - mymap = UserDict() - mymap['red'] = 5 - self.assertIsInstance(mymap.keys(), Set) - self.assertIsInstance(mymap.keys(), KeysView) - self.assertIsInstance(mymap.items(), Set) - self.assertIsInstance(mymap.items(), ItemsView) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.keys() | {'orange'} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), ['orange', 'red']) - - mymap = UserDict() - mymap['red'] = 5 - z = mymap.items() | {('orange', 3)} - self.assertIsInstance(z, set) - list(z) - mymap['blue'] = 7 # Shouldn't affect 'z' - self.assertEqual(sorted(z), [('orange', 3), ('red', 5)]) - - def test_Sequence(self): - for sample in [tuple, list, bytes, str]: - self.assertIsInstance(sample(), Sequence) - self.assertTrue(issubclass(sample, Sequence)) - self.assertIsInstance(range(10), Sequence) - self.assertTrue(issubclass(range, Sequence)) - self.assertIsInstance(memoryview(b""), Sequence) - self.assertTrue(issubclass(memoryview, Sequence)) - self.assertTrue(issubclass(str, Sequence)) - self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__', - '__getitem__') - - def test_Sequence_mixins(self): - class SequenceSubclass(Sequence): - def __init__(self, seq=()): - self.seq = seq - - def __getitem__(self, index): - return self.seq[index] - - def __len__(self): - return len(self.seq) - - # Compare Sequence.index() behavior to (list|str).index() behavior - def assert_index_same(seq1, seq2, index_args): - try: - expected = seq1.index(*index_args) - except ValueError: - with self.assertRaises(ValueError): - seq2.index(*index_args) - else: - actual = seq2.index(*index_args) - self.assertEqual( - actual, expected, '%r.index%s' % (seq1, index_args)) - - for ty in list, str: - nativeseq = ty('abracadabra') - indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3)) - seqseq = SequenceSubclass(nativeseq) - for letter in set(nativeseq) | {'z'}: - assert_index_same(nativeseq, seqseq, (letter,)) - for start in range(-3, len(nativeseq) + 3): - assert_index_same(nativeseq, seqseq, (letter, start)) - for stop in range(-3, len(nativeseq) + 3): - assert_index_same( - nativeseq, seqseq, (letter, start, stop)) - - def test_ByteString(self): - for sample in [bytes, bytearray]: - self.assertIsInstance(sample(), ByteString) - self.assertTrue(issubclass(sample, ByteString)) - for sample in [str, list, tuple]: - self.assertNotIsInstance(sample(), ByteString) - self.assertFalse(issubclass(sample, ByteString)) - self.assertNotIsInstance(memoryview(b""), ByteString) - self.assertFalse(issubclass(memoryview, ByteString)) - - def test_MutableSequence(self): - for sample in [tuple, str, bytes]: - self.assertNotIsInstance(sample(), MutableSequence) - self.assertFalse(issubclass(sample, MutableSequence)) - for sample in [list, bytearray, deque]: - self.assertIsInstance(sample(), MutableSequence) - self.assertTrue(issubclass(sample, MutableSequence)) - self.assertFalse(issubclass(str, MutableSequence)) - self.validate_abstract_methods(MutableSequence, '__contains__', '__iter__', - '__len__', '__getitem__', '__setitem__', '__delitem__', 'insert') - - def test_MutableSequence_mixins(self): - # Test the mixins of MutableSequence by creating a miminal concrete - # class inherited from it. - class MutableSequenceSubclass(MutableSequence): - def __init__(self): - self.lst = [] - - def __setitem__(self, index, value): - self.lst[index] = value - - def __getitem__(self, index): - return self.lst[index] - - def __len__(self): - return len(self.lst) - - def __delitem__(self, index): - del self.lst[index] - - def insert(self, index, value): - self.lst.insert(index, value) - - mss = MutableSequenceSubclass() - mss.append(0) - mss.extend((1, 2, 3, 4)) - self.assertEqual(len(mss), 5) - self.assertEqual(mss[3], 3) - mss.reverse() - self.assertEqual(mss[3], 1) - mss.pop() - self.assertEqual(len(mss), 4) - mss.remove(3) - self.assertEqual(len(mss), 3) - mss += (10, 20, 30) - self.assertEqual(len(mss), 6) - self.assertEqual(mss[-1], 30) - mss.clear() - self.assertEqual(len(mss), 0) - -################################################################################ -### Counter -################################################################################ - -class CounterSubclassWithSetItem(Counter): - # Test a counter subclass that overrides __setitem__ - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def __setitem__(self, key, value): - self.called = True - Counter.__setitem__(self, key, value) - -class CounterSubclassWithGet(Counter): - # Test a counter subclass that overrides get() - def __init__(self, *args, **kwds): - self.called = False - Counter.__init__(self, *args, **kwds) - def get(self, key, default): - self.called = True - return Counter.get(self, key, default) - -class TestCounter(unittest.TestCase): - - def test_basics(self): - c = Counter('abcaba') - self.assertEqual(c, Counter({'a':3 , 'b': 2, 'c': 1})) - self.assertEqual(c, Counter(a=3, b=2, c=1)) - self.assertIsInstance(c, dict) - self.assertIsInstance(c, Mapping) - self.assertTrue(issubclass(Counter, dict)) - self.assertTrue(issubclass(Counter, Mapping)) - self.assertEqual(len(c), 3) - self.assertEqual(sum(c.values()), 6) - self.assertEqual(sorted(c.values()), [1, 2, 3]) - self.assertEqual(sorted(c.keys()), ['a', 'b', 'c']) - self.assertEqual(sorted(c), ['a', 'b', 'c']) - self.assertEqual(sorted(c.items()), - [('a', 3), ('b', 2), ('c', 1)]) - self.assertEqual(c['b'], 2) - self.assertEqual(c['z'], 0) - self.assertEqual(c.__contains__('c'), True) - self.assertEqual(c.__contains__('z'), False) - self.assertEqual(c.get('b', 10), 2) - self.assertEqual(c.get('z', 10), 10) - self.assertEqual(c, dict(a=3, b=2, c=1)) - self.assertEqual(repr(c), "Counter({'a': 3, 'b': 2, 'c': 1})") - self.assertEqual(c.most_common(), [('a', 3), ('b', 2), ('c', 1)]) - for i in range(5): - self.assertEqual(c.most_common(i), - [('a', 3), ('b', 2), ('c', 1)][:i]) - self.assertEqual(''.join(sorted(c.elements())), 'aaabbc') - c['a'] += 1 # increment an existing value - c['b'] -= 2 # sub existing value to zero - del c['c'] # remove an entry - del c['c'] # make sure that del doesn't raise KeyError - c['d'] -= 2 # sub from a missing value - c['e'] = -5 # directly assign a missing value - c['f'] += 4 # add to a missing value - self.assertEqual(c, dict(a=4, b=0, d=-2, e=-5, f=4)) - self.assertEqual(''.join(sorted(c.elements())), 'aaaaffff') - self.assertEqual(c.pop('f'), 4) - self.assertNotIn('f', c) - for i in range(3): - elem, cnt = c.popitem() - self.assertNotIn(elem, c) - c.clear() - self.assertEqual(c, {}) - self.assertEqual(repr(c), 'Counter()') - self.assertRaises(NotImplementedError, Counter.fromkeys, 'abc') - self.assertRaises(TypeError, hash, c) - c.update(dict(a=5, b=3)) - c.update(c=1) - c.update(Counter('a' * 50 + 'b' * 30)) - c.update() # test case with no args - c.__init__('a' * 500 + 'b' * 300) - c.__init__('cdc') - c.__init__() - self.assertEqual(c, dict(a=555, b=333, c=3, d=1)) - self.assertEqual(c.setdefault('d', 5), 1) - self.assertEqual(c['d'], 1) - self.assertEqual(c.setdefault('e', 5), 5) - self.assertEqual(c['e'], 5) - - def test_init(self): - self.assertEqual(list(Counter(self=42).items()), [('self', 42)]) - self.assertEqual(list(Counter(iterable=42).items()), [('iterable', 42)]) - self.assertEqual(list(Counter(iterable=None).items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter, 42) - self.assertRaises(TypeError, Counter, (), ()) - self.assertRaises(TypeError, Counter.__init__) - - def test_update(self): - c = Counter() - c.update(self=42) - self.assertEqual(list(c.items()), [('self', 42)]) - c = Counter() - c.update(iterable=42) - self.assertEqual(list(c.items()), [('iterable', 42)]) - c = Counter() - c.update(iterable=None) - self.assertEqual(list(c.items()), [('iterable', None)]) - self.assertRaises(TypeError, Counter().update, 42) - self.assertRaises(TypeError, Counter().update, {}, {}) - self.assertRaises(TypeError, Counter.update) - - def test_copying(self): - # Check that counters are copyable, deepcopyable, picklable, and - #have a repr/eval round-trip - words = Counter('which witch had which witches wrist watch'.split()) - def check(dup): - msg = "\ncopy: %s\nwords: %s" % (dup, words) - self.assertIsNot(dup, words, msg) - self.assertEqual(dup, words) - check(words.copy()) - check(copy.copy(words)) - check(copy.deepcopy(words)) - for proto in range(pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - check(pickle.loads(pickle.dumps(words, proto))) - check(eval(repr(words))) - update_test = Counter() - update_test.update(words) - check(update_test) - check(Counter(words)) - - def test_copy_subclass(self): - class MyCounter(Counter): - pass - c = MyCounter('slartibartfast') - d = c.copy() - self.assertEqual(d, c) - self.assertEqual(len(d), len(c)) - self.assertEqual(type(d), type(c)) - - def test_conversions(self): - # Convert to: set, list, dict - s = 'she sells sea shells by the sea shore' - self.assertEqual(sorted(Counter(s).elements()), sorted(s)) - self.assertEqual(sorted(Counter(s)), sorted(set(s))) - self.assertEqual(dict(Counter(s)), dict(Counter(s).items())) - self.assertEqual(set(Counter(s)), set(s)) - - def test_invariant_for_the_in_operator(self): - c = Counter(a=10, b=-2, c=0) - for elem in c: - self.assertTrue(elem in c) - self.assertIn(elem, c) - - def test_multiset_operations(self): - # Verify that adding a zero counter will strip zeros and negatives - c = Counter(a=10, b=-2, c=0) + Counter() - self.assertEqual(dict(c), dict(a=10)) - - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for counterop, numberop in [ - (Counter.__add__, lambda x, y: max(0, x+y)), - (Counter.__sub__, lambda x, y: max(0, x-y)), - (Counter.__or__, lambda x, y: max(0,x,y)), - (Counter.__and__, lambda x, y: max(0, min(x,y))), - ]: - result = counterop(p, q) - for x in elements: - self.assertEqual(numberop(p[x], q[x]), result[x], - (counterop, x, p, q)) - # verify that results exclude non-positive counts - self.assertTrue(x>0 for x in result.values()) - - elements = 'abcdef' - for i in range(100): - # verify that random multisets with no repeats are exactly like sets - p = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - q = Counter(dict((elem, randrange(0, 2)) for elem in elements)) - for counterop, setop in [ - (Counter.__sub__, set.__sub__), - (Counter.__or__, set.__or__), - (Counter.__and__, set.__and__), - ]: - counter_result = counterop(p, q) - set_result = setop(set(p.elements()), set(q.elements())) - self.assertEqual(counter_result, dict.fromkeys(set_result, 1)) - - def test_inplace_operations(self): - elements = 'abcd' - for i in range(1000): - # test random pairs of multisets - p = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - p.update(e=1, f=-1, g=0) - q = Counter(dict((elem, randrange(-2,4)) for elem in elements)) - q.update(h=1, i=-1, j=0) - for inplace_op, regular_op in [ - (Counter.__iadd__, Counter.__add__), - (Counter.__isub__, Counter.__sub__), - (Counter.__ior__, Counter.__or__), - (Counter.__iand__, Counter.__and__), - ]: - c = p.copy() - c_id = id(c) - regular_result = regular_op(c, q) - inplace_result = inplace_op(c, q) - self.assertEqual(inplace_result, regular_result) - self.assertEqual(id(inplace_result), c_id) - - def test_subtract(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - c.subtract(Counter(a=1, b=2, c=-3, d=10, e=20, f=30, h=-50)) - self.assertEqual(c, Counter(a=-6, b=-2, c=8, d=0, e=-5, f=-30, g=40, h=50)) - c = Counter('aaabbcd') - c.subtract('aaaabbcce') - self.assertEqual(c, Counter(a=-1, b=0, c=-1, d=1, e=-1)) - - c = Counter() - c.subtract(self=42) - self.assertEqual(list(c.items()), [('self', -42)]) - c = Counter() - c.subtract(iterable=42) - self.assertEqual(list(c.items()), [('iterable', -42)]) - self.assertRaises(TypeError, Counter().subtract, 42) - self.assertRaises(TypeError, Counter().subtract, {}, {}) - self.assertRaises(TypeError, Counter.subtract) - - def test_unary(self): - c = Counter(a=-5, b=0, c=5, d=10, e=15,g=40) - self.assertEqual(dict(+c), dict(c=5, d=10, e=15, g=40)) - self.assertEqual(dict(-c), dict(a=5)) - - def test_repr_nonsortable(self): - c = Counter(a=2, b=None) - r = repr(c) - self.assertIn("'a': 2", r) - self.assertIn("'b': None", r) - - def test_helper_function(self): - # two paths, one for real dicts and one for other mappings - elems = list('abracadabra') - - d = dict() - _count_elements(d, elems) - self.assertEqual(d, {'a': 5, 'r': 2, 'b': 2, 'c': 1, 'd': 1}) - - m = OrderedDict() - _count_elements(m, elems) - self.assertEqual(m, - OrderedDict([('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)])) - - # test fidelity to the pure python version - c = CounterSubclassWithSetItem('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - c = CounterSubclassWithGet('abracadabra') - self.assertTrue(c.called) - self.assertEqual(dict(c), {'a': 5, 'b': 2, 'c': 1, 'd': 1, 'r':2 }) - - -################################################################################ -### OrderedDict -################################################################################ - -py_coll = import_fresh_module('collections', blocked=['_collections']) -c_coll = import_fresh_module('collections', fresh=['_collections']) +py_coll = support.import_fresh_module('collections', blocked=['_collections']) +c_coll = support.import_fresh_module('collections', fresh=['_collections']) @contextlib.contextmanager @@ -2195,6 +579,7 @@ self.assertNotIn('NULL', repr(od)) def test_dict_update(self): + OrderedDict = self.OrderedDict od = OrderedDict() dict.update(od, [('spam', 1)]) self.assertNotIn('NULL', repr(od)) @@ -2294,26 +679,5 @@ self.assertRaises(KeyError, d.popitem) -################################################################################ -### Run tests -################################################################################ - -import doctest, collections - -def test_main(verbose=None): - NamedTupleDocs = doctest.DocTestSuite(module=collections) - test_classes = [TestNamedTuple, NamedTupleDocs, TestOneTrickPonyABCs, - TestCollectionABCs, TestCounter, TestChainMap, - PurePythonOrderedDictTests, CPythonOrderedDictTests, - PurePythonOrderedDictSubclassTests, - CPythonOrderedDictSubclassTests, - PurePythonGeneralMappingTests, CPythonGeneralMappingTests, - PurePythonSubclassMappingTests, CPythonSubclassMappingTests, - TestUserObjects, - ] - support.run_unittest(*test_classes) - support.run_doctest(collections, verbose) - - if __name__ == "__main__": - test_main(verbose=True) + unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,12 @@ - Issue #25624: ZipFile now always writes a ZIP_STORED header for directory entries. Patch by Dingyuan Wang. +Tests +----- + +- Issue #25616: Tests for OrderedDict are extracted from test_collections + into separate file test_ordered_dict. + What's New in Python 3.5.1 final? ================================= -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 11:36:04 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 16:36:04 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI0MDk3?= =?utf-8?q?=3A_Fixed_crash_in_object=2E=5F=5Freduce=5F=5F=28=29_if_slot_na?= =?utf-8?q?me_is_freed_inside?= Message-ID: <20151125163603.22392.17119@psf.io> https://hg.python.org/cpython/rev/eed36e19f8b8 changeset: 99356:eed36e19f8b8 branch: 3.4 parent: 99352:8d9a0540adf9 user: Serhiy Storchaka date: Wed Nov 25 18:33:29 2015 +0200 summary: Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. Original patch by Antoine Pitrou. files: Lib/test/test_descr.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 3 +++ 3 files changed, 23 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4988,6 +4988,23 @@ objcopy2 = deepcopy(objcopy) self._assert_is_copy(obj, objcopy2) + def test_issue24097(self): + # Slot name is freed inside __getattr__ and is later used. + class S(str): # Not interned + pass + class A: + __slotnames__ = [S('spam')] + def __getattr__(self, attr): + if attr == 'spam': + A.__slotnames__[:] = [S('spam')] + return 42 + else: + raise AttributeError + + import copyreg + expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) + self.assertEqual(A().__reduce__(2), expected) # Shouldn't crash + class SharedKeyTests(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside + __getattr__. + - Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3768,8 +3768,10 @@ PyObject *name, *value; name = PyList_GET_ITEM(slotnames, i); + Py_INCREF(name); value = PyObject_GetAttr(obj, name); if (value == NULL) { + Py_DECREF(name); if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { goto error; } @@ -3778,6 +3780,7 @@ } else { int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); Py_DECREF(value); if (err) { goto error; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 11:36:04 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 16:36:04 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2324097=3A_Fixed_crash_in_object=2E=5F=5Freduce=5F=5F?= =?utf-8?q?=28=29_if_slot_name_is_freed_inside?= Message-ID: <20151125163604.29824.1667@psf.io> https://hg.python.org/cpython/rev/99839a1c9c6d changeset: 99357:99839a1c9c6d branch: 3.5 parent: 99353:46e95e0eaae5 parent: 99356:eed36e19f8b8 user: Serhiy Storchaka date: Wed Nov 25 18:34:19 2015 +0200 summary: Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. Original patch by Antoine Pitrou. files: Lib/test/test_descr.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 3 +++ 3 files changed, 23 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -5092,6 +5092,23 @@ objcopy2 = deepcopy(objcopy) self._assert_is_copy(obj, objcopy2) + def test_issue24097(self): + # Slot name is freed inside __getattr__ and is later used. + class S(str): # Not interned + pass + class A: + __slotnames__ = [S('spam')] + def __getattr__(self, attr): + if attr == 'spam': + A.__slotnames__[:] = [S('spam')] + return 42 + else: + raise AttributeError + + import copyreg + expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) + self.assertEqual(A().__reduce__(2), expected) # Shouldn't crash + class SharedKeyTests(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside + __getattr__. + - Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3889,8 +3889,10 @@ PyObject *name, *value; name = PyList_GET_ITEM(slotnames, i); + Py_INCREF(name); value = PyObject_GetAttr(obj, name); if (value == NULL) { + Py_DECREF(name); if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { goto error; } @@ -3899,6 +3901,7 @@ } else { int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); Py_DECREF(value); if (err) { goto error; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 11:36:04 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 16:36:04 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI0MDk3?= =?utf-8?q?=3A_Fixed_crash_in_object=2E=5F=5Freduce=5F=5F=28=29_if_slot_na?= =?utf-8?q?me_is_freed_inside?= Message-ID: <20151125163604.22386.57029@psf.io> https://hg.python.org/cpython/rev/4a201d0d4d1e changeset: 99359:4a201d0d4d1e branch: 2.7 parent: 99355:afaad8dc8edf user: Serhiy Storchaka date: Wed Nov 25 18:35:33 2015 +0200 summary: Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. Original patch by Antoine Pitrou. files: Lib/test/test_descr.py | 23 ++++++++++++++++++++++- Misc/NEWS | 3 +++ Objects/typeobject.c | 6 +++++- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -4763,6 +4763,26 @@ type.mro(tuple) +class PicklingTests(unittest.TestCase): + + def test_issue24097(self): + # Slot name is freed inside __getattr__ and is later used. + class S(str): # Not interned + pass + class A(object): + __slotnames__ = [S('spam')] + def __getattr__(self, attr): + if attr == 'spam': + A.__slotnames__[:] = [S('spam')] + return 42 + else: + raise AttributeError + + import copy_reg + expected = (copy_reg.__newobj__, (A,), ({}, {'spam': 42}), None, None) + self.assertEqual(A().__reduce__(2), expected) + + def test_main(): deprecations = [(r'complex divmod\(\), // and % are deprecated$', DeprecationWarning)] @@ -4774,7 +4794,8 @@ with test_support.check_warnings(*deprecations): # Run all local test cases, with PTypesLongInitTest first. test_support.run_unittest(PTypesLongInitTest, OperatorsTest, - ClassPropertiesAndMethods, DictProxyTests) + ClassPropertiesAndMethods, DictProxyTests, + PicklingTests) if __name__ == "__main__": test_main() diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside + __getattr__. + - Issue #24731: Fixed crash on converting objects with special methods __str__, __trunc__, and __float__ returning instances of subclasses of str, long, and float to subclasses of str, long, and float correspondingly. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3269,12 +3269,16 @@ for (i = 0; i < PyList_GET_SIZE(names); i++) { PyObject *name, *value; name = PyList_GET_ITEM(names, i); + Py_INCREF(name); value = PyObject_GetAttr(obj, name); - if (value == NULL) + if (value == NULL) { + Py_DECREF(name); PyErr_Clear(); + } else { int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); Py_DECREF(value); if (err) goto end; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 11:36:12 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 16:36:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2324097=3A_Fixed_crash_in_object=2E=5F=5Freduce?= =?utf-8?q?=5F=5F=28=29_if_slot_name_is_freed_inside?= Message-ID: <20151125163604.59409.75668@psf.io> https://hg.python.org/cpython/rev/502465d22522 changeset: 99358:502465d22522 parent: 99354:81fa901162f9 parent: 99357:99839a1c9c6d user: Serhiy Storchaka date: Wed Nov 25 18:35:15 2015 +0200 summary: Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. Original patch by Antoine Pitrou. files: Lib/test/test_descr.py | 17 +++++++++++++++++ Misc/NEWS | 3 +++ Objects/typeobject.c | 3 +++ 3 files changed, 23 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -5085,6 +5085,23 @@ objcopy2 = deepcopy(objcopy) self._assert_is_copy(obj, objcopy2) + def test_issue24097(self): + # Slot name is freed inside __getattr__ and is later used. + class S(str): # Not interned + pass + class A: + __slotnames__ = [S('spam')] + def __getattr__(self, attr): + if attr == 'spam': + A.__slotnames__[:] = [S('spam')] + return 42 + else: + raise AttributeError + + import copyreg + expected = (copyreg.__newobj__, (A,), (None, {'spam': 42}), None, None) + self.assertEqual(A().__reduce__(2), expected) # Shouldn't crash + class SharedKeyTests(unittest.TestCase): diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside + __getattr__. + - Issue #24731: Fixed crash on converting objects with special methods __bytes__, __trunc__, and __float__ returning instances of subclasses of bytes, int, and float to subclasses of bytes, int, and float correspondingly. diff --git a/Objects/typeobject.c b/Objects/typeobject.c --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -3897,8 +3897,10 @@ PyObject *name, *value; name = PyList_GET_ITEM(slotnames, i); + Py_INCREF(name); value = PyObject_GetAttr(obj, name); if (value == NULL) { + Py_DECREF(name); if (!PyErr_ExceptionMatches(PyExc_AttributeError)) { goto error; } @@ -3907,6 +3909,7 @@ } else { int err = PyDict_SetItem(slots, name, value); + Py_DECREF(name); Py_DECREF(value); if (err) { goto error; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 13:18:41 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 18:18:41 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Null_merge?= Message-ID: <20151125181840.22394.50945@psf.io> https://hg.python.org/cpython/rev/022c4521ce8a changeset: 99363:022c4521ce8a parent: 99358:502465d22522 parent: 99362:6425a07a6072 user: Serhiy Storchaka date: Wed Nov 25 20:16:36 2015 +0200 summary: Null merge files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 13:18:41 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 18:18:41 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzE5Njg3?= =?utf-8?q?=3A_Fixed_possible_integer_overflows_in_ElementTree=2E?= Message-ID: <20151125181840.660.89378@psf.io> https://hg.python.org/cpython/rev/745fd5550bc0 changeset: 99361:745fd5550bc0 branch: 2.7 parent: 99359:4a201d0d4d1e user: Serhiy Storchaka date: Wed Nov 25 20:12:58 2015 +0200 summary: Issue #19687: Fixed possible integer overflows in ElementTree. Based on patch by Christian Heimes. files: Modules/_elementtree.c | 29 +++++++++++++++++++++++------ 1 files changed, 23 insertions(+), 6 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -337,9 +337,9 @@ } LOCAL(int) -element_resize(ElementObject* self, int extra) +element_resize(ElementObject* self, Py_ssize_t extra) { - int size; + Py_ssize_t size; PyObject* *children; /* make sure self->children can hold the given number of extra @@ -359,6 +359,13 @@ * be safe. */ size = size ? size : 1; + if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) + goto nomemory; + if (size > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "too many children"); + return -1; + } if (self->extra->children != self->extra->_children) { /* Coverity CID #182 size_error: Allocating 1 bytes to pointer * "children", which needs at least 4 bytes. Although it's a @@ -1256,15 +1263,16 @@ element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) { ElementObject* self = (ElementObject*) self_; - int i; + int i, index; PyObject* old; - if (!self->extra || index < 0 || index >= self->extra->length) { + if (!self->extra || index_ < 0 || index_ >= self->extra->length) { PyErr_SetString( PyExc_IndexError, "child assignment index out of range"); return -1; } + index = (int)index_; old = self->extra->children[index]; @@ -1373,6 +1381,7 @@ &start, &stop, &step, &slicelen) < 0) { return -1; } + assert(slicelen <= self->extra->length); if (value == NULL) newlen = 0; @@ -1413,6 +1422,8 @@ return -1; } } + assert(newlen - slicelen <= INT_MAX - self->extra->length); + assert(newlen - slicelen >= -self->extra->length); if (slicelen > 0) { /* to avoid recursive calls to this method (via decref), move @@ -1446,7 +1457,7 @@ self->extra->children[cur] = element; } - self->extra->length += newlen - slicelen; + self->extra->length += (int)(newlen - slicelen); Py_XDECREF(seq); @@ -2704,8 +2715,14 @@ break; } + if (PyString_GET_SIZE(buffer) > INT_MAX) { + Py_DECREF(buffer); + Py_DECREF(reader); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } res = expat_parse( - self, PyString_AS_STRING(buffer), PyString_GET_SIZE(buffer), 0 + self, PyString_AS_STRING(buffer), (int)PyString_GET_SIZE(buffer), 0 ); Py_DECREF(buffer); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 13:18:46 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 18:18:46 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Null_merge?= Message-ID: <20151125181840.87887.57038@psf.io> https://hg.python.org/cpython/rev/6425a07a6072 changeset: 99362:6425a07a6072 branch: 3.5 parent: 99357:99839a1c9c6d parent: 99360:e5eac1d692ad user: Serhiy Storchaka date: Wed Nov 25 20:16:22 2015 +0200 summary: Null merge files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 13:18:52 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Wed, 25 Nov 2015 18:18:52 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzE5Njg3?= =?utf-8?q?=3A_Fixed_possible_integer_overflows_in_ElementTree=2E?= Message-ID: <20151125181840.69582.35067@psf.io> https://hg.python.org/cpython/rev/e5eac1d692ad changeset: 99360:e5eac1d692ad branch: 3.4 parent: 99356:eed36e19f8b8 user: Serhiy Storchaka date: Wed Nov 25 20:12:37 2015 +0200 summary: Issue #19687: Fixed possible integer overflows in ElementTree. Based on patch by Christian Heimes. files: Modules/_elementtree.c | 44 +++++++++++++++++++++++------ 1 files changed, 34 insertions(+), 10 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -429,9 +429,9 @@ } LOCAL(int) -element_resize(ElementObject* self, int extra) +element_resize(ElementObject* self, Py_ssize_t extra) { - int size; + Py_ssize_t size; PyObject* *children; /* make sure self->children can hold the given number of extra @@ -453,6 +453,13 @@ * be safe. */ size = size ? size : 1; + if ((size_t)size > PY_SSIZE_T_MAX/sizeof(PyObject*)) + goto nomemory; + if (size > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "too many children"); + return -1; + } if (self->extra->children != self->extra->_children) { /* Coverity CID #182 size_error: Allocating 1 bytes to pointer * "children", which needs at least 4 bytes. Although it's a @@ -889,7 +896,7 @@ PyObject *tail, PyObject *children) { - Py_ssize_t i, nchildren; + int i, nchildren; if (!tag) { PyErr_SetString(PyExc_TypeError, "tag may not be NULL"); @@ -914,11 +921,18 @@ /* Compute 'nchildren'. */ if (children) { + Py_ssize_t size; if (!PyList_Check(children)) { PyErr_SetString(PyExc_TypeError, "'_children' is not a list"); return NULL; } - nchildren = PyList_Size(children); + size = PyList_Size(children); + /* expat limits nchildren to int */ + if (size > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, "too many children"); + return NULL; + } + nchildren = (int)size; } else { nchildren = 0; @@ -1505,18 +1519,19 @@ } static int -element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) +element_setitem(PyObject* self_, Py_ssize_t index_, PyObject* item) { ElementObject* self = (ElementObject*) self_; - int i; + int i, index; PyObject* old; - if (!self->extra || index < 0 || index >= self->extra->length) { + if (!self->extra || index_ < 0 || index_ >= self->extra->length) { PyErr_SetString( PyExc_IndexError, "child assignment index out of range"); return -1; } + index = (int)index_; old = self->extra->children[index]; @@ -1617,6 +1632,7 @@ &start, &stop, &step, &slicelen) < 0) { return -1; } + assert(slicelen <= self->extra->length); if (value == NULL) { /* Delete slice */ @@ -1678,7 +1694,7 @@ (self->extra->length - cur) * sizeof(PyObject *)); } - self->extra->length -= slicelen; + self->extra->length -= (int)slicelen; /* Discard the recycle list with all the deleted sub-elements */ Py_XDECREF(recycle); @@ -1714,6 +1730,8 @@ return -1; } } + assert(newlen - slicelen <= INT_MAX - self->extra->length); + assert(newlen - slicelen >= -self->extra->length); if (slicelen > 0) { /* to avoid recursive calls to this method (via decref), move @@ -1747,7 +1765,7 @@ self->extra->children[cur] = element; } - self->extra->length += newlen - slicelen; + self->extra->length += (int)(newlen - slicelen); Py_DECREF(seq); @@ -3528,8 +3546,14 @@ break; } + if (PyBytes_GET_SIZE(buffer) > INT_MAX) { + Py_DECREF(buffer); + Py_DECREF(reader); + PyErr_SetString(PyExc_OverflowError, "size does not fit in an int"); + return NULL; + } res = expat_parse( - self, PyBytes_AS_STRING(buffer), PyBytes_GET_SIZE(buffer), 0 + self, PyBytes_AS_STRING(buffer), (int)PyBytes_GET_SIZE(buffer), 0 ); Py_DECREF(buffer); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Wed Nov 25 21:56:36 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 02:56:36 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325622=3A_Rename_t?= =?utf-8?q?o_PythonValuesTestCase_and_enable_for_non-Windows?= Message-ID: <20151126025636.31395.26063@psf.io> https://hg.python.org/cpython/rev/6a8fbb97c8d8 changeset: 99364:6a8fbb97c8d8 user: Martin Panter date: Thu Nov 26 02:36:26 2015 +0000 summary: Issue #25622: Rename to PythonValuesTestCase and enable for non-Windows files: Lib/ctypes/test/test_values.py | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -28,8 +28,7 @@ ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - at unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') -class Win_ValuesTestCase(unittest.TestCase): +class PythonValuesTestCase(unittest.TestCase): """This test only works when python itself is a dll/shared library""" def test_optimizeflag(self): @@ -76,7 +75,7 @@ if entry.name in bootstrap_expected: bootstrap_seen.append(entry.name) self.assertTrue(entry.size, - "{} was reported as having no size".format(entry.name)) + "{!r} was reported as having no size".format(entry.name)) continue items.append((entry.name, entry.size)) -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Thu Nov 26 03:43:51 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 26 Nov 2015 08:43:51 +0000 Subject: [Python-checkins] Daily reference leaks (6a8fbb97c8d8): sum=5 Message-ID: <20151126084350.676.1744@psf.io> results for 6a8fbb97c8d8 on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 test_smtplib leaked [1, 0, 0] references, sum=1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogE8yZEf', '--timeout', '7200'] From python-checkins at python.org Thu Nov 26 04:22:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 26 Nov 2015 09:22:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fixed_compilat?= =?utf-8?q?ion_error_introduced_in_745fd5550bc0=2E?= Message-ID: <20151126092247.13431.41915@psf.io> https://hg.python.org/cpython/rev/416f0e629c5d changeset: 99365:416f0e629c5d branch: 2.7 parent: 99361:745fd5550bc0 user: Serhiy Storchaka date: Thu Nov 26 11:21:47 2015 +0200 summary: Fixed compilation error introduced in 745fd5550bc0. files: Modules/_elementtree.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -1260,7 +1260,7 @@ } static int -element_setitem(PyObject* self_, Py_ssize_t index, PyObject* item) +element_setitem(PyObject* self_, Py_ssize_t index_, PyObject* item) { ElementObject* self = (ElementObject*) self_; int i, index; -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 05:45:14 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 10:45:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NjIy?= =?utf-8?q?=3A_Rename_to_PythonValuesTestCase_and_enable_for_non-Windows?= Message-ID: <20151126104513.31397.59801@psf.io> https://hg.python.org/cpython/rev/0325eca1927e changeset: 99366:0325eca1927e branch: 3.4 parent: 99360:e5eac1d692ad user: Martin Panter date: Thu Nov 26 02:36:26 2015 +0000 summary: Issue #25622: Rename to PythonValuesTestCase and enable for non-Windows files: Lib/ctypes/test/test_values.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -28,8 +28,7 @@ ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - at unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') -class Win_ValuesTestCase(unittest.TestCase): +class PythonValuesTestCase(unittest.TestCase): """This test only works when python itself is a dll/shared library""" def test_optimizeflag(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 05:45:14 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 10:45:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy41KTogSXNzdWUgIzI1NjIy?= =?utf-8?q?=3A_Use_repr=28bytes=29_to_avoid_BytesWarning?= Message-ID: <20151126104514.29812.13239@psf.io> https://hg.python.org/cpython/rev/38f749f0a1bd changeset: 99368:38f749f0a1bd branch: 3.5 user: Martin Panter date: Thu Nov 26 02:36:26 2015 +0000 summary: Issue #25622: Use repr(bytes) to avoid BytesWarning files: Lib/ctypes/test/test_values.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -75,7 +75,7 @@ if entry.name in bootstrap_expected: bootstrap_seen.append(entry.name) self.assertTrue(entry.size, - "{} was reported as having no size".format(entry.name)) + "{!r} was reported as having no size".format(entry.name)) continue items.append((entry.name, entry.size)) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 05:45:14 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 10:45:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Merge_from_3=2E5=3B_no_changes?= Message-ID: <20151126104514.31417.85433@psf.io> https://hg.python.org/cpython/rev/3c1ec06f5324 changeset: 99369:3c1ec06f5324 parent: 99364:6a8fbb97c8d8 parent: 99368:38f749f0a1bd user: Martin Panter date: Thu Nov 26 10:44:07 2015 +0000 summary: Merge from 3.5; no changes files: -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 05:45:15 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 10:45:15 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325622=3A_Merge_ctypes_test_from_3=2E4_into_3=2E5?= Message-ID: <20151126104514.87863.78446@psf.io> https://hg.python.org/cpython/rev/18a74ef65d3f changeset: 99367:18a74ef65d3f branch: 3.5 parent: 99362:6425a07a6072 parent: 99366:0325eca1927e user: Martin Panter date: Thu Nov 26 10:26:33 2015 +0000 summary: Issue #25622: Merge ctypes test from 3.4 into 3.5 files: Lib/ctypes/test/test_values.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -28,8 +28,7 @@ ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - at unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') -class Win_ValuesTestCase(unittest.TestCase): +class PythonValuesTestCase(unittest.TestCase): """This test only works when python itself is a dll/shared library""" def test_optimizeflag(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 06:07:12 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 11:07:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWVzICMyMjk4?= =?utf-8?q?9=2C_=2321228=3A_Document_HTTP_response_object_for_urlopen=28?= =?utf-8?q?=29?= Message-ID: <20151126110711.29808.33726@psf.io> https://hg.python.org/cpython/rev/fa3c9faabfb0 changeset: 99370:fa3c9faabfb0 branch: 3.4 parent: 99366:0325eca1927e user: Martin Panter date: Thu Nov 26 11:01:58 2015 +0000 summary: Issues #22989, #21228: Document HTTP response object for urlopen() Previous documentation was not clear if the geturl(), info() and getcode() were valid for HTTP responses. The ?msg? attribute is different to the usual HTTPResponse.msg attribute. Based on patch by Evens Fortun?. files: Doc/library/urllib.request.rst | 20 +++++++++++++------- Misc/ACKS | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -59,13 +59,7 @@ The *cadefault* parameter is ignored. - For http and https urls, this function returns a - :class:`http.client.HTTPResponse` object which has the following - :ref:`httpresponse-objects` methods. - - For ftp, file, and data urls and requests explicitly handled by legacy - :class:`URLopener` and :class:`FancyURLopener` classes, this function - returns a :class:`urllib.response.addinfourl` object which can work as + This function always returns an object which can work as :term:`context manager` and has methods such as * :meth:`~urllib.response.addinfourl.geturl` --- return the URL of the resource retrieved, @@ -77,6 +71,18 @@ * :meth:`~urllib.response.addinfourl.getcode` -- return the HTTP status code of the response. + For http and https urls, this function returns a + :class:`http.client.HTTPResponse` object slightly modified. In addition + to the three new methods above, the msg attribute contains the + same information as the :attr:`~http.client.HTTPResponse.reason` + attribute --- the reason phrase returned by server --- instead of + the response headers as it is specified in the documentation for + :class:`~http.client.HTTPResponse`. + + For ftp, file, and data urls and requests explicitly handled by legacy + :class:`URLopener` and :class:`FancyURLopener` classes, this function + returns a :class:`urllib.response.addinfourl` object. + Raises :exc:`~urllib.error.URLError` on errors. Note that ``None`` may be returned if no handler handles the request (though diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -436,6 +436,7 @@ Michael Foord Amaury Forgeot d'Arc Doug Fort +Evens Fortun? Chris Foster John Fouhy Andrew Francis -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 06:07:12 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 11:07:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2322989=2C_=2321228=3A_Merge_urlopen=28=29_doc_from_3?= =?utf-8?q?=2E4_into_3=2E5?= Message-ID: <20151126110712.31417.28705@psf.io> https://hg.python.org/cpython/rev/b55c006b79bc changeset: 99371:b55c006b79bc branch: 3.5 parent: 99368:38f749f0a1bd parent: 99370:fa3c9faabfb0 user: Martin Panter date: Thu Nov 26 11:03:50 2015 +0000 summary: Issue #22989, #21228: Merge urlopen() doc from 3.4 into 3.5 files: Doc/library/urllib.request.rst | 20 +++++++++++++------- Misc/ACKS | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -59,13 +59,7 @@ The *cadefault* parameter is ignored. - For http and https urls, this function returns a - :class:`http.client.HTTPResponse` object which has the following - :ref:`httpresponse-objects` methods. - - For ftp, file, and data urls and requests explicitly handled by legacy - :class:`URLopener` and :class:`FancyURLopener` classes, this function - returns a :class:`urllib.response.addinfourl` object which can work as + This function always returns an object which can work as :term:`context manager` and has methods such as * :meth:`~urllib.response.addinfourl.geturl` --- return the URL of the resource retrieved, @@ -77,6 +71,18 @@ * :meth:`~urllib.response.addinfourl.getcode` -- return the HTTP status code of the response. + For http and https urls, this function returns a + :class:`http.client.HTTPResponse` object slightly modified. In addition + to the three new methods above, the msg attribute contains the + same information as the :attr:`~http.client.HTTPResponse.reason` + attribute --- the reason phrase returned by server --- instead of + the response headers as it is specified in the documentation for + :class:`~http.client.HTTPResponse`. + + For ftp, file, and data urls and requests explicitly handled by legacy + :class:`URLopener` and :class:`FancyURLopener` classes, this function + returns a :class:`urllib.response.addinfourl` object. + Raises :exc:`~urllib.error.URLError` on errors. Note that ``None`` may be returned if no handler handles the request (though diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -443,6 +443,7 @@ Michael Foord Amaury Forgeot d'Arc Doug Fort +Evens Fortun? Chris Foster John Fouhy Andrew Francis -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 06:07:16 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 11:07:16 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2322989=2C_=2321228=3A_Merge_urlopen=28=29_doc_fr?= =?utf-8?q?om_3=2E5?= Message-ID: <20151126110713.59409.74387@psf.io> https://hg.python.org/cpython/rev/c6930661599b changeset: 99372:c6930661599b parent: 99369:3c1ec06f5324 parent: 99371:b55c006b79bc user: Martin Panter date: Thu Nov 26 11:04:06 2015 +0000 summary: Issue #22989, #21228: Merge urlopen() doc from 3.5 files: Doc/library/urllib.request.rst | 20 +++++++++++++------- Misc/ACKS | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/Doc/library/urllib.request.rst b/Doc/library/urllib.request.rst --- a/Doc/library/urllib.request.rst +++ b/Doc/library/urllib.request.rst @@ -59,13 +59,7 @@ The *cadefault* parameter is ignored. - For http and https urls, this function returns a - :class:`http.client.HTTPResponse` object which has the following - :ref:`httpresponse-objects` methods. - - For ftp, file, and data urls and requests explicitly handled by legacy - :class:`URLopener` and :class:`FancyURLopener` classes, this function - returns a :class:`urllib.response.addinfourl` object which can work as + This function always returns an object which can work as :term:`context manager` and has methods such as * :meth:`~urllib.response.addinfourl.geturl` --- return the URL of the resource retrieved, @@ -77,6 +71,18 @@ * :meth:`~urllib.response.addinfourl.getcode` -- return the HTTP status code of the response. + For http and https urls, this function returns a + :class:`http.client.HTTPResponse` object slightly modified. In addition + to the three new methods above, the msg attribute contains the + same information as the :attr:`~http.client.HTTPResponse.reason` + attribute --- the reason phrase returned by server --- instead of + the response headers as it is specified in the documentation for + :class:`~http.client.HTTPResponse`. + + For ftp, file, and data urls and requests explicitly handled by legacy + :class:`URLopener` and :class:`FancyURLopener` classes, this function + returns a :class:`urllib.response.addinfourl` object. + Raises :exc:`~urllib.error.URLError` on errors. Note that ``None`` may be returned if no handler handles the request (though diff --git a/Misc/ACKS b/Misc/ACKS --- a/Misc/ACKS +++ b/Misc/ACKS @@ -444,6 +444,7 @@ Michael Foord Amaury Forgeot d'Arc Doug Fort +Evens Fortun? Chris Foster John Fouhy Andrew Francis -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 06:22:19 2015 From: python-checkins at python.org (martin.panter) Date: Thu, 26 Nov 2015 11:22:19 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NjIy?= =?utf-8?q?=3A_Rename_to_PythonValuesTestCase_and_enable_for_non-Windows?= Message-ID: <20151126112218.59411.36179@psf.io> https://hg.python.org/cpython/rev/7b12b04f4f18 changeset: 99373:7b12b04f4f18 branch: 2.7 parent: 99365:416f0e629c5d user: Martin Panter date: Thu Nov 26 02:36:26 2015 +0000 summary: Issue #25622: Rename to PythonValuesTestCase and enable for non-Windows files: Lib/ctypes/test/test_values.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/Lib/ctypes/test/test_values.py b/Lib/ctypes/test/test_values.py --- a/Lib/ctypes/test/test_values.py +++ b/Lib/ctypes/test/test_values.py @@ -22,8 +22,7 @@ ctdll = CDLL(_ctypes_test.__file__) self.assertRaises(ValueError, c_int.in_dll, ctdll, "Undefined_Symbol") - at unittest.skipUnless(sys.platform == 'win32', 'Windows-specific test') -class Win_ValuesTestCase(unittest.TestCase): +class PythonValuesTestCase(unittest.TestCase): """This test only works when python itself is a dll/shared library""" def test_optimizeflag(self): -- Repository URL: https://hg.python.org/cpython From lp_benchmark_robot at intel.com Thu Nov 26 09:19:55 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 26 Nov 2015 14:19:55 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-26 Message-ID: Results for project Python 2.7, build date 2015-11-26 09:37:14 +0000 commit: 416f0e629c5de198416f4021d4fda5d9a9870833 revision date: 2015-11-26 09:21:47 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-| django_v2 0.18% -1.13% 1.99% 11.24% :-) pybench 0.21% -0.12% 6.12% 7.18% :-( regex_v8 1.11% -0.26% -2.84% 8.98% :-) nbody 0.16% 0.06% 9.36% 4.61% :-) json_dump_v2 0.31% 0.48% 2.16% 13.71% :-| normal_startup 1.94% -0.07% -1.61% 3.21% :-| ssbench 0.36% -0.54% 0.09% 1.92% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Thu Nov 26 09:19:27 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 26 Nov 2015 14:19:27 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-26 Message-ID: <6f05ffe9-1c96-4a82-a12b-19c07aa10239@irsmsx104.ger.corp.intel.com> Results for project Python default, build date 2015-11-26 07:22:07 +0000 commit: 6a8fbb97c8d8ddf8ab46e495d328290b990f703f revision date: 2015-11-26 02:36:26 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.21% -2.19% 7.57% 17.17% :-| pybench 0.09% 0.17% -1.98% 9.48% :-( regex_v8 2.71% 0.63% -4.77% 5.95% :-| nbody 0.07% 1.99% 0.10% 7.01% :-| json_dump_v2 0.20% 0.75% 0.59% 8.75% :-| normal_startup 0.83% 0.24% 0.22% 4.37% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Thu Nov 26 12:46:27 2015 From: python-checkins at python.org (r.david.murray) Date: Thu, 26 Nov 2015 17:46:27 +0000 Subject: [Python-checkins] =?utf-8?q?devguide=3A_=2325194=3A_Fix_indentati?= =?utf-8?q?on_in_Nick=27s_entry=2E?= Message-ID: <20151126174625.69582.52114@psf.io> https://hg.python.org/devguide/rev/2d4907e5b51c changeset: 775:2d4907e5b51c user: R David Murray date: Thu Nov 26 12:46:04 2015 -0500 summary: #25194: Fix indentation in Nick's entry. files: motivations.rst | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-) diff --git a/motivations.rst b/motivations.rst --- a/motivations.rst +++ b/motivations.rst @@ -166,22 +166,22 @@ .. topic:: Nick Coghlan (Australia) - * Personal site: `Curious Efficiency `_ - * `Extended bio `__ - * Red Hat (Software Engineer, Developer Experience) - * Python Software Foundation (Board of Directors) + * Personal site: `Curious Efficiency `_ + * `Extended bio `__ + * Red Hat (Software Engineer, Developer Experience) + * Python Software Foundation (Board of Directors) - Nick originally began participating in CPython core development as an - interesting and enlightening hobby activity while working for Boeing Defence - Australia. After commencing work for Red Hat, he also became involved in a - range of topics related directly to improving the experience of Python - developers on the Fedora Linux distribution and derived platforms, and now - works for Red Hat's Developer Experience team. + Nick originally began participating in CPython core development as an + interesting and enlightening hobby activity while working for Boeing Defence + Australia. After commencing work for Red Hat, he also became involved in a + range of topics related directly to improving the experience of Python + developers on the Fedora Linux distribution and derived platforms, and now + works for Red Hat's Developer Experience team. - In addition to his personal and professional interest in ensuring Python - remains an excellent choice for Linux-based network service and system - utility development, he is also interested in helping to ensure its - continued suitability for educational and data analysis use cases. + In addition to his personal and professional interest in ensuring Python + remains an excellent choice for Linux-based network service and system + utility development, he is also interested in helping to ensure its + continued suitability for educational and data analysis use cases. .. topic:: R. David Murray (United States) -- Repository URL: https://hg.python.org/devguide From python-checkins at python.org Thu Nov 26 12:46:26 2015 From: python-checkins at python.org (r.david.murray) Date: Thu, 26 Nov 2015 17:46:26 +0000 Subject: [Python-checkins] =?utf-8?q?devguide=3A_=2325194=3A_add_my_entry_?= =?utf-8?q?to_=27motivations=27=2E?= Message-ID: <20151126174625.81860.92@psf.io> https://hg.python.org/devguide/rev/b360bad24805 changeset: 774:b360bad24805 user: R David Murray date: Thu Nov 26 12:45:30 2015 -0500 summary: #25194: add my entry to 'motivations'. files: motivations.rst | 28 ++++++++++++++++++++++++++++ 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/motivations.rst b/motivations.rst --- a/motivations.rst +++ b/motivations.rst @@ -182,3 +182,31 @@ remains an excellent choice for Linux-based network service and system utility development, he is also interested in helping to ensure its continued suitability for educational and data analysis use cases. + +.. topic:: R. David Murray (United States) + + * Personal site: `bitdance.com `_ + * Available for `Python and Internet Services Consulting + and Python contract programming `_ + + David has been involved in the Internet since the days when the old IBM + BITNET and the ARPANet got cross connected, and in Python programming since + he first discovered it around the days of Python 1.4. After transitioning + from being Director of Operations for dialup Internet providers (when that + business started declining) to being a full time independent consultant, + David started contributing directly to CPython development. He became a + committer in 2009. He subsequently took over primary maintenance of the + email package from Barry Warsaw, and contributed the unicode oriented API. + David is also active in mentoring new contributors and, when time is + available, working on the infrastructure that supports CPython development, + specifically the Roundup-based bug tracker and the buildbot system. + + David currently does both proprietary and open source developement work, + primarily in Python, through the company in which he is a partner, `Murray & + Walker, Inc `_. He has done contract work + focused specifically on CPython development both through the PSF (the + kickstart of the email unicode API development) and directly funded by + interested corporations (additional development work on email fundeded by + QNX, and work on CPython ICC support funded by Intel). He would like to + spend more of his (and his company's) time on open source work, and so is + actively seeking additional such contract opportunities. -- Repository URL: https://hg.python.org/devguide From python-checkins at python.org Thu Nov 26 16:53:01 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 26 Nov 2015 21:53:01 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzEwMTMx?= =?utf-8?q?=3A_Fixed_deep_copying_of_minidom_documents=2E__Based_on_patch?= Message-ID: <20151126215301.81868.30961@psf.io> https://hg.python.org/cpython/rev/0eea57ddb75f changeset: 99374:0eea57ddb75f branch: 2.7 user: Serhiy Storchaka date: Thu Nov 26 23:48:30 2015 +0200 summary: Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. files: Lib/test/test_minidom.py | 97 ++++++++++++++------------ Lib/xml/dom/minicompat.py | 6 +- Misc/NEWS | 3 + 3 files changed, 59 insertions(+), 47 deletions(-) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1,5 +1,6 @@ # test for xml.dom.minidom +import copy import pickle from StringIO import StringIO from test.test_support import verbose, run_unittest, findfile @@ -14,7 +15,13 @@ tstfile = findfile("test.xml", subdir="xmltestdata") - +sample = ("\n" + "\n" + " \n" + "]> text\n" + " ") # The tests of DocumentType importing use these helpers to construct # the documents to work with, since not all DOM builders actually @@ -1377,52 +1384,54 @@ self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) + def assert_recursive_equal(self, doc, doc2): + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.assertEqual(n1.nodeType, n2.nodeType) + self.assertEqual(len(n1.childNodes), len(n2.childNodes)) + self.assertEqual(n1.nodeName, n2.nodeName) + self.assertFalse(n1.isSameNode(n2)) + self.assertFalse(n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.assertEqual(len(n1.entities), len(n2.entities)) + self.assertEqual(len(n1.notations), len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.assertEqual(no1.name, no2.name) + self.assertEqual(no1.publicId, no2.publicId) + self.assertEqual(no1.systemId, no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.assertEqual(e1.notationName, e2.notationName) + self.assertEqual(e1.publicId, e2.publicId) + self.assertEqual(e1.systemId, e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.assertTrue(n1.ownerDocument.isSameNode(doc)) + self.assertTrue(n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + def testPickledDocument(self): - doc = parseString("\n" - "\n" - " \n" - "]> text\n" - " ") - for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): + doc = parseString(sample) + for proto in range(pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(doc, proto) doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + self.assert_recursive_equal(doc, doc2) + + def testDeepcopiedDocument(self): + doc = parseString(sample) + doc2 = copy.deepcopy(doc) + self.assert_recursive_equal(doc, doc2) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -65,10 +65,10 @@ length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") - def __getstate__(self): - return list(self) - + # For backward compatibility def __setstate__(self, state): + if state is None: + state = [] self[:] = state diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -20,6 +20,9 @@ Library ------- +- Issue #10131: Fixed deep copying of minidom documents. Based on patch + by Marian Ganisin. + - Issue #25725: Fixed a reference leak in cPickle.loads() when unpickling invalid data including tuple instructions. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 16:53:01 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 26 Nov 2015 21:53:01 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzEwMTMx?= =?utf-8?q?=3A_Fixed_deep_copying_of_minidom_documents=2E__Based_on_patch?= Message-ID: <20151126215301.81864.36168@psf.io> https://hg.python.org/cpython/rev/aa304ad32292 changeset: 99375:aa304ad32292 branch: 3.4 parent: 99370:fa3c9faabfb0 user: Serhiy Storchaka date: Thu Nov 26 23:49:42 2015 +0200 summary: Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. files: Lib/test/test_minidom.py | 94 +++++++++------- Lib/test/test_xml_dom_minicompat.py | 36 ++++++ Lib/xml/dom/minicompat.py | 6 +- Misc/NEWS | 3 + 4 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1,5 +1,6 @@ # test for xml.dom.minidom +import copy import pickle from test.support import run_unittest, findfile import unittest @@ -11,6 +12,13 @@ tstfile = findfile("test.xml", subdir="xmltestdata") +sample = ("\n" + "\n" + " \n" + "]> text\n" + " ") # The tests of DocumentType importing use these helpers to construct # the documents to work with, since not all DOM builders actually @@ -1466,52 +1474,54 @@ self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) + def assert_recursive_equal(self, doc, doc2): + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.assertEqual(n1.nodeType, n2.nodeType) + self.assertEqual(len(n1.childNodes), len(n2.childNodes)) + self.assertEqual(n1.nodeName, n2.nodeName) + self.assertFalse(n1.isSameNode(n2)) + self.assertFalse(n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.assertEqual(len(n1.entities), len(n2.entities)) + self.assertEqual(len(n1.notations), len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.assertEqual(no1.name, no2.name) + self.assertEqual(no1.publicId, no2.publicId) + self.assertEqual(no1.systemId, no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.assertEqual(e1.notationName, e2.notationName) + self.assertEqual(e1.publicId, e2.publicId) + self.assertEqual(e1.systemId, e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.assertTrue(n1.ownerDocument.isSameNode(doc)) + self.assertTrue(n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + def testPickledDocument(self): - doc = parseString("\n" - "\n" - " \n" - "]> text\n" - " ") + doc = parseString(sample) for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(doc, proto) doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + self.assert_recursive_equal(doc, doc2) + + def testDeepcopiedDocument(self): + doc = parseString(sample) + doc2 = copy.deepcopy(doc) + self.assert_recursive_equal(doc, doc2) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -1,5 +1,6 @@ # Tests for xml.dom.minicompat +import copy import pickle import unittest @@ -89,6 +90,7 @@ node_list = NodeList() pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) # Non-empty NodeList. @@ -96,7 +98,41 @@ node_list.append(2) pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) + def test_nodelist_copy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIs(x, y) + + def test_nodelist_deepcopy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIsNot(x, y) + self.assertEqual(x, y) + if __name__ == '__main__': unittest.main() diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -64,10 +64,10 @@ length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") - def __getstate__(self): - return list(self) - + # For backward compatibility def __setstate__(self, state): + if state is None: + state = [] self[:] = state diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -113,6 +113,9 @@ Library ------- +- Issue #10131: Fixed deep copying of minidom documents. Based on patch + by Marian Ganisin. + - Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 16:53:06 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 26 Nov 2015 21:53:06 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2310131=3A_Fixed_deep_copying_of_minidom_documents=2E__?= =?utf-8?q?Based_on_patch?= Message-ID: <20151126215306.22408.53793@psf.io> https://hg.python.org/cpython/rev/5d6b2dc7e3d0 changeset: 99376:5d6b2dc7e3d0 branch: 3.5 parent: 99371:b55c006b79bc parent: 99375:aa304ad32292 user: Serhiy Storchaka date: Thu Nov 26 23:50:54 2015 +0200 summary: Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. files: Lib/test/test_minidom.py | 94 +++++++++------- Lib/test/test_xml_dom_minicompat.py | 36 ++++++ Lib/xml/dom/minicompat.py | 6 +- Misc/NEWS | 3 + 4 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1,5 +1,6 @@ # test for xml.dom.minidom +import copy import pickle from test.support import findfile import unittest @@ -11,6 +12,13 @@ tstfile = findfile("test.xml", subdir="xmltestdata") +sample = ("\n" + "\n" + " \n" + "]> text\n" + " ") # The tests of DocumentType importing use these helpers to construct # the documents to work with, since not all DOM builders actually @@ -1481,52 +1489,54 @@ self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) + def assert_recursive_equal(self, doc, doc2): + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.assertEqual(n1.nodeType, n2.nodeType) + self.assertEqual(len(n1.childNodes), len(n2.childNodes)) + self.assertEqual(n1.nodeName, n2.nodeName) + self.assertFalse(n1.isSameNode(n2)) + self.assertFalse(n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.assertEqual(len(n1.entities), len(n2.entities)) + self.assertEqual(len(n1.notations), len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.assertEqual(no1.name, no2.name) + self.assertEqual(no1.publicId, no2.publicId) + self.assertEqual(no1.systemId, no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.assertEqual(e1.notationName, e2.notationName) + self.assertEqual(e1.publicId, e2.publicId) + self.assertEqual(e1.systemId, e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.assertTrue(n1.ownerDocument.isSameNode(doc)) + self.assertTrue(n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + def testPickledDocument(self): - doc = parseString("\n" - "\n" - " \n" - "]> text\n" - " ") + doc = parseString(sample) for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(doc, proto) doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + self.assert_recursive_equal(doc, doc2) + + def testDeepcopiedDocument(self): + doc = parseString(sample) + doc2 = copy.deepcopy(doc) + self.assert_recursive_equal(doc, doc2) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -1,5 +1,6 @@ # Tests for xml.dom.minicompat +import copy import pickle import unittest @@ -89,6 +90,7 @@ node_list = NodeList() pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) # Non-empty NodeList. @@ -96,7 +98,41 @@ node_list.append(2) pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) + def test_nodelist_copy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIs(x, y) + + def test_nodelist_deepcopy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIsNot(x, y) + self.assertEqual(x, y) + if __name__ == '__main__': unittest.main() diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -64,10 +64,10 @@ length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") - def __getstate__(self): - return list(self) - + # For backward compatibility def __setstate__(self, state): + if state is None: + state = [] self[:] = state diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -20,6 +20,9 @@ Library ------- +- Issue #10131: Fixed deep copying of minidom documents. Based on patch + by Marian Ganisin. + - Issue #25725: Fixed a reference leak in pickle.loads() when unpickling invalid data including tuple instructions. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Thu Nov 26 16:53:07 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Thu, 26 Nov 2015 21:53:07 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2310131=3A_Fixed_deep_copying_of_minidom_document?= =?utf-8?q?s=2E__Based_on_patch?= Message-ID: <20151126215306.69578.90413@psf.io> https://hg.python.org/cpython/rev/9fcfdb53e8af changeset: 99377:9fcfdb53e8af parent: 99372:c6930661599b parent: 99376:5d6b2dc7e3d0 user: Serhiy Storchaka date: Thu Nov 26 23:52:34 2015 +0200 summary: Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. files: Lib/test/test_minidom.py | 94 +++++++++------- Lib/test/test_xml_dom_minicompat.py | 36 ++++++ Lib/xml/dom/minicompat.py | 6 +- Misc/NEWS | 3 + 4 files changed, 94 insertions(+), 45 deletions(-) diff --git a/Lib/test/test_minidom.py b/Lib/test/test_minidom.py --- a/Lib/test/test_minidom.py +++ b/Lib/test/test_minidom.py @@ -1,5 +1,6 @@ # test for xml.dom.minidom +import copy import pickle from test.support import findfile import unittest @@ -11,6 +12,13 @@ tstfile = findfile("test.xml", subdir="xmltestdata") +sample = ("\n" + "\n" + " \n" + "]> text\n" + " ") # The tests of DocumentType importing use these helpers to construct # the documents to work with, since not all DOM builders actually @@ -1481,52 +1489,54 @@ self.confirm(e.isSameNode(doc.getElementById("w")) and a2.isId) + def assert_recursive_equal(self, doc, doc2): + stack = [(doc, doc2)] + while stack: + n1, n2 = stack.pop() + self.assertEqual(n1.nodeType, n2.nodeType) + self.assertEqual(len(n1.childNodes), len(n2.childNodes)) + self.assertEqual(n1.nodeName, n2.nodeName) + self.assertFalse(n1.isSameNode(n2)) + self.assertFalse(n2.isSameNode(n1)) + if n1.nodeType == Node.DOCUMENT_TYPE_NODE: + len(n1.entities) + len(n2.entities) + len(n1.notations) + len(n2.notations) + self.assertEqual(len(n1.entities), len(n2.entities)) + self.assertEqual(len(n1.notations), len(n2.notations)) + for i in range(len(n1.notations)): + # XXX this loop body doesn't seem to be executed? + no1 = n1.notations.item(i) + no2 = n1.notations.item(i) + self.assertEqual(no1.name, no2.name) + self.assertEqual(no1.publicId, no2.publicId) + self.assertEqual(no1.systemId, no2.systemId) + stack.append((no1, no2)) + for i in range(len(n1.entities)): + e1 = n1.entities.item(i) + e2 = n2.entities.item(i) + self.assertEqual(e1.notationName, e2.notationName) + self.assertEqual(e1.publicId, e2.publicId) + self.assertEqual(e1.systemId, e2.systemId) + stack.append((e1, e2)) + if n1.nodeType != Node.DOCUMENT_NODE: + self.assertTrue(n1.ownerDocument.isSameNode(doc)) + self.assertTrue(n2.ownerDocument.isSameNode(doc2)) + for i in range(len(n1.childNodes)): + stack.append((n1.childNodes[i], n2.childNodes[i])) + def testPickledDocument(self): - doc = parseString("\n" - "\n" - " \n" - "]> text\n" - " ") + doc = parseString(sample) for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): s = pickle.dumps(doc, proto) doc2 = pickle.loads(s) - stack = [(doc, doc2)] - while stack: - n1, n2 = stack.pop() - self.confirm(n1.nodeType == n2.nodeType - and len(n1.childNodes) == len(n2.childNodes) - and n1.nodeName == n2.nodeName - and not n1.isSameNode(n2) - and not n2.isSameNode(n1)) - if n1.nodeType == Node.DOCUMENT_TYPE_NODE: - len(n1.entities) - len(n2.entities) - len(n1.notations) - len(n2.notations) - self.confirm(len(n1.entities) == len(n2.entities) - and len(n1.notations) == len(n2.notations)) - for i in range(len(n1.notations)): - # XXX this loop body doesn't seem to be executed? - no1 = n1.notations.item(i) - no2 = n1.notations.item(i) - self.confirm(no1.name == no2.name - and no1.publicId == no2.publicId - and no1.systemId == no2.systemId) - stack.append((no1, no2)) - for i in range(len(n1.entities)): - e1 = n1.entities.item(i) - e2 = n2.entities.item(i) - self.confirm(e1.notationName == e2.notationName - and e1.publicId == e2.publicId - and e1.systemId == e2.systemId) - stack.append((e1, e2)) - if n1.nodeType != Node.DOCUMENT_NODE: - self.confirm(n1.ownerDocument.isSameNode(doc) - and n2.ownerDocument.isSameNode(doc2)) - for i in range(len(n1.childNodes)): - stack.append((n1.childNodes[i], n2.childNodes[i])) + self.assert_recursive_equal(doc, doc2) + + def testDeepcopiedDocument(self): + doc = parseString(sample) + doc2 = copy.deepcopy(doc) + self.assert_recursive_equal(doc, doc2) def testSerializeCommentNodeWithDoubleHyphen(self): doc = create_doc_without_doctype() diff --git a/Lib/test/test_xml_dom_minicompat.py b/Lib/test/test_xml_dom_minicompat.py --- a/Lib/test/test_xml_dom_minicompat.py +++ b/Lib/test/test_xml_dom_minicompat.py @@ -1,5 +1,6 @@ # Tests for xml.dom.minicompat +import copy import pickle import unittest @@ -89,6 +90,7 @@ node_list = NodeList() pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) # Non-empty NodeList. @@ -96,7 +98,41 @@ node_list.append(2) pickled = pickle.dumps(node_list, proto) unpickled = pickle.loads(pickled) + self.assertIsNot(unpickled, node_list) self.assertEqual(unpickled, node_list) + def test_nodelist_copy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.copy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIs(x, y) + + def test_nodelist_deepcopy(self): + # Empty NodeList. + node_list = NodeList() + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + + # Non-empty NodeList. + node_list.append([1]) + node_list.append([2]) + copied = copy.deepcopy(node_list) + self.assertIsNot(copied, node_list) + self.assertEqual(copied, node_list) + for x, y in zip(copied, node_list): + self.assertIsNot(x, y) + self.assertEqual(x, y) + if __name__ == '__main__': unittest.main() diff --git a/Lib/xml/dom/minicompat.py b/Lib/xml/dom/minicompat.py --- a/Lib/xml/dom/minicompat.py +++ b/Lib/xml/dom/minicompat.py @@ -64,10 +64,10 @@ length = property(_get_length, _set_length, doc="The number of nodes in the NodeList.") - def __getstate__(self): - return list(self) - + # For backward compatibility def __setstate__(self, state): + if state is None: + state = [] self[:] = state diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -102,6 +102,9 @@ Library ------- +- Issue #10131: Fixed deep copying of minidom documents. Based on patch + by Marian Ganisin. + - Issue #7990: dir() on ElementTree.Element now lists properties: "tag", "text", "tail" and "attrib". Original patch by Santoso Wijaya. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 27 00:54:35 2015 From: python-checkins at python.org (nick.coghlan) Date: Fri, 27 Nov 2015 05:54:35 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_PEP_493=3A_First_draft_as_a_s?= =?utf-8?q?tandards_track_PEP?= Message-ID: <20151127055434.29810.73940@psf.io> https://hg.python.org/peps/rev/f602a47ea795 changeset: 6132:f602a47ea795 user: Nick Coghlan date: Fri Nov 27 15:51:43 2015 +1000 summary: PEP 493: First draft as a standards track PEP - now has 2 feature sections, and 3 backport recommendations - features are for a new Python API and environment setting - backports are all for targeting versions < 2.7.9 - Python 3 is excluded from scope files: pep-0493.txt | 333 ++++++++++++++++++++++++++++---------- 1 files changed, 240 insertions(+), 93 deletions(-) diff --git a/pep-0493.txt b/pep-0493.txt --- a/pep-0493.txt +++ b/pep-0493.txt @@ -1,78 +1,91 @@ PEP: 493 -Title: HTTPS verification recommendations for Python 2.7 redistributors +Title: HTTPS verification migration tools for Python 2.7 Version: $Revision$ Last-Modified: $Date$ Author: Nick Coghlan , Robert Kuska , Marc-Andr? Lemburg Status: Draft -Type: Informational +Type: Standards Track Content-Type: text/x-rst Created: 10-May-2015 +Python-Version: 2.7.12 Post-History: 06-Jul-2015, 11-Nov-2015, 24-Nov-2015 Abstract ======== -PEP 476 updated Python's default handling of HTTPS certificates to be -appropriate for communication over the public internet. The Python 2.7 long -term maintenance series was judged to be in scope for this change, with the -new behaviour introduced in the Python 2.7.9 maintenance release. +PEP 476 updated Python's default handling of HTTPS certificates in client +modules to align with certificate handling in web browsers, by validating +that the certificates received belonged to the server the client was attempting +to contact. The Python 2.7 long term maintenance series was judged to be in +scope for this change, with the new behaviour introduced in the Python 2.7.9 +maintenance release. -This PEP provides recommendations to downstream redistributors wishing to -provide a smoother migration experience when helping their users to manage -this change in Python's default behaviour. - -*Note that this PEP is not currently accepted, so it is a *proposed* -recommendation, rather than an active one.* +This has created a non-trivial barrier to adoption for affected Python 2.7 +maintenance releases, so this PEP proposes additional Python 2.7 specific +features that allow system administrators and other users to more easily +decouple the decision to verify server certificates in HTTPS client modules +from the decision to update to newer Python 2.7 maintenance releases. Rationale ========= -PEP 476 changed Python's default behaviour to better match the needs and -expectations of developers operating over the public internet, a category -which appears to include most new Python developers. It is the position of -the authors of this PEP that this was a correct decision. +PEP 476 changed Python's default behaviour to align with expectations +established by web browsers in regards to the semantics of HTTPS URLs: +starting with Python 2.7.9 and 3.4.3, HTTPS clients in the standard library +validate server certificates by default. However, it is also the case that this change *does* cause problems for infrastructure administrators operating private intranets that rely on self-signed certificates, or otherwise encounter problems with the new default certificate verification settings. -The long term answer for such environments is to update their internal -certificate management to at least match the standards set by the public -internet, but in the meantime, it is desirable to offer these administrators -a way to continue receiving maintenance updates to the Python 2.7 series, -without having to gate that on upgrades to their certificate management -infrastructure. +To manage these kinds of situations, web browsers provide users with "click +through" warnings that allow the user to add the server's certificate to the +browser's certificate store. Network client tools like ``curl`` and ``wget`` +offer options to switch off certificate checking entirely (by way of +``curl --insecure`` and ``wget --no-check-certificate``, respectively). -PEP 476 did attempt to address this question, by covering how to revert the -new settings process wide by monkeypatching the ``ssl`` module to restore the +At a different layer of the technology stack, Linux security modules like +`SELinux` and `AppArmor`, while enabled by default by distribution vendors, +offer relatively straightforward mechanisms for turning them off. + +At the moment, no such convenient mechanisms exist to disable Python's +default certificate checking for a whole process. + +PEP 476 did attempt to address this question, by covering how to revert to the +old settings process wide by monkeypatching the ``ssl`` module to restore the old behaviour. Unfortunately, the ``sitecustomize.py`` based technique proposed to allow system administrators to disable the feature by default in their Standard Operating Environment definition has been determined to be -insufficient in at least some cases. The specific case of interest to the -authors of this PEP is the one where a Linux distributor aims to provide -their users with a +insufficient in at least some cases. The specific case that led to the +initial creation of this PEP is the one where a Linux distributor aims to +provide their users with a `smoother migration path `__ than the standard one provided by consuming upstream CPython 2.7 releases directly, but other potential challenges have also been pointed out with updating embedded Python runtimes and other user level installations of Python. Rather than allowing a plethora of mutually incompatibile migration techniques -to bloom, this PEP proposes two alternative approaches that redistributors -may take when addressing these problems. Redistributors may choose to implement -one, both, or neither of these approaches based on their assessment of the -needs of their particular userbase. +to bloom, this PEP proposes an additional feature to be added to Python 2.7.12 +to make it easier to revert a process to the past behaviour of skipping +certificate validation in HTTPS client modules. It also provides additional +recommendations to redistributors backporting these features to versions of +Python prior to Python 2.7.9. -These designs are being proposed as a recommendation for redistributors, rather -than as new upstream features, as they are needed purely to support legacy -environments migrating from older versions of Python 2.7. Neither approach -is being proposed as an upstream Python 2.7 feature, nor as a feature in any -version of Python 3 (whether published directly by the Python Software -Foundation or by a redistributor). +These designs are being proposed purely as tools for helping to manage the +transition to the new default certificate handling behaviour in the context +of Python 2.7. They are not being proposed as new features for Python 3, as +it is expected that the vast majority of client applications affected by this +problem without the ability to update the application itself will be Python 2 +applications. + +It would likely be desirable for a future version of Python 3 to allow default +certificate handling for secure protocols to be configurable on a per-protocol +basis, but that question is beyond the scope of this PEP. Alternatives ------------ @@ -84,20 +97,20 @@ * Continuing to rebase on new Python 2.7.x releases, while providing no additional assistance beyond the mechanisms defined in PEP 476 in migrating from unchecked to checked hostnames in standard library HTTPS clients -* Gating availability of the improved default handling of HTTPS connections on - upgrading from Python 2 to Python 3 -* For Linux distribution vendors, gating availability of the improved default +* Gating availability of the changes in default handling of HTTPS connections + on upgrading from Python 2 to Python 3 +* For Linux distribution vendors, gating availability of the changes in default handling of HTTPS connections on upgrading to a new operating system version -* Implementing one or both of the design suggestions described in this PEP, +* Implementing one or both of the backport suggestions described in this PEP, regardless of the formal status of the PEP Requirements for capability detection ===================================== -As these recommendations are intended to cover backports to earlier Python +As the proposals in this PEP aim to facilitate backports to earlier Python versions, the Python version number cannot be used as a reliable means for -detecting them. Instead, the recommendations are defined to allow the presence +detecting them. Instead, they are designed to allow the presence or absence of the feature to be determined using the following technique:: python -c "import ssl; ssl._relevant_attribute" @@ -108,57 +121,99 @@ The marker attributes are prefixed with an underscore to indicate the implementation dependent nature of these capabilities - not all Python distributions will offer them, only those that are providing a multi-stage -migration process from the legacy HTTPS handling to the new default behaviour. +migration process from the original Python 2.7 HTTPS handling to the new +default behaviour. +Feature: Configuration API +========================== -Recommendation for an environment variable based security downgrade -=================================================================== +This change is proposed for inclusion in CPython 2.7.12 and later CPython 2.7.x +releases. It consists of a new ``ssl._verify_https_certificates()`` to specify +the default handling of HTTPS certificates in standard library client libraries. -Some redistributors may wish to provide a per-application option to disable -certificate verification in selected applications that run on or embed CPython -without needing to modify the application itself. +It is not proposed to forward port this change to Python 3, so Python 3 +applications that need to support skipping certificate verification will still +need to define their own suitable security context. -In these cases, a configuration mechanism is needed that provides: +Feature detection +----------------- -* an opt-out model that allows certificate verification to be selectively - turned off for particular applications after upgrading to a version of - Python that verifies certificates by default -* the ability for all users to configure this setting on a per-application - basis, rather than on a per-system, or per-Python-installation basis +The marker attribute on the ``ssl`` module related to this feature is the +``ssl._verify_https_certificates`` function itself. -This approach may be used for any redistributor provided version of Python 2.7, -including those that advertise themselves as providing Python 2.7.9 or later. +Specification +------------- +The ``ssl._verify_https_certificates`` function will work as follows:: -Required marker attribute -------------------------- + def _verify_https_certificates(enable=True): + """Verify server HTTPS certificates by default?""" + global _create_default_https_context + if enable: + _create_default_https_context = create_default_context + else: + _create_default_https_context = _create_unverified_context -The required marker attribute on the ``ssl`` module when implementing this -recommendation is:: +If called without arguments, or with ``enable`` set to a true value, then +standard library client modules will subsequently verify HTTPS certificates by default, otherwise they will skip verification. - _https_verify_envvar = 'PYTHONHTTPSVERIFY' +If called with ``enable`` set to a false value, then standard library client +modules will subsequently skip verifying HTTPS certificates by default. + +Security Considerations +----------------------- + +The inclusion of this feature will allow security sensitive applications to +include the following forward-compatible snippet in their code:: + + if hasattr(ssl, "_verify_https_certificates"): + ssl._verify_https_certificates() + +Some developers may also choose to opt out of certificate checking using +``ssl._verify_https_certificates(enable=False)``. This doesn't introduce any +major new security concerns, as monkeypatching the affected internal APIs was +already possible. + + +Feature: environment based configuration +======================================== + +This change is proposed for inclusion in CPython 2.7.12 and later CPython 2.7.x +releases. It consists of a new ``PYTHONHTTPSVERIFY`` environment variable that +allows the default verification to be disabled without modifying the +application source code (which may not even be available in cases of +bytecode-only application distribution) + +It is not proposed to forward port this change to Python 3, so Python 3 +applications that need to support skipping certificate verification will still +need to define their own suitable security context. + +Feature detection +----------------- + +The marker attribute on the ``ssl`` module related to this feature is: + +* the ``ssl._https_verify_envvar`` attribute, giving the name of environment + variable affecting the default behaviour This not only makes it straightforward to detect the presence (or absence) of the capability, it also makes it possible to programmatically determine the relevant environment variable name. +Specification +------------- -Recommended modifications to the Python standard library --------------------------------------------------------- +Rather than always defaulting to the use of ``ssl.create_default_context``, +the ``ssl`` module will be modified to: -The recommended approach to providing a per-application configuration setting -for HTTPS certificate verification that doesn't require modifications to the -application itself is to: - -* modify the ``ssl`` module to read the ``PYTHONHTTPSVERIFY`` environment - variable when the module is first imported into a Python process +* read the ``PYTHONHTTPSVERIFY`` environment variable when the module is first + imported into a Python process * set the ``ssl._create_default_https_context`` function to be an alias for ``ssl._create_unverified_context`` if this environment variable is present and set to ``'0'`` * otherwise, set the ``ssl._create_default_https_context`` function to be an alias for ``ssl.create_default_context`` as usual - Example implementation ---------------------- @@ -175,14 +230,13 @@ _create_default_https_context = _get_https_context_factory() - Security Considerations ----------------------- -Relative to an unmodified version of CPython 2.7.9 or later, this approach -does introduce a new downgrade attack against the default security settings -that potentially allows a sufficiently determined attacker to revert Python -to the vulnerable configuration used in CPython 2.7.8 and earlier releases. +Relative to the behaviour in Python 3.4.3+ and Python 2.7.9->2.7.11, this +approach does introduce a new downgrade attack against the default security +settings that potentially allows a sufficiently determined attacker to revert +Python to the default behaviour used in CPython 2.7.8 and earlier releases. However, such an attack requires the ability to modify the execution environment of a Python process prior to the import of the ``ssl`` module, and any attacker with such access would already be able to modify the @@ -191,13 +245,13 @@ Interaction with Python virtual environments -------------------------------------------- -This setting is read directly from the process environment, and hence works -the same way regardless of whether or not the interpreter is being run inside -an activated Python virtual environment. +The default setting is read directly from the process environment, and hence +works the same way regardless of whether or not the interpreter is being run +inside an activated Python virtual environment. -Recommendation for backporting to earlier Python versions -========================================================= +Backporting PEP 476 to earlier Python versions +============================================== Some redistributors, most notably Linux distributions, may choose to backport the PEP 476 HTTPS verification changes to modified Python versions based on @@ -214,17 +268,21 @@ installations that have been explicitly configured to skip verifying HTTPS certificates by default -This approach should not be used for any Python installation that advertises +As it only affects backports to earlier releases of Python 2.7, this change is +not proposed for inclusion in upstream CPython, but rather is offered as +guidance to redistributors to reduce the likelihood of multiple mutually +incompatible approaches to backporting being adopted. + +This approach SHOULD NOT be used for any Python installation that advertises itself as providing Python 2.7.9 or later, as most Python users will have the reasonable expectation that all such environments will validate HTTPS certificates by default. -Required marker attribute -------------------------- +Feature detection +----------------- -The required marker attribute on the ``ssl`` module when implementing this -recommendation is:: +The marker attribute on the ``ssl`` module related to this feature is:: _cert_verification_config = '' @@ -320,7 +378,7 @@ Security Considerations ----------------------- -The specific recommendations for the backporting case are designed to work for +The specific recommendations for this backporting case are designed to work for privileged, security sensitive processes, even those being run in the following locked down configuration: @@ -356,19 +414,108 @@ processes using that interpreter, regardless of whether or not the interpreter is being run inside an activated Python virtual environment. +Origins of this recommendation +------------------------------ -Combining the recommendations -============================= +This recommendation is based on the backporting approach adopted for Red Hat +Enterprise Linux 7.2, as published in the original July 2015 draft of this PEP +and described in detail in `this KnowledgeBase article +`__. Red Hat's patches implementing +this backport for Python 2.7.5 can be found in the `CentOS git repository +`__. -If a redistributor chooses to implement both recommendations, then the -environment variable should take precedence over the system-wide configuration -setting. This allows the setting to be changed for a given user, virtual -environment or application, regardless of the system-wide default behaviour. + +Backporting this PEP to earlier Python versions +=============================================== + +The configuration file based backport described above is designed to cover +backporting the PEP 476 changes to default certificate handling without the +additional configuration mechanisms defined in this PEP. + +If this PEP is accepted, then an additional backporting option becomes +available, which is to backport the per-process configuration mechanisms +defined in this PEP, without backporting the ability to change the default behaviour of the overall Python installation. + +Such a backport would differ from the mechanism proposed in this PEP solely in +the default behaviour when ``PYTHONHTTPSVERIFY`` was not set at all: it would +continue to default to skipping certificate validation. In this case, if the ``PYTHONHTTPSVERIFY`` environment variable is defined, and set to anything *other* than ``'0'``, then HTTPS certificate verification should be enabled. + +Feature detection +----------------- + +There's no specific attribute indicating that this situation applies. Rather, +it is indicated by the ``ssl._verify_https_certificates`` and +``ssl._https_verify_envvar`` attributes being present in a Python version that +is nominally older than Python 2.7.9. + +Specification +------------- + +Implementing this backport involves backporting the changes in PEP 466, 476 and +this PEP, with the following change to the handling of the +``PYTHONHTTPSVERIFY`` environment variable in the ``ssl`` module: + +* read the ``PYTHONHTTPSVERIFY`` environment variable when the module is first + imported into a Python process +* set the ``ssl._create_default_https_context`` function to be an alias for + ``ssl.create_default_context`` if this environment variable is present + and set to any value other than ``'0'`` +* otherwise, set the ``ssl._create_default_https_context`` function to be an + alias for ``ssl._create_unverified_context`` + +Example implementation +---------------------- + +:: + + _https_verify_envvar = 'PYTHONHTTPSVERIFY' + + def _get_https_context_factory(): + if not sys.flags.ignore_environment: + config_setting = os.environ.get(_https_verify_envvar) + if config_setting != '0': + return create_default_context + return _create_unverified_context + + _create_default_https_context = _get_https_context_factory() + + def _disable_https_default_verification(): + """Skip verification of HTTPS certificates by default""" + global _create_default_https_context + _create_default_https_context = _create_unverified_context + +Security Considerations +----------------------- + +This change would be a strict security upgrade for any Python version that +currently defaults to skipping certificate validation in standard library +HTTPS clients. The technical trade-offs to be taken into account relate largely +to the magnitude of the PEP 466 backport also required rather than to anything +security related. + +Interaction with Python virtual environments +-------------------------------------------- + +The default setting is read directly from the process environment, and hence +works the same way regardless of whether or not the interpreter is being run +inside an activated Python virtual environment. + + +Recommendation for combined feature backports +============================================= + +If a redistributor chooses to backport the environment variable based +configuration setting from this PEP to a modified Python version that also +implements the configuration file based PEP 476 , then the environment +variable should take precedence over the system-wide configuration setting. +This allows the setting to be changed for a given user or application, +regardless of the installation-wide default behaviour. + Example implementation ---------------------- -- Repository URL: https://hg.python.org/peps From python-checkins at python.org Fri Nov 27 02:22:05 2015 From: python-checkins at python.org (zach.ware) Date: Fri, 27 Nov 2015 07:22:05 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzIzOTE0?= =?utf-8?q?=3A_Fix_test=5Fxpickle_with_python_2=2E4_and_2=2E5?= Message-ID: <20151127072204.29812.40575@psf.io> https://hg.python.org/cpython/rev/322060740b64 changeset: 99378:322060740b64 branch: 2.7 parent: 99374:0eea57ddb75f user: Zachary Ware date: Fri Nov 27 01:21:51 2015 -0600 summary: Issue #23914: Fix test_xpickle with python 2.4 and 2.5 Remove 'b' prefix from strings, remove unused import. files: Lib/test/pickletester.py | 105 +++++++++++++------------- 1 files changed, 52 insertions(+), 53 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -7,7 +7,7 @@ import pickletools import copy_reg -from test.test_support import TestFailed, verbose, have_unicode, TESTFN, captured_stdout +from test.test_support import TestFailed, verbose, have_unicode, TESTFN try: from test.test_support import _2G, _1M, precisionbigmemtest except ImportError: @@ -636,41 +636,41 @@ def test_bad_stack(self): badpickles = [ - b'0.', # POP - b'1.', # POP_MARK - b'2.', # DUP - # b'(2.', # PyUnpickler doesn't raise - b'R.', # REDUCE - b')R.', - b'a.', # APPEND - b'Na.', - b'b.', # BUILD - b'Nb.', - b'd.', # DICT - b'e.', # APPENDS - # b'(e.', # PyUnpickler raises AttributeError - b'i__builtin__\nlist\n.', # INST - b'l.', # LIST - b'o.', # OBJ - b'(o.', - b'p1\n.', # PUT - b'q\x00.', # BINPUT - b'r\x00\x00\x00\x00.', # LONG_BINPUT - b's.', # SETITEM - b'Ns.', - b'NNs.', - b't.', # TUPLE - b'u.', # SETITEMS - b'(u.', - b'}(Nu.', - b'\x81.', # NEWOBJ - b')\x81.', - b'\x85.', # TUPLE1 - b'\x86.', # TUPLE2 - b'N\x86.', - b'\x87.', # TUPLE3 - b'N\x87.', - b'NN\x87.', + '0.', # POP + '1.', # POP_MARK + '2.', # DUP + # '(2.', # PyUnpickler doesn't raise + 'R.', # REDUCE + ')R.', + 'a.', # APPEND + 'Na.', + 'b.', # BUILD + 'Nb.', + 'd.', # DICT + 'e.', # APPENDS + # '(e.', # PyUnpickler raises AttributeError + 'i__builtin__\nlist\n.', # INST + 'l.', # LIST + 'o.', # OBJ + '(o.', + 'p1\n.', # PUT + 'q\x00.', # BINPUT + 'r\x00\x00\x00\x00.', # LONG_BINPUT + 's.', # SETITEM + 'Ns.', + 'NNs.', + 't.', # TUPLE + 'u.', # SETITEMS + '(u.', + '}(Nu.', + '\x81.', # NEWOBJ + ')\x81.', + '\x85.', # TUPLE1 + '\x86.', # TUPLE2 + 'N\x86.', + '\x87.', # TUPLE3 + 'N\x87.', + 'NN\x87.', ] for p in badpickles: try: @@ -681,25 +681,24 @@ def test_bad_mark(self): badpickles = [ - b'c__builtin__\nlist\n)(R.', # REDUCE - b'c__builtin__\nlist\n()R.', - b']N(a.', # APPEND - b'cexceptions\nValueError\n)R}(b.', # BUILD - b'cexceptions\nValueError\n)R(}b.', - b'(Nd.', # DICT - b'}NN(s.', # SETITEM - b'}N(Ns.', - b'c__builtin__\nlist\n)(\x81.', # NEWOBJ - b'c__builtin__\nlist\n()\x81.', - b'N(\x85.', # TUPLE1 - b'NN(\x86.', # TUPLE2 - b'N(N\x86.', - b'NNN(\x87.', # TUPLE3 - b'NN(N\x87.', - b'N(NN\x87.', + 'c__builtin__\nlist\n)(R.', # REDUCE + 'c__builtin__\nlist\n()R.', + ']N(a.', # APPEND + 'cexceptions\nValueError\n)R}(b.', # BUILD + 'cexceptions\nValueError\n)R(}b.', + '(Nd.', # DICT + '}NN(s.', # SETITEM + '}N(Ns.', + 'c__builtin__\nlist\n)(\x81.', # NEWOBJ + 'c__builtin__\nlist\n()\x81.', + 'N(\x85.', # TUPLE1 + 'NN(\x86.', # TUPLE2 + 'N(N\x86.', + 'NNN(\x87.', # TUPLE3 + 'NN(N\x87.', + 'N(NN\x87.', ] for p in badpickles: - # PyUnpickler prints reduce errors to stdout try: self.loads(p) except (IndexError, AttributeError, TypeError, -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Fri Nov 27 02:46:45 2015 From: python-checkins at python.org (nick.coghlan) Date: Fri, 27 Nov 2015 07:46:45 +0000 Subject: [Python-checkins] =?utf-8?q?peps=3A_PEP_493=3A_make_word_order_co?= =?utf-8?q?nsistent?= Message-ID: <20151127074645.31391.19238@psf.io> https://hg.python.org/peps/rev/3cf229a9457a changeset: 6133:3cf229a9457a user: Nick Coghlan date: Fri Nov 27 17:46:37 2015 +1000 summary: PEP 493: make word order consistent files: pep-0493.txt | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pep-0493.txt b/pep-0493.txt --- a/pep-0493.txt +++ b/pep-0493.txt @@ -128,7 +128,7 @@ ========================== This change is proposed for inclusion in CPython 2.7.12 and later CPython 2.7.x -releases. It consists of a new ``ssl._verify_https_certificates()`` to specify +releases. It consists of a new ``ssl._https_verify_certificates()`` to specify the default handling of HTTPS certificates in standard library client libraries. It is not proposed to forward port this change to Python 3, so Python 3 @@ -139,14 +139,14 @@ ----------------- The marker attribute on the ``ssl`` module related to this feature is the -``ssl._verify_https_certificates`` function itself. +``ssl._https_verify_certificates`` function itself. Specification ------------- -The ``ssl._verify_https_certificates`` function will work as follows:: +The ``ssl._https_verify_certificates`` function will work as follows:: - def _verify_https_certificates(enable=True): + def _https_verify_certificates(enable=True): """Verify server HTTPS certificates by default?""" global _create_default_https_context if enable: @@ -166,11 +166,11 @@ The inclusion of this feature will allow security sensitive applications to include the following forward-compatible snippet in their code:: - if hasattr(ssl, "_verify_https_certificates"): - ssl._verify_https_certificates() + if hasattr(ssl, "_https_verify_certificates"): + ssl._https_verify_certificates() Some developers may also choose to opt out of certificate checking using -``ssl._verify_https_certificates(enable=False)``. This doesn't introduce any +``ssl._https_verify_certificates(enable=False)``. This doesn't introduce any major new security concerns, as monkeypatching the affected internal APIs was already possible. @@ -449,7 +449,7 @@ ----------------- There's no specific attribute indicating that this situation applies. Rather, -it is indicated by the ``ssl._verify_https_certificates`` and +it is indicated by the ``ssl._https_verify_certificates`` and ``ssl._https_verify_envvar`` attributes being present in a Python version that is nominally older than Python 2.7.9. -- Repository URL: https://hg.python.org/peps From solipsis at pitrou.net Fri Nov 27 03:43:30 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 27 Nov 2015 08:43:30 +0000 Subject: [Python-checkins] Daily reference leaks (9fcfdb53e8af): sum=4 Message-ID: <20151127084330.22398.77769@psf.io> results for 9fcfdb53e8af on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogGMV3oi', '--timeout', '7200'] From lp_benchmark_robot at intel.com Fri Nov 27 09:17:46 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 27 Nov 2015 14:17:46 +0000 Subject: [Python-checkins] Benchmark Results for Python Default 2015-11-27 Message-ID: Results for project Python default, build date 2015-11-27 04:02:13 +0000 commit: 9fcfdb53e8af859b86bd8dfd84368c015f88f659 revision date: 2015-11-26 21:52:34 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v3.4.3, with hash b4cbecbc0781e89a309d03b60a1f75f8499250e6 from 2015-02-25 12:15:33+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.40% 1.31% 8.78% 17.17% :-| pybench 0.09% 0.02% -1.96% 9.07% :-( regex_v8 2.74% 0.19% -4.58% 5.60% :-| nbody 0.12% 0.01% 0.11% 8.87% :-| json_dump_v2 0.26% -0.49% 0.10% 11.57% :-| normal_startup 0.95% -0.22% 0.38% 4.99% ---------------------------------------------------------------------------------- Note: Benchmark results are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From lp_benchmark_robot at intel.com Fri Nov 27 09:18:13 2015 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 27 Nov 2015 14:18:13 +0000 Subject: [Python-checkins] Benchmark Results for Python 2.7 2015-11-27 Message-ID: Results for project Python 2.7, build date 2015-11-27 04:49:19 +0000 commit: 0eea57ddb75f1d0a6ef3fbc762d62d016cf3c010 revision date: 2015-11-26 21:48:30 +0000 environment: Haswell-EP cpu: Intel(R) Xeon(R) CPU E5-2699 v3 @ 2.30GHz 2x18 cores, stepping 2, LLC 45 MB mem: 128 GB os: CentOS 7.1 kernel: Linux 3.10.0-229.4.2.el7.x86_64 Baseline results were generated using release v2.7.10, with hash 15c95b7d81dcf821daade360741e00714667653f from 2015-05-23 16:02:14+00:00 ---------------------------------------------------------------------------------- benchmark relative change since change since current rev run std_dev* last run baseline with PGO ---------------------------------------------------------------------------------- :-) django_v2 0.41% 0.12% 2.10% 9.53% :-) pybench 0.22% 0.05% 6.16% 7.71% :-( regex_v8 0.91% 0.34% -2.49% 8.56% :-) nbody 0.13% -0.01% 9.35% 4.40% :-) json_dump_v2 0.30% -0.04% 2.12% 15.41% :-| normal_startup 1.79% 0.11% -1.50% 2.54% :-| ssbench 0.34% 0.10% 0.19% 1.90% ---------------------------------------------------------------------------------- Note: Benchmark results for ssbench are measured in requests/second while all other are measured in seconds. * Relative Standard Deviation (Standard Deviation/Average) Our lab does a nightly source pull and build of the Python project and measures performance changes against the previous stable version and the previous nightly measurement. This is provided as a service to the community so that quality issues with current hardware can be identified quickly. Intel technologies' features and benefits depend on system configuration and may require enabled hardware, software or service activation. Performance varies depending on system configuration. From python-checkins at python.org Fri Nov 27 12:38:29 2015 From: python-checkins at python.org (zach.ware) Date: Fri, 27 Nov 2015 17:38:29 +0000 Subject: [Python-checkins] =?utf-8?q?benchmarks=3A_Issue_=2325719=3A_Depre?= =?utf-8?q?cate_spitfire_benchmark=2E?= Message-ID: <20151127173827.59389.26150@psf.io> https://hg.python.org/benchmarks/rev/75751d838789 changeset: 236:75751d838789 user: Zachary Ware date: Fri Nov 27 11:38:22 2015 -0600 summary: Issue #25719: Deprecate spitfire benchmark. It makes use of psycho, which does not support 64bit platforms at all and is long dead. Patch by Florin Papa. files: perf.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/perf.py b/perf.py --- a/perf.py +++ b/perf.py @@ -2318,7 +2318,7 @@ "formatted_logging"], # These are removed from the "all" group "deprecated": ["chameleon", "django", "iterative_count", - "json_dump", "mako", "threaded_count"], + "json_dump", "mako", "threaded_count", "spitfire"], } # Calculate set of 2-and-3 compatible benchmarks. -- Repository URL: https://hg.python.org/benchmarks From python-checkins at python.org Fri Nov 27 17:55:37 2015 From: python-checkins at python.org (victor.stinner) Date: Fri, 27 Nov 2015 22:55:37 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogQ2xvc2VzICMyNTc0?= =?utf-8?q?2=3A_locale=2Esetlocale=28=29_now_accepts_a_Unicode_string_for_?= =?utf-8?q?its_second?= Message-ID: <20151127225536.59407.86180@psf.io> https://hg.python.org/cpython/rev/7841e9b614eb changeset: 99379:7841e9b614eb branch: 2.7 user: Victor Stinner date: Fri Nov 27 23:54:36 2015 +0100 summary: Closes #25742: locale.setlocale() now accepts a Unicode string for its second parameter. files: Lib/locale.py | 6 +++++- Lib/test/test_locale.py | 10 ++++++++++ Misc/NEWS | 3 +++ 3 files changed, 18 insertions(+), 1 deletions(-) diff --git a/Lib/locale.py b/Lib/locale.py --- a/Lib/locale.py +++ b/Lib/locale.py @@ -18,6 +18,10 @@ import operator import functools +# keep a copy of the builtin str type, because 'str' name is overriden +# in globals by a function below +_str = str + try: _unicode = unicode except NameError: @@ -573,7 +577,7 @@ category may be given as one of the LC_* values. """ - if locale and type(locale) is not type(""): + if locale and not isinstance(locale, (_str, _unicode)): # convert to string locale = normalize(_build_localename(locale)) return _setlocale(category, locale) diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -493,6 +493,16 @@ # longer accept unicode strings. self.assertEqual(locale.normalize(u'en_US'), 'en_US.ISO8859-1') + def test_setlocale_unicode(self): + old_loc = locale.getlocale(locale.LC_ALL) + try: + user_locale = locale.setlocale(locale.LC_ALL, '') + unicode_locale = user_locale.decode('utf-8') + user_locale2 = locale.setlocale(locale.LC_ALL, unicode_locale) + self.assertEqual(user_locale, user_locale2) + finally: + locale.setlocale(locale.LC_ALL, old_loc) + def test_main(): tests = [ diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -20,6 +20,9 @@ Library ------- +- Issue #25742: :func:`locale.setlocale` now accepts a Unicode string for + its second parameter. + - Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sat Nov 28 03:42:35 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 28 Nov 2015 08:42:35 +0000 Subject: [Python-checkins] Daily reference leaks (9fcfdb53e8af): sum=7 Message-ID: <20151128084234.59387.49765@psf.io> results for 9fcfdb53e8af on branch "default" -------------------------------------------- test_asyncio leaked [0, 3, 0] memory blocks, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogx_IaGX', '--timeout', '7200'] From python-checkins at python.org Sat Nov 28 12:25:11 2015 From: python-checkins at python.org (r.david.murray) Date: Sat, 28 Nov 2015 17:25:11 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_=2325485=3A_Add_context_ma?= =?utf-8?q?nager_support_to_Telnet_class=2E?= Message-ID: <20151128172510.22398.33974@psf.io> https://hg.python.org/cpython/rev/277824f2d133 changeset: 99380:277824f2d133 parent: 99377:9fcfdb53e8af user: R David Murray date: Sat Nov 28 12:24:52 2015 -0500 summary: #25485: Add context manager support to Telnet class. Patch by St?phane Wirtel. files: Doc/library/telnetlib.rst | 11 +++++++++++ Doc/whatsnew/3.6.rst | 7 +++++++ Lib/telnetlib.py | 15 ++++++++++----- Lib/test/test_telnetlib.py | 5 +++++ Misc/NEWS | 2 ++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Doc/library/telnetlib.rst b/Doc/library/telnetlib.rst --- a/Doc/library/telnetlib.rst +++ b/Doc/library/telnetlib.rst @@ -43,6 +43,17 @@ :exc:`EOFError` when the end of the connection is read, because they can return an empty string for other reasons. See the individual descriptions below. + A :class:`Telnet` object is a context manager and can be used in a + :keyword:`with` statement. When the :keyword:`with` block ends, the + :meth:`close` method is called:: + + >>> from telnetlib import Telnet + >>> with Telnet('localhost', 23) as tn: + ... tn.interact() + ... + + .. versionchanged:: 3.6 Context manager support added + .. seealso:: diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -125,6 +125,13 @@ an instance were excluded. (Contributed by Martin Panter in :issue:`25590`.) +telnetlib +--------- + +:class:`~telnetlib.Telnet` is now a context manager (contributed by +St?phane Wirtel in :issue:`25485`). + + urllib.robotparser ------------------ diff --git a/Lib/telnetlib.py b/Lib/telnetlib.py --- a/Lib/telnetlib.py +++ b/Lib/telnetlib.py @@ -637,6 +637,12 @@ raise EOFError return (-1, None, text) + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + def test(): """Test program for telnetlib. @@ -660,11 +666,10 @@ port = int(portstr) except ValueError: port = socket.getservbyname(portstr, 'tcp') - tn = Telnet() - tn.set_debuglevel(debuglevel) - tn.open(host, port, timeout=0.5) - tn.interact() - tn.close() + with Telnet() as tn: + tn.set_debuglevel(debuglevel) + tn.open(host, port, timeout=0.5) + tn.interact() if __name__ == '__main__': test() diff --git a/Lib/test/test_telnetlib.py b/Lib/test/test_telnetlib.py --- a/Lib/test/test_telnetlib.py +++ b/Lib/test/test_telnetlib.py @@ -42,6 +42,11 @@ telnet = telnetlib.Telnet(HOST, self.port) telnet.sock.close() + def testContextManager(self): + with telnetlib.Telnet(HOST, self.port) as tn: + self.assertIsNotNone(tn.get_socket()) + self.assertIsNone(tn.get_socket()) + def testTimeoutDefault(self): self.assertTrue(socket.getdefaulttimeout() is None) socket.setdefaulttimeout(30) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ Core and Builtins ----------------- +- Issue #25485: telnetlib.Telnet is now a context manager. + - Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside __getattr__. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sat Nov 28 17:57:03 2015 From: python-checkins at python.org (martin.panter) Date: Sat, 28 Nov 2015 22:57:03 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=2325754=3A_Allow_te?= =?utf-8?q?st=5Frlcompleter_to_be_run_multiple_times?= Message-ID: <20151128225703.87863.24603@psf.io> https://hg.python.org/cpython/rev/2e889344436e changeset: 99381:2e889344436e user: Martin Panter date: Sat Nov 28 22:38:24 2015 +0000 summary: Issue #25754: Allow test_rlcompleter to be run multiple times files: Lib/test/test_rlcompleter.py | 13 +++++++------ 1 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_rlcompleter.py b/Lib/test/test_rlcompleter.py --- a/Lib/test/test_rlcompleter.py +++ b/Lib/test/test_rlcompleter.py @@ -1,4 +1,5 @@ import unittest +from unittest.mock import patch import builtins import rlcompleter @@ -72,12 +73,12 @@ self.assertIn('CompleteMe.__name__', matches) self.assertIn('CompleteMe.__new__(', matches) - CompleteMe.me = CompleteMe - self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'), - ['CompleteMe.me.me.spam']) - self.assertEqual(self.completer.attr_matches('egg.s'), - ['egg.{}('.format(x) for x in dir(str) - if x.startswith('s')]) + with patch.object(CompleteMe, "me", CompleteMe, create=True): + self.assertEqual(self.completer.attr_matches('CompleteMe.me.me.sp'), + ['CompleteMe.me.me.spam']) + self.assertEqual(self.completer.attr_matches('egg.s'), + ['egg.{}('.format(x) for x in dir(str) + if x.startswith('s')]) def test_excessive_getattr(self): # Ensure getattr() is invoked no more than once per attribute -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Sun Nov 29 03:42:33 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 29 Nov 2015 08:42:33 +0000 Subject: [Python-checkins] Daily reference leaks (2e889344436e): sum=8 Message-ID: <20151129084233.29812.99742@psf.io> results for 2e889344436e on branch "default" -------------------------------------------- test_asyncio leaked [3, 0, 0] memory blocks, sum=3 test_functools leaked [0, 2, 2] memory blocks, sum=4 test_smtplib leaked [0, 1, 0] references, sum=1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogsO_r6H', '--timeout', '7200'] From python-checkins at python.org Sun Nov 29 06:14:41 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 11:14:41 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NzYx?= =?utf-8?q?=3A_Added_more_test_cases_for_testing_unpickling_broken_data=2E?= Message-ID: <20151129111441.22378.65877@psf.io> https://hg.python.org/cpython/rev/c7e7d77ef8bf changeset: 99383:c7e7d77ef8bf branch: 2.7 parent: 99379:7841e9b614eb user: Serhiy Storchaka date: Sun Nov 29 13:12:40 2015 +0200 summary: Issue #25761: Added more test cases for testing unpickling broken data. Output raised exception at verbose level 2 (-vv). files: Lib/test/pickletester.py | 227 +++++++++++++++++--------- Lib/test/test_cpickle.py | 6 + Lib/test/test_pickle.py | 13 + 3 files changed, 170 insertions(+), 76 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -6,7 +6,9 @@ import cStringIO import pickletools import copy_reg +import sys +from test import test_support as support from test.test_support import TestFailed, verbose, have_unicode, TESTFN try: from test.test_support import _2G, _1M, precisionbigmemtest @@ -473,6 +475,17 @@ self.assertEqual(getattr(obj, slot, None), getattr(objcopy, slot, None), msg=msg) + def check_unpickling_error(self, errors, data): + with self.assertRaises(errors): + try: + self.loads(data) + except: + if support.verbose > 1: + exc = sys.exc_info()[1] + print('%-32r - %s: %s' % + (data, exc.__class__.__name__, exc)) + raise + def test_load_from_canned_string(self): expected = self._testdata for canned in DATA0, DATA1, DATA2: @@ -480,7 +493,7 @@ self.assert_is_copy(expected, got) def test_garyp(self): - self.assertRaises(self.error, self.loads, 'garyp') + self.check_unpickling_error(self.error, 'garyp') def test_maxint64(self): maxint64 = (1L << 63) - 1 @@ -490,7 +503,7 @@ # Try too with a bogus literal. data = 'I' + str(maxint64) + 'JUNK\n.' - self.assertRaises(ValueError, self.loads, data) + self.check_unpickling_error(ValueError, data) def test_insecure_strings(self): insecure = ["abc", "2 + 2", # not quoted @@ -511,7 +524,7 @@ ] for s in insecure: buf = "S" + s + "\n." - self.assertRaises(ValueError, self.loads, buf) + self.check_unpickling_error(ValueError, buf) def test_correctly_quoted_string(self): goodpickles = [("S''\n.", ''), @@ -578,11 +591,6 @@ 'q\x00oq\x01}q\x02b.').replace('X', xname) self.assert_is_copy(X(*args), self.loads(pickle2)) - def test_pop_empty_stack(self): - # Test issue7455 - s = '0' - self.assertRaises((cPickle.UnpicklingError, IndexError), self.loads, s) - def test_load_str(self): # From Python 2: pickle.dumps('a\x00\xa0', protocol=0) self.assertEqual(self.loads("S'a\\x00\\xa0'\n."), 'a\x00\xa0') @@ -607,8 +615,8 @@ self.assertIs(self.loads('I00\n.'), False) def test_misc_get(self): - self.assertRaises(self.error, self.loads, 'g0\np0\n') - self.assertRaises(self.error, self.loads, 'h\x00q\x00') + self.check_unpickling_error(self.error, 'g0\np0\n') + self.check_unpickling_error(self.error, 'h\x00q\x00') def test_get(self): pickled = '((lp100000\ng100000\nt.' @@ -636,74 +644,145 @@ def test_bad_stack(self): badpickles = [ - '0.', # POP - '1.', # POP_MARK - '2.', # DUP - # '(2.', # PyUnpickler doesn't raise - 'R.', # REDUCE - ')R.', - 'a.', # APPEND - 'Na.', - 'b.', # BUILD - 'Nb.', - 'd.', # DICT - 'e.', # APPENDS - # '(e.', # PyUnpickler raises AttributeError - 'i__builtin__\nlist\n.', # INST - 'l.', # LIST - 'o.', # OBJ - '(o.', - 'p1\n.', # PUT - 'q\x00.', # BINPUT - 'r\x00\x00\x00\x00.', # LONG_BINPUT - 's.', # SETITEM - 'Ns.', - 'NNs.', - 't.', # TUPLE - 'u.', # SETITEMS - '(u.', - '}(Nu.', - '\x81.', # NEWOBJ - ')\x81.', - '\x85.', # TUPLE1 - '\x86.', # TUPLE2 - 'N\x86.', - '\x87.', # TUPLE3 - 'N\x87.', - 'NN\x87.', + '.', # STOP + '0', # POP + '1', # POP_MARK + '2', # DUP + # '(2', # PyUnpickler doesn't raise + 'R', # REDUCE + ')R', + 'a', # APPEND + 'Na', + 'b', # BUILD + 'Nb', + 'd', # DICT + 'e', # APPENDS + # '(e', # PyUnpickler raises AttributeError + 'i__builtin__\nlist\n', # INST + 'l', # LIST + 'o', # OBJ + '(o', + 'p1\n', # PUT + 'q\x00', # BINPUT + 'r\x00\x00\x00\x00', # LONG_BINPUT + 's', # SETITEM + 'Ns', + 'NNs', + 't', # TUPLE + 'u', # SETITEMS + # '(u', # PyUnpickler doesn't raise + '}(Nu', + '\x81', # NEWOBJ + ')\x81', + '\x85', # TUPLE1 + '\x86', # TUPLE2 + 'N\x86', + '\x87', # TUPLE3 + 'N\x87', + 'NN\x87', ] for p in badpickles: - try: - self.assertRaises(self.bad_stack_errors, self.loads, p) - except: - print '***', repr(p) - raise + self.check_unpickling_error(self.bad_stack_errors, p) def test_bad_mark(self): badpickles = [ - 'c__builtin__\nlist\n)(R.', # REDUCE - 'c__builtin__\nlist\n()R.', - ']N(a.', # APPEND - 'cexceptions\nValueError\n)R}(b.', # BUILD - 'cexceptions\nValueError\n)R(}b.', - '(Nd.', # DICT - '}NN(s.', # SETITEM - '}N(Ns.', - 'c__builtin__\nlist\n)(\x81.', # NEWOBJ - 'c__builtin__\nlist\n()\x81.', - 'N(\x85.', # TUPLE1 - 'NN(\x86.', # TUPLE2 - 'N(N\x86.', - 'NNN(\x87.', # TUPLE3 - 'NN(N\x87.', - 'N(NN\x87.', + # 'N(.', # STOP + 'N(2', # DUP + 'c__builtin__\nlist\n)(R', # REDUCE + 'c__builtin__\nlist\n()R', + ']N(a', # APPEND + # BUILD + 'c__builtin__\nValueError\n)R}(b', + 'c__builtin__\nValueError\n)R(}b', + '(Nd', # DICT + 'N(p1\n', # PUT + 'N(q\x00', # BINPUT + 'N(r\x00\x00\x00\x00', # LONG_BINPUT + '}NN(s', # SETITEM + '}N(Ns', + '}(NNs', + '}((u', # SETITEMS + # NEWOBJ + 'c__builtin__\nlist\n)(\x81', + 'c__builtin__\nlist\n()\x81', + 'N(\x85', # TUPLE1 + 'NN(\x86', # TUPLE2 + 'N(N\x86', + 'NNN(\x87', # TUPLE3 + 'NN(N\x87', + 'N(NN\x87', ] for p in badpickles: - try: - self.loads(p) - except (IndexError, AttributeError, TypeError, - pickle.UnpicklingError): - pass + self.check_unpickling_error(self.bad_mark_errors, p) + + def test_truncated_data(self): + self.check_unpickling_error(EOFError, b'') + self.check_unpickling_error(EOFError, b'N') + badpickles = [ + 'F', # FLOAT + 'F0.0', + 'F0.00', + 'G', # BINFLOAT + 'G\x00\x00\x00\x00\x00\x00\x00', + 'I', # INT + 'I0', + 'J', # BININT + 'J\x00\x00\x00', + 'K', # BININT1 + 'L', # LONG + 'L0', + 'L10', + 'L0L', + 'L10L', + 'M', # BININT2 + 'M\x00', + # 'P', # PERSID + # 'Pabc', + 'S', # STRING + b"S'abc'", + 'T', # BINSTRING + 'T\x03\x00\x00', + 'T\x03\x00\x00\x00', + 'T\x03\x00\x00\x00ab', + 'U', # SHORT_BINSTRING + 'U\x03', + 'U\x03ab', + 'V', # UNICODE + 'Vabc', + 'X', # BINUNICODE + 'X\x03\x00\x00', + 'X\x03\x00\x00\x00', + 'X\x03\x00\x00\x00ab', + '(c', # GLOBAL + '(c__builtin__', + '(c__builtin__\n', + '(c__builtin__\nlist', + 'Ng', # GET + 'Ng0', + '(i', # INST + '(i__builtin__', + '(i__builtin__\n', + '(i__builtin__\nlist', + 'Nh', # BINGET + 'Nj', # LONG_BINGET + 'Nj\x00\x00\x00', + 'Np', # PUT + 'Np0', + 'Nq', # BINPUT + 'Nr', # LONG_BINPUT + 'Nr\x00\x00\x00', + '\x80', # PROTO + '\x82', # EXT1 + '\x83', # EXT2 + '\x84\x01', + '\x84', # EXT4 + '\x84\x01\x00\x00', + '\x8a', # LONG1 + '\x8b', # LONG4 + '\x8b\x00\x00\x00', + ] + for p in badpickles: + self.check_unpickling_error(self.truncated_errors, p) class AbstractPickleTests(unittest.TestCase): @@ -1467,11 +1546,7 @@ # Test issue4298 s = '\x58\0\0\0\x54' self.assertRaises(EOFError, self.module.loads, s) - # Test issue7455 - s = '0' - # XXX Why doesn't pickle raise UnpicklingError? - self.assertRaises((IndexError, cPickle.UnpicklingError), - self.module.loads, s) + class AbstractPersistentPicklerTests(unittest.TestCase): diff --git a/Lib/test/test_cpickle.py b/Lib/test/test_cpickle.py --- a/Lib/test/test_cpickle.py +++ b/Lib/test/test_cpickle.py @@ -52,6 +52,9 @@ error = cPickle.BadPickleGet module = cPickle bad_stack_errors = (cPickle.UnpicklingError,) + bad_mark_errors = (EOFError,) + truncated_errors = (cPickle.UnpicklingError, EOFError, + AttributeError, ValueError) class cPickleUnpicklerTests(AbstractUnpickleTests): @@ -65,6 +68,9 @@ error = cPickle.BadPickleGet bad_stack_errors = (cPickle.UnpicklingError,) + bad_mark_errors = (EOFError,) + truncated_errors = (cPickle.UnpicklingError, EOFError, + AttributeError, ValueError) class cStringIOCUnpicklerTests(cStringIOMixin, cPickleUnpicklerTests): pass diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -1,4 +1,5 @@ import pickle +import struct from cStringIO import StringIO from test import test_support @@ -24,11 +25,23 @@ module = pickle error = KeyError bad_stack_errors = (IndexError,) + bad_mark_errors = (IndexError, pickle.UnpicklingError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError, + TypeError, KeyError) class UnpicklerTests(AbstractUnpickleTests): error = KeyError bad_stack_errors = (IndexError,) + bad_mark_errors = (IndexError, pickle.UnpicklingError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError, + TypeError, KeyError) def loads(self, buf): f = StringIO(buf) -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 06:14:41 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 11:14:41 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NzYx?= =?utf-8?q?=3A_Added_more_test_cases_for_testing_unpickling_broken_data=2E?= Message-ID: <20151129111441.29816.32175@psf.io> https://hg.python.org/cpython/rev/d47e5b162072 changeset: 99382:d47e5b162072 branch: 3.4 parent: 99375:aa304ad32292 user: Serhiy Storchaka date: Sun Nov 29 13:12:10 2015 +0200 summary: Issue #25761: Added more test cases for testing unpickling broken data. Output raised exception at verbose level 2 (-vv). files: Lib/test/pickletester.py | 290 ++++++++++++++++++-------- Lib/test/test_pickle.py | 13 + 2 files changed, 210 insertions(+), 93 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -11,8 +11,9 @@ import weakref from http.cookies import SimpleCookie +from test import support from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, + TestFailed, TESTFN, run_with_locale, no_tracing, _2G, _4G, bigmemtest, ) @@ -679,6 +680,17 @@ self.assertEqual(getattr(obj, slot, None), getattr(objcopy, slot, None), msg=msg) + def check_unpickling_error(self, errors, data): + with self.subTest(data=data), \ + self.assertRaises(errors): + try: + self.loads(data) + except BaseException as exc: + if support.verbose > 1: + print('%-32r - %s: %s' % + (data, exc.__class__.__name__, exc)) + raise + def test_load_from_data0(self): self.assert_is_copy(self._testdata, self.loads(DATA0)) @@ -759,12 +771,7 @@ # Try too with a bogus literal. data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' - self.assertRaises(ValueError, self.loads, data) - - def test_pop_empty_stack(self): - # Test issue7455 - s = b'0' - self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s) + self.check_unpickling_error(ValueError, data) def test_unpickle_from_2x(self): # Unpickle non-trivial data from Python 2.x. @@ -849,22 +856,22 @@ def test_negative_32b_binbytes(self): # On 32-bit builds, a BINBYTES of 2**31 or more is refused dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_negative_32b_binunicode(self): # On 32-bit builds, a BINUNICODE of 2**31 or more is refused dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_short_binunicode(self): dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.' self.assertEqual(self.loads(dumped), '\u20ac\x00') def test_misc_get(self): - self.assertRaises(KeyError, self.loads, b'g0\np0') + self.check_unpickling_error(KeyError, b'g0\np0') self.assert_is_copy([(100,), (100,)], self.loads(b'((Kdtp0\nh\x00l.))')) @@ -879,14 +886,14 @@ @requires_32b def test_large_32b_binbytes8(self): dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_large_32b_binunicode8(self): dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_get(self): pickled = b'((lp100000\ng100000\nt.' @@ -915,16 +922,16 @@ def test_negative_put(self): # Issue #12847 dumped = b'Va\np-1\n.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) @requires_32b def test_negative_32b_binput(self): # Issue #12847 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) def test_badly_escaped_string(self): - self.assertRaises(ValueError, self.loads, b"S'\\'\n.") + self.check_unpickling_error(ValueError, b"S'\\'\n.") def test_badly_quoted_string(self): # Issue #17710 @@ -942,7 +949,7 @@ b'S\n.', b'S.'] for p in badpickles: - self.assertRaises(pickle.UnpicklingError, self.loads, p) + self.check_unpickling_error(pickle.UnpicklingError, p) def test_correctly_quoted_string(self): goodpickles = [(b"S''\n.", ''), @@ -989,86 +996,183 @@ def test_bad_stack(self): badpickles = [ - b'0.', # POP - b'1.', # POP_MARK - b'2.', # DUP - # b'(2.', # PyUnpickler doesn't raise - b'R.', # REDUCE - b')R.', - b'a.', # APPEND - b'Na.', - b'b.', # BUILD - b'Nb.', - b'd.', # DICT - b'e.', # APPENDS - # b'(e.', # PyUnpickler raises AttributeError - b'ibuiltins\nlist\n.', # INST - b'l.', # LIST - b'o.', # OBJ - b'(o.', - b'p1\n.', # PUT - b'q\x00.', # BINPUT - b'r\x00\x00\x00\x00.', # LONG_BINPUT - b's.', # SETITEM - b'Ns.', - b'NNs.', - b't.', # TUPLE - b'u.', # SETITEMS - b'(u.', - b'}(Nu.', - b'\x81.', # NEWOBJ - b')\x81.', - b'\x85.', # TUPLE1 - b'\x86.', # TUPLE2 - b'N\x86.', - b'\x87.', # TUPLE3 - b'N\x87.', - b'NN\x87.', - b'\x90.', # ADDITEMS - # b'(\x90.', # PyUnpickler raises AttributeError - b'\x91.', # FROZENSET - b'\x92.', # NEWOBJ_EX - b')}\x92.', - b'\x93.', # STACK_GLOBAL - b'Vlist\n\x93.', - b'\x94.', # MEMOIZE + b'.', # STOP + b'0', # POP + b'1', # POP_MARK + b'2', # DUP + # b'(2', # PyUnpickler doesn't raise + b'R', # REDUCE + b')R', + b'a', # APPEND + b'Na', + b'b', # BUILD + b'Nb', + b'd', # DICT + b'e', # APPENDS + # b'(e', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n', # INST + b'l', # LIST + b'o', # OBJ + b'(o', + b'p1\n', # PUT + b'q\x00', # BINPUT + b'r\x00\x00\x00\x00', # LONG_BINPUT + b's', # SETITEM + b'Ns', + b'NNs', + b't', # TUPLE + b'u', # SETITEMS + # b'(u', # PyUnpickler doesn't raise + b'}(Nu', + b'\x81', # NEWOBJ + b')\x81', + b'\x85', # TUPLE1 + b'\x86', # TUPLE2 + b'N\x86', + b'\x87', # TUPLE3 + b'N\x87', + b'NN\x87', + b'\x90', # ADDITEMS + # b'(\x90', # PyUnpickler raises AttributeError + b'\x91', # FROZENSET + b'\x92', # NEWOBJ_EX + b')}\x92', + b'\x93', # STACK_GLOBAL + b'Vlist\n\x93', + b'\x94', # MEMOIZE ] for p in badpickles: - with self.subTest(p): - self.assertRaises(self.bad_stack_errors, self.loads, p) + self.check_unpickling_error(self.bad_stack_errors, p) def test_bad_mark(self): badpickles = [ - b'cbuiltins\nlist\n)(R.', # REDUCE - b'cbuiltins\nlist\n()R.', - b']N(a.', # APPEND - b'cbuiltins\nValueError\n)R}(b.', # BUILD - b'cbuiltins\nValueError\n)R(}b.', - b'(Nd.', # DICT - b'}NN(s.', # SETITEM - b'}N(Ns.', - b'cbuiltins\nlist\n)(\x81.', # NEWOBJ - b'cbuiltins\nlist\n()\x81.', - b'N(\x85.', # TUPLE1 - b'NN(\x86.', # TUPLE2 - b'N(N\x86.', - b'NNN(\x87.', # TUPLE3 - b'NN(N\x87.', - b'N(NN\x87.', - b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX - b'cbuiltins\nlist\n)(}\x92.', - b'cbuiltins\nlist\n()}\x92.', - b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL - b'Vbuiltins\nVlist\n(\x93.', + # b'N(.', # STOP + b'N(2', # DUP + b'cbuiltins\nlist\n)(R', # REDUCE + b'cbuiltins\nlist\n()R', + b']N(a', # APPEND + # BUILD + b'cbuiltins\nValueError\n)R}(b', + b'cbuiltins\nValueError\n)R(}b', + b'(Nd', # DICT + b'N(p1\n', # PUT + b'N(q\x00', # BINPUT + b'N(r\x00\x00\x00\x00', # LONG_BINPUT + b'}NN(s', # SETITEM + b'}N(Ns', + b'}(NNs', + b'}((u', # SETITEMS + b'cbuiltins\nlist\n)(\x81', # NEWOBJ + b'cbuiltins\nlist\n()\x81', + b'N(\x85', # TUPLE1 + b'NN(\x86', # TUPLE2 + b'N(N\x86', + b'NNN(\x87', # TUPLE3 + b'NN(N\x87', + b'N(NN\x87', + b']((\x90', # ADDITEMS + # NEWOBJ_EX + b'cbuiltins\nlist\n)}(\x92', + b'cbuiltins\nlist\n)(}\x92', + b'cbuiltins\nlist\n()}\x92', + # STACK_GLOBAL + b'Vbuiltins\n(Vlist\n\x93', + b'Vbuiltins\nVlist\n(\x93', + b'N(\x94', # MEMOIZE ] for p in badpickles: - # PyUnpickler prints reduce errors to stdout - with self.subTest(p), captured_stdout(): - try: - self.loads(p) - except (IndexError, AttributeError, TypeError, - pickle.UnpicklingError): - pass + self.check_unpickling_error(self.bad_mark_errors, p) + + def test_truncated_data(self): + self.check_unpickling_error(EOFError, b'') + self.check_unpickling_error(EOFError, b'N') + badpickles = [ + b'B', # BINBYTES + b'B\x03\x00\x00', + b'B\x03\x00\x00\x00', + b'B\x03\x00\x00\x00ab', + b'C', # SHORT_BINBYTES + b'C\x03', + b'C\x03ab', + b'F', # FLOAT + b'F0.0', + b'F0.00', + b'G', # BINFLOAT + b'G\x00\x00\x00\x00\x00\x00\x00', + b'I', # INT + b'I0', + b'J', # BININT + b'J\x00\x00\x00', + b'K', # BININT1 + b'L', # LONG + b'L0', + b'L10', + b'L0L', + b'L10L', + b'M', # BININT2 + b'M\x00', + # b'P', # PERSID + # b'Pabc', + b'S', # STRING + b"S'abc'", + b'T', # BINSTRING + b'T\x03\x00\x00', + b'T\x03\x00\x00\x00', + b'T\x03\x00\x00\x00ab', + b'U', # SHORT_BINSTRING + b'U\x03', + b'U\x03ab', + b'V', # UNICODE + b'Vabc', + b'X', # BINUNICODE + b'X\x03\x00\x00', + b'X\x03\x00\x00\x00', + b'X\x03\x00\x00\x00ab', + b'(c', # GLOBAL + b'(cbuiltins', + b'(cbuiltins\n', + b'(cbuiltins\nlist', + b'Ng', # GET + b'Ng0', + b'(i', # INST + b'(ibuiltins', + b'(ibuiltins\n', + b'(ibuiltins\nlist', + b'Nh', # BINGET + b'Nj', # LONG_BINGET + b'Nj\x00\x00\x00', + b'Np', # PUT + b'Np0', + b'Nq', # BINPUT + b'Nr', # LONG_BINPUT + b'Nr\x00\x00\x00', + b'\x80', # PROTO + b'\x82', # EXT1 + b'\x83', # EXT2 + b'\x84\x01', + b'\x84', # EXT4 + b'\x84\x01\x00\x00', + b'\x8a', # LONG1 + b'\x8b', # LONG4 + b'\x8b\x00\x00\x00', + b'\x8c', # SHORT_BINUNICODE + b'\x8c\x03', + b'\x8c\x03ab', + b'\x8d', # BINUNICODE8 + b'\x8d\x03\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x8e', # BINBYTES8 + b'\x8e\x03\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x95', # FRAME + b'\x95\x02\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N', + ] + for p in badpickles: + self.check_unpickling_error(self.truncated_errors, p) class AbstractPickleTests(unittest.TestCase): diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -33,6 +33,11 @@ unpickler = pickle._Unpickler bad_stack_errors = (IndexError,) + bad_mark_errors = (IndexError, pickle.UnpicklingError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -64,6 +69,11 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler bad_stack_errors = (pickle.UnpicklingError, IndexError) + bad_mark_errors = (pickle.UnpicklingError, IndexError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -122,6 +132,9 @@ class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler bad_stack_errors = (pickle.UnpicklingError,) + bad_mark_errors = (EOFError,) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 06:14:42 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 11:14:42 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325761=3A_Added_more_test_cases_for_testing_unpickling?= =?utf-8?q?_broken_data=2E?= Message-ID: <20151129111442.87865.29674@psf.io> https://hg.python.org/cpython/rev/4897438543da changeset: 99384:4897438543da branch: 3.5 parent: 99376:5d6b2dc7e3d0 parent: 99382:d47e5b162072 user: Serhiy Storchaka date: Sun Nov 29 13:13:24 2015 +0200 summary: Issue #25761: Added more test cases for testing unpickling broken data. Output raised exception at verbose level 2 (-vv). files: Lib/test/pickletester.py | 290 ++++++++++++++++++-------- Lib/test/test_pickle.py | 13 + 2 files changed, 210 insertions(+), 93 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -11,8 +11,9 @@ import weakref from http.cookies import SimpleCookie +from test import support from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, + TestFailed, TESTFN, run_with_locale, no_tracing, _2G, _4G, bigmemtest, ) @@ -679,6 +680,17 @@ self.assertEqual(getattr(obj, slot, None), getattr(objcopy, slot, None), msg=msg) + def check_unpickling_error(self, errors, data): + with self.subTest(data=data), \ + self.assertRaises(errors): + try: + self.loads(data) + except BaseException as exc: + if support.verbose > 1: + print('%-32r - %s: %s' % + (data, exc.__class__.__name__, exc)) + raise + def test_load_from_data0(self): self.assert_is_copy(self._testdata, self.loads(DATA0)) @@ -759,12 +771,7 @@ # Try too with a bogus literal. data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' - self.assertRaises(ValueError, self.loads, data) - - def test_pop_empty_stack(self): - # Test issue7455 - s = b'0' - self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s) + self.check_unpickling_error(ValueError, data) def test_unpickle_from_2x(self): # Unpickle non-trivial data from Python 2.x. @@ -849,22 +856,22 @@ def test_negative_32b_binbytes(self): # On 32-bit builds, a BINBYTES of 2**31 or more is refused dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_negative_32b_binunicode(self): # On 32-bit builds, a BINUNICODE of 2**31 or more is refused dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_short_binunicode(self): dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.' self.assertEqual(self.loads(dumped), '\u20ac\x00') def test_misc_get(self): - self.assertRaises(KeyError, self.loads, b'g0\np0') + self.check_unpickling_error(KeyError, b'g0\np0') self.assert_is_copy([(100,), (100,)], self.loads(b'((Kdtp0\nh\x00l.))')) @@ -879,14 +886,14 @@ @requires_32b def test_large_32b_binbytes8(self): dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_large_32b_binunicode8(self): dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_get(self): pickled = b'((lp100000\ng100000\nt.' @@ -915,16 +922,16 @@ def test_negative_put(self): # Issue #12847 dumped = b'Va\np-1\n.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) @requires_32b def test_negative_32b_binput(self): # Issue #12847 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) def test_badly_escaped_string(self): - self.assertRaises(ValueError, self.loads, b"S'\\'\n.") + self.check_unpickling_error(ValueError, b"S'\\'\n.") def test_badly_quoted_string(self): # Issue #17710 @@ -942,7 +949,7 @@ b'S\n.', b'S.'] for p in badpickles: - self.assertRaises(pickle.UnpicklingError, self.loads, p) + self.check_unpickling_error(pickle.UnpicklingError, p) def test_correctly_quoted_string(self): goodpickles = [(b"S''\n.", ''), @@ -989,86 +996,183 @@ def test_bad_stack(self): badpickles = [ - b'0.', # POP - b'1.', # POP_MARK - b'2.', # DUP - # b'(2.', # PyUnpickler doesn't raise - b'R.', # REDUCE - b')R.', - b'a.', # APPEND - b'Na.', - b'b.', # BUILD - b'Nb.', - b'd.', # DICT - b'e.', # APPENDS - # b'(e.', # PyUnpickler raises AttributeError - b'ibuiltins\nlist\n.', # INST - b'l.', # LIST - b'o.', # OBJ - b'(o.', - b'p1\n.', # PUT - b'q\x00.', # BINPUT - b'r\x00\x00\x00\x00.', # LONG_BINPUT - b's.', # SETITEM - b'Ns.', - b'NNs.', - b't.', # TUPLE - b'u.', # SETITEMS - b'(u.', - b'}(Nu.', - b'\x81.', # NEWOBJ - b')\x81.', - b'\x85.', # TUPLE1 - b'\x86.', # TUPLE2 - b'N\x86.', - b'\x87.', # TUPLE3 - b'N\x87.', - b'NN\x87.', - b'\x90.', # ADDITEMS - # b'(\x90.', # PyUnpickler raises AttributeError - b'\x91.', # FROZENSET - b'\x92.', # NEWOBJ_EX - b')}\x92.', - b'\x93.', # STACK_GLOBAL - b'Vlist\n\x93.', - b'\x94.', # MEMOIZE + b'.', # STOP + b'0', # POP + b'1', # POP_MARK + b'2', # DUP + # b'(2', # PyUnpickler doesn't raise + b'R', # REDUCE + b')R', + b'a', # APPEND + b'Na', + b'b', # BUILD + b'Nb', + b'd', # DICT + b'e', # APPENDS + # b'(e', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n', # INST + b'l', # LIST + b'o', # OBJ + b'(o', + b'p1\n', # PUT + b'q\x00', # BINPUT + b'r\x00\x00\x00\x00', # LONG_BINPUT + b's', # SETITEM + b'Ns', + b'NNs', + b't', # TUPLE + b'u', # SETITEMS + # b'(u', # PyUnpickler doesn't raise + b'}(Nu', + b'\x81', # NEWOBJ + b')\x81', + b'\x85', # TUPLE1 + b'\x86', # TUPLE2 + b'N\x86', + b'\x87', # TUPLE3 + b'N\x87', + b'NN\x87', + b'\x90', # ADDITEMS + # b'(\x90', # PyUnpickler raises AttributeError + b'\x91', # FROZENSET + b'\x92', # NEWOBJ_EX + b')}\x92', + b'\x93', # STACK_GLOBAL + b'Vlist\n\x93', + b'\x94', # MEMOIZE ] for p in badpickles: - with self.subTest(p): - self.assertRaises(self.bad_stack_errors, self.loads, p) + self.check_unpickling_error(self.bad_stack_errors, p) def test_bad_mark(self): badpickles = [ - b'cbuiltins\nlist\n)(R.', # REDUCE - b'cbuiltins\nlist\n()R.', - b']N(a.', # APPEND - b'cbuiltins\nValueError\n)R}(b.', # BUILD - b'cbuiltins\nValueError\n)R(}b.', - b'(Nd.', # DICT - b'}NN(s.', # SETITEM - b'}N(Ns.', - b'cbuiltins\nlist\n)(\x81.', # NEWOBJ - b'cbuiltins\nlist\n()\x81.', - b'N(\x85.', # TUPLE1 - b'NN(\x86.', # TUPLE2 - b'N(N\x86.', - b'NNN(\x87.', # TUPLE3 - b'NN(N\x87.', - b'N(NN\x87.', - b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX - b'cbuiltins\nlist\n)(}\x92.', - b'cbuiltins\nlist\n()}\x92.', - b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL - b'Vbuiltins\nVlist\n(\x93.', + # b'N(.', # STOP + b'N(2', # DUP + b'cbuiltins\nlist\n)(R', # REDUCE + b'cbuiltins\nlist\n()R', + b']N(a', # APPEND + # BUILD + b'cbuiltins\nValueError\n)R}(b', + b'cbuiltins\nValueError\n)R(}b', + b'(Nd', # DICT + b'N(p1\n', # PUT + b'N(q\x00', # BINPUT + b'N(r\x00\x00\x00\x00', # LONG_BINPUT + b'}NN(s', # SETITEM + b'}N(Ns', + b'}(NNs', + b'}((u', # SETITEMS + b'cbuiltins\nlist\n)(\x81', # NEWOBJ + b'cbuiltins\nlist\n()\x81', + b'N(\x85', # TUPLE1 + b'NN(\x86', # TUPLE2 + b'N(N\x86', + b'NNN(\x87', # TUPLE3 + b'NN(N\x87', + b'N(NN\x87', + b']((\x90', # ADDITEMS + # NEWOBJ_EX + b'cbuiltins\nlist\n)}(\x92', + b'cbuiltins\nlist\n)(}\x92', + b'cbuiltins\nlist\n()}\x92', + # STACK_GLOBAL + b'Vbuiltins\n(Vlist\n\x93', + b'Vbuiltins\nVlist\n(\x93', + b'N(\x94', # MEMOIZE ] for p in badpickles: - # PyUnpickler prints reduce errors to stdout - with self.subTest(p), captured_stdout(): - try: - self.loads(p) - except (IndexError, AttributeError, TypeError, - pickle.UnpicklingError): - pass + self.check_unpickling_error(self.bad_mark_errors, p) + + def test_truncated_data(self): + self.check_unpickling_error(EOFError, b'') + self.check_unpickling_error(EOFError, b'N') + badpickles = [ + b'B', # BINBYTES + b'B\x03\x00\x00', + b'B\x03\x00\x00\x00', + b'B\x03\x00\x00\x00ab', + b'C', # SHORT_BINBYTES + b'C\x03', + b'C\x03ab', + b'F', # FLOAT + b'F0.0', + b'F0.00', + b'G', # BINFLOAT + b'G\x00\x00\x00\x00\x00\x00\x00', + b'I', # INT + b'I0', + b'J', # BININT + b'J\x00\x00\x00', + b'K', # BININT1 + b'L', # LONG + b'L0', + b'L10', + b'L0L', + b'L10L', + b'M', # BININT2 + b'M\x00', + # b'P', # PERSID + # b'Pabc', + b'S', # STRING + b"S'abc'", + b'T', # BINSTRING + b'T\x03\x00\x00', + b'T\x03\x00\x00\x00', + b'T\x03\x00\x00\x00ab', + b'U', # SHORT_BINSTRING + b'U\x03', + b'U\x03ab', + b'V', # UNICODE + b'Vabc', + b'X', # BINUNICODE + b'X\x03\x00\x00', + b'X\x03\x00\x00\x00', + b'X\x03\x00\x00\x00ab', + b'(c', # GLOBAL + b'(cbuiltins', + b'(cbuiltins\n', + b'(cbuiltins\nlist', + b'Ng', # GET + b'Ng0', + b'(i', # INST + b'(ibuiltins', + b'(ibuiltins\n', + b'(ibuiltins\nlist', + b'Nh', # BINGET + b'Nj', # LONG_BINGET + b'Nj\x00\x00\x00', + b'Np', # PUT + b'Np0', + b'Nq', # BINPUT + b'Nr', # LONG_BINPUT + b'Nr\x00\x00\x00', + b'\x80', # PROTO + b'\x82', # EXT1 + b'\x83', # EXT2 + b'\x84\x01', + b'\x84', # EXT4 + b'\x84\x01\x00\x00', + b'\x8a', # LONG1 + b'\x8b', # LONG4 + b'\x8b\x00\x00\x00', + b'\x8c', # SHORT_BINUNICODE + b'\x8c\x03', + b'\x8c\x03ab', + b'\x8d', # BINUNICODE8 + b'\x8d\x03\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x8e', # BINBYTES8 + b'\x8e\x03\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x95', # FRAME + b'\x95\x02\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N', + ] + for p in badpickles: + self.check_unpickling_error(self.truncated_errors, p) class AbstractPickleTests(unittest.TestCase): diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -33,6 +33,11 @@ unpickler = pickle._Unpickler bad_stack_errors = (IndexError,) + bad_mark_errors = (IndexError, pickle.UnpicklingError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -64,6 +69,11 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler bad_stack_errors = (pickle.UnpicklingError, IndexError) + bad_mark_errors = (pickle.UnpicklingError, IndexError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -122,6 +132,9 @@ class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler bad_stack_errors = (pickle.UnpicklingError,) + bad_mark_errors = (EOFError,) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 06:14:42 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 11:14:42 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325761=3A_Added_more_test_cases_for_testing_unpi?= =?utf-8?q?ckling_broken_data=2E?= Message-ID: <20151129111442.13439.89766@psf.io> https://hg.python.org/cpython/rev/c852c7d8d681 changeset: 99385:c852c7d8d681 parent: 99381:2e889344436e parent: 99384:4897438543da user: Serhiy Storchaka date: Sun Nov 29 13:14:00 2015 +0200 summary: Issue #25761: Added more test cases for testing unpickling broken data. Output raised exception at verbose level 2 (-vv). files: Lib/test/pickletester.py | 290 ++++++++++++++++++-------- Lib/test/test_pickle.py | 13 + 2 files changed, 210 insertions(+), 93 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -11,8 +11,9 @@ import weakref from http.cookies import SimpleCookie +from test import support from test.support import ( - TestFailed, TESTFN, run_with_locale, no_tracing, captured_stdout, + TestFailed, TESTFN, run_with_locale, no_tracing, _2G, _4G, bigmemtest, ) @@ -679,6 +680,17 @@ self.assertEqual(getattr(obj, slot, None), getattr(objcopy, slot, None), msg=msg) + def check_unpickling_error(self, errors, data): + with self.subTest(data=data), \ + self.assertRaises(errors): + try: + self.loads(data) + except BaseException as exc: + if support.verbose > 1: + print('%-32r - %s: %s' % + (data, exc.__class__.__name__, exc)) + raise + def test_load_from_data0(self): self.assert_is_copy(self._testdata, self.loads(DATA0)) @@ -759,12 +771,7 @@ # Try too with a bogus literal. data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' - self.assertRaises(ValueError, self.loads, data) - - def test_pop_empty_stack(self): - # Test issue7455 - s = b'0' - self.assertRaises((pickle.UnpicklingError, IndexError), self.loads, s) + self.check_unpickling_error(ValueError, data) def test_unpickle_from_2x(self): # Unpickle non-trivial data from Python 2.x. @@ -849,22 +856,22 @@ def test_negative_32b_binbytes(self): # On 32-bit builds, a BINBYTES of 2**31 or more is refused dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_negative_32b_binunicode(self): # On 32-bit builds, a BINUNICODE of 2**31 or more is refused dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_short_binunicode(self): dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.' self.assertEqual(self.loads(dumped), '\u20ac\x00') def test_misc_get(self): - self.assertRaises(KeyError, self.loads, b'g0\np0') + self.check_unpickling_error(KeyError, b'g0\np0') self.assert_is_copy([(100,), (100,)], self.loads(b'((Kdtp0\nh\x00l.))')) @@ -879,14 +886,14 @@ @requires_32b def test_large_32b_binbytes8(self): dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) @requires_32b def test_large_32b_binunicode8(self): dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' - with self.assertRaises((pickle.UnpicklingError, OverflowError)): - self.loads(dumped) + self.check_unpickling_error((pickle.UnpicklingError, OverflowError), + dumped) def test_get(self): pickled = b'((lp100000\ng100000\nt.' @@ -915,16 +922,16 @@ def test_negative_put(self): # Issue #12847 dumped = b'Va\np-1\n.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) @requires_32b def test_negative_32b_binput(self): # Issue #12847 dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.' - self.assertRaises(ValueError, self.loads, dumped) + self.check_unpickling_error(ValueError, dumped) def test_badly_escaped_string(self): - self.assertRaises(ValueError, self.loads, b"S'\\'\n.") + self.check_unpickling_error(ValueError, b"S'\\'\n.") def test_badly_quoted_string(self): # Issue #17710 @@ -942,7 +949,7 @@ b'S\n.', b'S.'] for p in badpickles: - self.assertRaises(pickle.UnpicklingError, self.loads, p) + self.check_unpickling_error(pickle.UnpicklingError, p) def test_correctly_quoted_string(self): goodpickles = [(b"S''\n.", ''), @@ -989,86 +996,183 @@ def test_bad_stack(self): badpickles = [ - b'0.', # POP - b'1.', # POP_MARK - b'2.', # DUP - # b'(2.', # PyUnpickler doesn't raise - b'R.', # REDUCE - b')R.', - b'a.', # APPEND - b'Na.', - b'b.', # BUILD - b'Nb.', - b'd.', # DICT - b'e.', # APPENDS - # b'(e.', # PyUnpickler raises AttributeError - b'ibuiltins\nlist\n.', # INST - b'l.', # LIST - b'o.', # OBJ - b'(o.', - b'p1\n.', # PUT - b'q\x00.', # BINPUT - b'r\x00\x00\x00\x00.', # LONG_BINPUT - b's.', # SETITEM - b'Ns.', - b'NNs.', - b't.', # TUPLE - b'u.', # SETITEMS - b'(u.', - b'}(Nu.', - b'\x81.', # NEWOBJ - b')\x81.', - b'\x85.', # TUPLE1 - b'\x86.', # TUPLE2 - b'N\x86.', - b'\x87.', # TUPLE3 - b'N\x87.', - b'NN\x87.', - b'\x90.', # ADDITEMS - # b'(\x90.', # PyUnpickler raises AttributeError - b'\x91.', # FROZENSET - b'\x92.', # NEWOBJ_EX - b')}\x92.', - b'\x93.', # STACK_GLOBAL - b'Vlist\n\x93.', - b'\x94.', # MEMOIZE + b'.', # STOP + b'0', # POP + b'1', # POP_MARK + b'2', # DUP + # b'(2', # PyUnpickler doesn't raise + b'R', # REDUCE + b')R', + b'a', # APPEND + b'Na', + b'b', # BUILD + b'Nb', + b'd', # DICT + b'e', # APPENDS + # b'(e', # PyUnpickler raises AttributeError + b'ibuiltins\nlist\n', # INST + b'l', # LIST + b'o', # OBJ + b'(o', + b'p1\n', # PUT + b'q\x00', # BINPUT + b'r\x00\x00\x00\x00', # LONG_BINPUT + b's', # SETITEM + b'Ns', + b'NNs', + b't', # TUPLE + b'u', # SETITEMS + # b'(u', # PyUnpickler doesn't raise + b'}(Nu', + b'\x81', # NEWOBJ + b')\x81', + b'\x85', # TUPLE1 + b'\x86', # TUPLE2 + b'N\x86', + b'\x87', # TUPLE3 + b'N\x87', + b'NN\x87', + b'\x90', # ADDITEMS + # b'(\x90', # PyUnpickler raises AttributeError + b'\x91', # FROZENSET + b'\x92', # NEWOBJ_EX + b')}\x92', + b'\x93', # STACK_GLOBAL + b'Vlist\n\x93', + b'\x94', # MEMOIZE ] for p in badpickles: - with self.subTest(p): - self.assertRaises(self.bad_stack_errors, self.loads, p) + self.check_unpickling_error(self.bad_stack_errors, p) def test_bad_mark(self): badpickles = [ - b'cbuiltins\nlist\n)(R.', # REDUCE - b'cbuiltins\nlist\n()R.', - b']N(a.', # APPEND - b'cbuiltins\nValueError\n)R}(b.', # BUILD - b'cbuiltins\nValueError\n)R(}b.', - b'(Nd.', # DICT - b'}NN(s.', # SETITEM - b'}N(Ns.', - b'cbuiltins\nlist\n)(\x81.', # NEWOBJ - b'cbuiltins\nlist\n()\x81.', - b'N(\x85.', # TUPLE1 - b'NN(\x86.', # TUPLE2 - b'N(N\x86.', - b'NNN(\x87.', # TUPLE3 - b'NN(N\x87.', - b'N(NN\x87.', - b'cbuiltins\nlist\n)}(\x92.', # NEWOBJ_EX - b'cbuiltins\nlist\n)(}\x92.', - b'cbuiltins\nlist\n()}\x92.', - b'Vbuiltins\n(Vlist\n\x93.', # STACK_GLOBAL - b'Vbuiltins\nVlist\n(\x93.', + # b'N(.', # STOP + b'N(2', # DUP + b'cbuiltins\nlist\n)(R', # REDUCE + b'cbuiltins\nlist\n()R', + b']N(a', # APPEND + # BUILD + b'cbuiltins\nValueError\n)R}(b', + b'cbuiltins\nValueError\n)R(}b', + b'(Nd', # DICT + b'N(p1\n', # PUT + b'N(q\x00', # BINPUT + b'N(r\x00\x00\x00\x00', # LONG_BINPUT + b'}NN(s', # SETITEM + b'}N(Ns', + b'}(NNs', + b'}((u', # SETITEMS + b'cbuiltins\nlist\n)(\x81', # NEWOBJ + b'cbuiltins\nlist\n()\x81', + b'N(\x85', # TUPLE1 + b'NN(\x86', # TUPLE2 + b'N(N\x86', + b'NNN(\x87', # TUPLE3 + b'NN(N\x87', + b'N(NN\x87', + b']((\x90', # ADDITEMS + # NEWOBJ_EX + b'cbuiltins\nlist\n)}(\x92', + b'cbuiltins\nlist\n)(}\x92', + b'cbuiltins\nlist\n()}\x92', + # STACK_GLOBAL + b'Vbuiltins\n(Vlist\n\x93', + b'Vbuiltins\nVlist\n(\x93', + b'N(\x94', # MEMOIZE ] for p in badpickles: - # PyUnpickler prints reduce errors to stdout - with self.subTest(p), captured_stdout(): - try: - self.loads(p) - except (IndexError, AttributeError, TypeError, - pickle.UnpicklingError): - pass + self.check_unpickling_error(self.bad_mark_errors, p) + + def test_truncated_data(self): + self.check_unpickling_error(EOFError, b'') + self.check_unpickling_error(EOFError, b'N') + badpickles = [ + b'B', # BINBYTES + b'B\x03\x00\x00', + b'B\x03\x00\x00\x00', + b'B\x03\x00\x00\x00ab', + b'C', # SHORT_BINBYTES + b'C\x03', + b'C\x03ab', + b'F', # FLOAT + b'F0.0', + b'F0.00', + b'G', # BINFLOAT + b'G\x00\x00\x00\x00\x00\x00\x00', + b'I', # INT + b'I0', + b'J', # BININT + b'J\x00\x00\x00', + b'K', # BININT1 + b'L', # LONG + b'L0', + b'L10', + b'L0L', + b'L10L', + b'M', # BININT2 + b'M\x00', + # b'P', # PERSID + # b'Pabc', + b'S', # STRING + b"S'abc'", + b'T', # BINSTRING + b'T\x03\x00\x00', + b'T\x03\x00\x00\x00', + b'T\x03\x00\x00\x00ab', + b'U', # SHORT_BINSTRING + b'U\x03', + b'U\x03ab', + b'V', # UNICODE + b'Vabc', + b'X', # BINUNICODE + b'X\x03\x00\x00', + b'X\x03\x00\x00\x00', + b'X\x03\x00\x00\x00ab', + b'(c', # GLOBAL + b'(cbuiltins', + b'(cbuiltins\n', + b'(cbuiltins\nlist', + b'Ng', # GET + b'Ng0', + b'(i', # INST + b'(ibuiltins', + b'(ibuiltins\n', + b'(ibuiltins\nlist', + b'Nh', # BINGET + b'Nj', # LONG_BINGET + b'Nj\x00\x00\x00', + b'Np', # PUT + b'Np0', + b'Nq', # BINPUT + b'Nr', # LONG_BINPUT + b'Nr\x00\x00\x00', + b'\x80', # PROTO + b'\x82', # EXT1 + b'\x83', # EXT2 + b'\x84\x01', + b'\x84', # EXT4 + b'\x84\x01\x00\x00', + b'\x8a', # LONG1 + b'\x8b', # LONG4 + b'\x8b\x00\x00\x00', + b'\x8c', # SHORT_BINUNICODE + b'\x8c\x03', + b'\x8c\x03ab', + b'\x8d', # BINUNICODE8 + b'\x8d\x03\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x8e', # BINBYTES8 + b'\x8e\x03\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00', + b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab', + b'\x95', # FRAME + b'\x95\x02\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00', + b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N', + ] + for p in badpickles: + self.check_unpickling_error(self.truncated_errors, p) class AbstractPickleTests(unittest.TestCase): diff --git a/Lib/test/test_pickle.py b/Lib/test/test_pickle.py --- a/Lib/test/test_pickle.py +++ b/Lib/test/test_pickle.py @@ -33,6 +33,11 @@ unpickler = pickle._Unpickler bad_stack_errors = (IndexError,) + bad_mark_errors = (IndexError, pickle.UnpicklingError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def loads(self, buf, **kwds): f = io.BytesIO(buf) @@ -64,6 +69,11 @@ pickler = pickle._Pickler unpickler = pickle._Unpickler bad_stack_errors = (pickle.UnpicklingError, IndexError) + bad_mark_errors = (pickle.UnpicklingError, IndexError, + TypeError, AttributeError, EOFError) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError, + struct.error, IndexError, ImportError) def dumps(self, arg, protocol=None): return pickle.dumps(arg, protocol) @@ -122,6 +132,9 @@ class CUnpicklerTests(PyUnpicklerTests): unpickler = _pickle.Unpickler bad_stack_errors = (pickle.UnpicklingError,) + bad_mark_errors = (EOFError,) + truncated_errors = (pickle.UnpicklingError, EOFError, + AttributeError, ValueError) class CPicklerTests(PyPicklerTests): pickler = _pickle.Pickler -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 09:14:12 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 14:14:12 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogR290IHJpZCBvZiAi?= =?utf-8?q?with=22_for_compatibility_test=5Fxpickle_with_Python_2=2E5=2E?= Message-ID: <20151129141412.22396.27006@psf.io> https://hg.python.org/cpython/rev/2e864db39267 changeset: 99386:2e864db39267 branch: 2.7 parent: 99383:c7e7d77ef8bf user: Serhiy Storchaka date: Sun Nov 29 16:13:51 2015 +0200 summary: Got rid of "with" for compatibility test_xpickle with Python 2.5. files: Lib/test/pickletester.py | 15 +++++++++++---- 1 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -476,15 +476,22 @@ getattr(objcopy, slot, None), msg=msg) def check_unpickling_error(self, errors, data): - with self.assertRaises(errors): + try: try: self.loads(data) except: if support.verbose > 1: - exc = sys.exc_info()[1] - print('%-32r - %s: %s' % - (data, exc.__class__.__name__, exc)) + exc_type, exc, tb = sys.exc_info() + print '%-32r - %s: %s' % (data, exc_type.__name__, exc) raise + except errors: + pass + else: + try: + exc_name = errors.__name__ + except AttributeError: + exc_name = str(errors) + raise self.failureException('%s not raised' % exc_name) def test_load_from_canned_string(self): expected = self._testdata -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 10:33:24 2015 From: python-checkins at python.org (victor.stinner) Date: Sun, 29 Nov 2015 15:33:24 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NzQy?= =?utf-8?q?=3A_Try_to_fix_test=5Flocale_on_Windows?= Message-ID: <20151129153324.31385.93999@psf.io> https://hg.python.org/cpython/rev/d7481ebeaa4f changeset: 99387:d7481ebeaa4f branch: 2.7 user: Victor Stinner date: Sun Nov 29 16:33:18 2015 +0100 summary: Issue #25742: Try to fix test_locale on Windows files: Lib/test/test_locale.py | 16 ++++++++-------- 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Lib/test/test_locale.py b/Lib/test/test_locale.py --- a/Lib/test/test_locale.py +++ b/Lib/test/test_locale.py @@ -494,14 +494,14 @@ self.assertEqual(locale.normalize(u'en_US'), 'en_US.ISO8859-1') def test_setlocale_unicode(self): - old_loc = locale.getlocale(locale.LC_ALL) - try: - user_locale = locale.setlocale(locale.LC_ALL, '') - unicode_locale = user_locale.decode('utf-8') - user_locale2 = locale.setlocale(locale.LC_ALL, unicode_locale) - self.assertEqual(user_locale, user_locale2) - finally: - locale.setlocale(locale.LC_ALL, old_loc) + oldlocale = locale.getlocale() + self.addCleanup(locale.setlocale, locale.LC_CTYPE, oldlocale) + + user_locale = locale.setlocale(locale.LC_CTYPE, '') + unicode_locale = user_locale.decode('utf-8') + + user_locale2 = locale.setlocale(locale.LC_CTYPE, unicode_locale) + self.assertEqual(user_locale, user_locale2) def test_main(): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 12:20:29 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 17:20:29 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Trying_to_fix_?= =?utf-8?q?test=5Fxpickle_with_python_2=2E4_and_2=2E5=2E?= Message-ID: <20151129172029.31417.88462@psf.io> https://hg.python.org/cpython/rev/ee29e93ab3fb changeset: 99388:ee29e93ab3fb branch: 2.7 user: Serhiy Storchaka date: Sun Nov 29 19:20:11 2015 +0200 summary: Trying to fix test_xpickle with python 2.4 and 2.5. files: Lib/test/pickletester.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -723,8 +723,8 @@ self.check_unpickling_error(self.bad_mark_errors, p) def test_truncated_data(self): - self.check_unpickling_error(EOFError, b'') - self.check_unpickling_error(EOFError, b'N') + self.check_unpickling_error(EOFError, '') + self.check_unpickling_error(EOFError, 'N') badpickles = [ 'F', # FLOAT 'F0.0', -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 13:14:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 18:14:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fixed_Py3k_war?= =?utf-8?q?nings_in_tests_for_issue_=2324731=2E?= Message-ID: <20151129181414.22404.71608@psf.io> https://hg.python.org/cpython/rev/2ea1a3bf448f changeset: 99389:2ea1a3bf448f branch: 2.7 user: Serhiy Storchaka date: Sun Nov 29 20:13:56 2015 +0200 summary: Fixed Py3k warnings in tests for issue #24731. files: Lib/test/test_compile.py | 17 +++++++++-------- Lib/test/test_float.py | 17 ++++++++++------- Lib/test/test_int.py | 17 ++++++++++------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -576,14 +576,15 @@ # objects are accepted, which could be not terminated. with self.assertRaisesRegexp(TypeError, "without null bytes"): compile(u"123\x00", "", "eval") - with self.assertRaisesRegexp(TypeError, "without null bytes"): - compile(buffer("123\x00"), "", "eval") - code = compile(buffer("123\x00", 1, 2), "", "eval") - self.assertEqual(eval(code), 23) - code = compile(buffer("1234", 1, 2), "", "eval") - self.assertEqual(eval(code), 23) - code = compile(buffer("$23$", 1, 2), "", "eval") - self.assertEqual(eval(code), 23) + with test_support.check_py3k_warnings(): + with self.assertRaisesRegexp(TypeError, "without null bytes"): + compile(buffer("123\x00"), "", "eval") + code = compile(buffer("123\x00", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) + code = compile(buffer("1234", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) + code = compile(buffer("$23$", 1, 2), "", "eval") + self.assertEqual(eval(code), 23) class TestStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py --- a/Lib/test/test_float.py +++ b/Lib/test/test_float.py @@ -71,7 +71,8 @@ factories += [unicode, CustomUnicode] for f in factories: - x = f(" 3.14 ") + with test_support.check_py3k_warnings(quiet=True): + x = f(" 3.14 ") msg = 'x has value %s and type %s' % (x, type(x).__name__) try: self.assertEqual(float(x), 3.14, msg=msg) @@ -79,15 +80,17 @@ raise AssertionError('For %s got TypeError: %s' % (type(x).__name__, err)) errmsg = "could not convert" - with self.assertRaisesRegexp(ValueError, errmsg, msg=msg): + with self.assertRaisesRegexp(ValueError, errmsg, msg=msg), \ + test_support.check_py3k_warnings(quiet=True): float(f('A' * 0x10)) def test_float_buffer(self): - self.assertEqual(float(buffer('12.3', 1, 3)), 2.3) - self.assertEqual(float(buffer('12.3\x00', 1, 3)), 2.3) - self.assertEqual(float(buffer('12.3 ', 1, 3)), 2.3) - self.assertEqual(float(buffer('12.3A', 1, 3)), 2.3) - self.assertEqual(float(buffer('12.34', 1, 3)), 2.3) + with test_support.check_py3k_warnings(): + self.assertEqual(float(buffer('12.3', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3\x00', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3 ', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.3A', 1, 3)), 2.3) + self.assertEqual(float(buffer('12.34', 1, 3)), 2.3) def check_conversion_to_int(self, x): """Check that int(x) has the correct value and type, for a float x.""" diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py --- a/Lib/test/test_int.py +++ b/Lib/test/test_int.py @@ -351,7 +351,8 @@ factories += [unicode, CustomUnicode] for f in factories: - x = f('100') + with test_support.check_py3k_warnings(quiet=True): + x = f('100') msg = 'x has value %s and type %s' % (x, type(x).__name__) try: self.assertEqual(int(x), 100, msg=msg) @@ -365,15 +366,17 @@ with self.assertRaisesRegexp(TypeError, errmsg, msg=msg): int(x, 2) errmsg = 'invalid literal' - with self.assertRaisesRegexp(ValueError, errmsg, msg=msg): + with self.assertRaisesRegexp(ValueError, errmsg, msg=msg), \ + test_support.check_py3k_warnings(quiet=True): int(f('A' * 0x10)) def test_int_buffer(self): - self.assertEqual(int(buffer('123', 1, 2)), 23) - self.assertEqual(int(buffer('123\x00', 1, 2)), 23) - self.assertEqual(int(buffer('123 ', 1, 2)), 23) - self.assertEqual(int(buffer('123A', 1, 2)), 23) - self.assertEqual(int(buffer('1234', 1, 2)), 23) + with test_support.check_py3k_warnings(): + self.assertEqual(int(buffer('123', 1, 2)), 23) + self.assertEqual(int(buffer('123\x00', 1, 2)), 23) + self.assertEqual(int(buffer('123 ', 1, 2)), 23) + self.assertEqual(int(buffer('123A', 1, 2)), 23) + self.assertEqual(int(buffer('1234', 1, 2)), 23) def test_error_on_string_float_for_x(self): self.assertRaises(ValueError, int, '1.2') -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 13:18:47 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Sun, 29 Nov 2015 18:18:47 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fixed_yet_one_?= =?utf-8?q?syntax_error_in_test=5Fxpickle_in_Python_2=2E5=2E?= Message-ID: <20151129181847.22402.72868@psf.io> https://hg.python.org/cpython/rev/436e58ae3bab changeset: 99390:436e58ae3bab branch: 2.7 user: Serhiy Storchaka date: Sun Nov 29 20:18:27 2015 +0200 summary: Fixed yet one syntax error in test_xpickle in Python 2.5. files: Lib/test/pickletester.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -746,7 +746,7 @@ # 'P', # PERSID # 'Pabc', 'S', # STRING - b"S'abc'", + "S'abc'", 'T', # BINSTRING 'T\x03\x00\x00', 'T\x03\x00\x00\x00', -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Sun Nov 29 22:29:48 2015 From: python-checkins at python.org (martin.panter) Date: Mon, 30 Nov 2015 03:29:48 +0000 Subject: [Python-checkins] =?utf-8?q?cpython=3A_Issue_=235319=3A_New_Py=5F?= =?utf-8?q?FinalizeEx=28=29_API_to_exit_with_status_120_on_failure?= Message-ID: <20151130032946.648.4874@psf.io> https://hg.python.org/cpython/rev/6b08429a3932 changeset: 99391:6b08429a3932 parent: 99385:c852c7d8d681 user: Martin Panter date: Mon Nov 30 03:18:29 2015 +0000 summary: Issue #5319: New Py_FinalizeEx() API to exit with status 120 on failure files: Doc/c-api/init.rst | 33 +++++++++----- Doc/c-api/intro.rst | 4 +- Doc/c-api/sys.rst | 14 ++++-- Doc/extending/embedding.rst | 6 +- Doc/includes/run-func.c | 4 +- Doc/library/sys.rst | 7 ++- Doc/whatsnew/3.6.rst | 6 +- Include/pylifecycle.h | 1 + Lib/test/test_cmd_line.py | 3 +- Misc/NEWS | 3 + Misc/SpecialBuilds.txt | 8 +- Modules/main.c | 8 ++- PC/bdist_wininst/install.c | 18 +++++--- PC/python3.def | 1 + Python/frozenmain.c | 4 +- Python/pylifecycle.c | 52 +++++++++++++++++------ Python/pystate.c | 2 +- Tools/scripts/combinerefs.py | 4 +- 18 files changed, 120 insertions(+), 58 deletions(-) diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -25,7 +25,7 @@ triple: module; search; path single: PySys_SetArgv() single: PySys_SetArgvEx() - single: Py_Finalize() + single: Py_FinalizeEx() Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the @@ -34,7 +34,7 @@ modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes the module search path (``sys.path``). It does not set ``sys.argv``; use :c:func:`PySys_SetArgvEx` for that. This is a no-op when called for a second time - (without calling :c:func:`Py_Finalize` first). There is no return value; it is a + (without calling :c:func:`Py_FinalizeEx` first). There is no return value; it is a fatal error if the initialization fails. @@ -48,19 +48,20 @@ .. c:function:: int Py_IsInitialized() Return true (nonzero) when the Python interpreter has been initialized, false - (zero) if not. After :c:func:`Py_Finalize` is called, this returns false until + (zero) if not. After :c:func:`Py_FinalizeEx` is called, this returns false until :c:func:`Py_Initialize` is called again. -.. c:function:: void Py_Finalize() +.. c:function:: int Py_FinalizeEx() Undo all initializations made by :c:func:`Py_Initialize` and subsequent use of Python/C API functions, and destroy all sub-interpreters (see :c:func:`Py_NewInterpreter` below) that were created and not yet destroyed since the last call to :c:func:`Py_Initialize`. Ideally, this frees all memory allocated by the Python interpreter. This is a no-op when called for a second - time (without calling :c:func:`Py_Initialize` again first). There is no return - value; errors during finalization are ignored. + time (without calling :c:func:`Py_Initialize` again first). Normally the + return value is 0. If there were errors during finalization + (flushing buffered data), -1 is returned. This function is provided for a number of reasons. An embedding application might want to restart Python without having to restart the application itself. @@ -79,7 +80,15 @@ freed. Some memory allocated by extension modules may not be freed. Some extensions may not work properly if their initialization routine is called more than once; this can happen if an application calls :c:func:`Py_Initialize` and - :c:func:`Py_Finalize` more than once. + :c:func:`Py_FinalizeEx` more than once. + + .. versionadded:: 3.6 + + +.. c:function:: void Py_Finalize() + + This is a backwards-compatible version of :c:func:`Py_FinalizeEx` that + disregards the return value. Process-wide parameters @@ -107,7 +116,7 @@ Note that :data:`sys.stderr` always uses the "backslashreplace" error handler, regardless of this (or any other) setting. - If :c:func:`Py_Finalize` is called, this function will need to be called + If :c:func:`Py_FinalizeEx` is called, this function will need to be called again in order to affect subsequent calls to :c:func:`Py_Initialize`. Returns 0 if successful, a nonzero value on error (e.g. calling after the @@ -918,7 +927,7 @@ entry.) .. index:: - single: Py_Finalize() + single: Py_FinalizeEx() single: Py_Initialize() Extension modules are shared between (sub-)interpreters as follows: the first @@ -928,7 +937,7 @@ and filled with the contents of this copy; the extension's ``init`` function is not called. Note that this is different from what happens when an extension is imported after the interpreter has been completely re-initialized by calling - :c:func:`Py_Finalize` and :c:func:`Py_Initialize`; in that case, the extension's + :c:func:`Py_FinalizeEx` and :c:func:`Py_Initialize`; in that case, the extension's ``initmodule`` function *is* called again. .. index:: single: close() (in module os) @@ -936,14 +945,14 @@ .. c:function:: void Py_EndInterpreter(PyThreadState *tstate) - .. index:: single: Py_Finalize() + .. index:: single: Py_FinalizeEx() Destroy the (sub-)interpreter represented by the given thread state. The given thread state must be the current thread state. See the discussion of thread states below. When the call returns, the current thread state is *NULL*. All thread states associated with this interpreter are destroyed. (The global interpreter lock must be held before calling this function and is still held - when it returns.) :c:func:`Py_Finalize` will destroy all sub-interpreters that + when it returns.) :c:func:`Py_FinalizeEx` will destroy all sub-interpreters that haven't been explicitly destroyed at that point. diff --git a/Doc/c-api/intro.rst b/Doc/c-api/intro.rst --- a/Doc/c-api/intro.rst +++ b/Doc/c-api/intro.rst @@ -578,9 +578,9 @@ application may want to start over (make another call to :c:func:`Py_Initialize`) or the application is simply done with its use of Python and wants to free memory allocated by Python. This can be accomplished -by calling :c:func:`Py_Finalize`. The function :c:func:`Py_IsInitialized` returns +by calling :c:func:`Py_FinalizeEx`. The function :c:func:`Py_IsInitialized` returns true if Python is currently in the initialized state. More information about -these functions is given in a later chapter. Notice that :c:func:`Py_Finalize` +these functions is given in a later chapter. Notice that :c:func:`Py_FinalizeEx` does *not* free all memory allocated by the Python interpreter, e.g. memory allocated by extension modules currently cannot be released. diff --git a/Doc/c-api/sys.rst b/Doc/c-api/sys.rst --- a/Doc/c-api/sys.rst +++ b/Doc/c-api/sys.rst @@ -212,20 +212,24 @@ .. c:function:: void Py_Exit(int status) .. index:: - single: Py_Finalize() + single: Py_FinalizeEx() single: exit() - Exit the current process. This calls :c:func:`Py_Finalize` and then calls the - standard C library function ``exit(status)``. + Exit the current process. This calls :c:func:`Py_FinalizeEx` and then calls the + standard C library function ``exit(status)``. If :c:func:`Py_FinalizeEx` + indicates an error, the exit status is set to 120. + + .. versionchanged:: 3.6 + Errors from finalization no longer ignored. .. c:function:: int Py_AtExit(void (*func) ()) .. index:: - single: Py_Finalize() + single: Py_FinalizeEx() single: cleanup functions - Register a cleanup function to be called by :c:func:`Py_Finalize`. The cleanup + Register a cleanup function to be called by :c:func:`Py_FinalizeEx`. The cleanup function will be called with no arguments and should return no value. At most 32 cleanup functions can be registered. When the registration is successful, :c:func:`Py_AtExit` returns ``0``; on failure, it returns ``-1``. The cleanup diff --git a/Doc/extending/embedding.rst b/Doc/extending/embedding.rst --- a/Doc/extending/embedding.rst +++ b/Doc/extending/embedding.rst @@ -67,7 +67,9 @@ Py_Initialize(); PyRun_SimpleString("from time import time,ctime\n" "print('Today is', ctime(time()))\n"); - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + exit(120); + } PyMem_RawFree(program); return 0; } @@ -76,7 +78,7 @@ :c:func:`Py_Initialize` to inform the interpreter about paths to Python run-time libraries. Next, the Python interpreter is initialized with :c:func:`Py_Initialize`, followed by the execution of a hard-coded Python script -that prints the date and time. Afterwards, the :c:func:`Py_Finalize` call shuts +that prints the date and time. Afterwards, the :c:func:`Py_FinalizeEx` call shuts the interpreter down, followed by the end of the program. In a real program, you may want to get the Python script from another source, perhaps a text-editor routine, a file, or a database. Getting the Python code from a file can better diff --git a/Doc/includes/run-func.c b/Doc/includes/run-func.c --- a/Doc/includes/run-func.c +++ b/Doc/includes/run-func.c @@ -63,6 +63,8 @@ fprintf(stderr, "Failed to load \"%s\"\n", argv[1]); return 1; } - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + return 120; + } return 0; } diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -255,7 +255,7 @@ (defaulting to zero), or another type of object. If it is an integer, zero is considered "successful termination" and any nonzero value is considered "abnormal termination" by shells and the like. Most systems require it to be - in the range 0-127, and produce undefined results otherwise. Some systems + in the range 0--127, and produce undefined results otherwise. Some systems have a convention for assigning specific meanings to specific exit codes, but these are generally underdeveloped; Unix programs generally use 2 for command line syntax errors and 1 for all other kind of errors. If another type of @@ -268,6 +268,11 @@ the process when called from the main thread, and the exception is not intercepted. + .. versionchanged:: 3.6 + If an error occurs in the cleanup after the Python interpreter + has caught :exc:`SystemExit` (such as an error flushing buffered data + in the standard streams), the exit status is changed to 120. + .. data:: flags diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst --- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -171,7 +171,8 @@ Build and C API Changes ======================= -* None yet. +* New :c:func:`Py_FinalizeEx` API which indicates if flushing buffered data + failed (:issue:`5319`). Deprecated @@ -247,4 +248,5 @@ Changes in the C API -------------------- -* None yet. +* :c:func:`Py_Exit` (and the main interpreter) now override the exit status + with 120 if flushing buffered data failed. See :issue:`5319`. diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h --- a/Include/pylifecycle.h +++ b/Include/pylifecycle.h @@ -27,6 +27,7 @@ PyAPI_FUNC(void) _Py_InitializeEx_Private(int, int); #endif PyAPI_FUNC(void) Py_Finalize(void); +PyAPI_FUNC(int) Py_FinalizeEx(void); PyAPI_FUNC(int) Py_IsInitialized(void); PyAPI_FUNC(PyThreadState *) Py_NewInterpreter(void); PyAPI_FUNC(void) Py_EndInterpreter(PyThreadState *); diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -348,8 +348,9 @@ test.support.SuppressCrashReport().__enter__() sys.stdout.write('x') os.close(sys.stdout.fileno())""" - rc, out, err = assert_python_ok('-c', code) + rc, out, err = assert_python_failure('-c', code) self.assertEqual(b'', out) + self.assertEqual(120, rc) self.assertRegex(err.decode('ascii', 'ignore'), 'Exception ignored in.*\nOSError: .*') diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #5319: New Py_FinalizeEx() API allowing Python to set an exit status + of 120 on failure to flush buffered streams. + - Issue #25485: telnetlib.Telnet is now a context manager. - Issue #24097: Fixed crash in object.__reduce__() if slot name is freed inside diff --git a/Misc/SpecialBuilds.txt b/Misc/SpecialBuilds.txt --- a/Misc/SpecialBuilds.txt +++ b/Misc/SpecialBuilds.txt @@ -65,9 +65,9 @@ simply by virtue of being in the list. envvar PYTHONDUMPREFS - If this envvar exists, Py_Finalize() arranges to print a list of all + If this envvar exists, Py_FinalizeEx() arranges to print a list of all still-live heap objects. This is printed twice, in different formats, - before and after Py_Finalize has cleaned up everything it can clean up. The + before and after Py_FinalizeEx has cleaned up everything it can clean up. The first output block produces the repr() of each object so is more informative; however, a lot of stuff destined to die is still alive then. The second output block is much harder to work with (repr() can't be invoked @@ -144,7 +144,7 @@ envvar PYTHONMALLOCSTATS If this envvar exists, a report of pymalloc summary statistics is printed to - stderr whenever a new arena is allocated, and also by Py_Finalize(). + stderr whenever a new arena is allocated, and also by Py_FinalizeEx(). Changed in 2.5: The number of extra bytes allocated is 4*sizeof(size_t). Before it was 16 on all boxes, reflecting that Python couldn't make use of @@ -179,7 +179,7 @@ */ int tp_maxalloc; -Allocation and deallocation code keeps these counts up to date. Py_Finalize() +Allocation and deallocation code keeps these counts up to date. Py_FinalizeEx() displays a summary of the info returned by sys.getcounts() (see below), along with assorted other special allocation counts (like the number of tuple allocations satisfied by a tuple free-list, the number of 1-character strings diff --git a/Modules/main.c b/Modules/main.c --- a/Modules/main.c +++ b/Modules/main.c @@ -654,7 +654,7 @@ Py_SetProgramName(wbuf); /* Don't free wbuf, the argument to Py_SetProgramName - * must remain valid until the Py_Finalize is called. + * must remain valid until Py_FinalizeEx is called. */ } else { Py_SetProgramName(argv[0]); @@ -785,7 +785,11 @@ sts = PyRun_AnyFileFlags(stdin, "", &cf) != 0; } - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + /* Value unlikely to be confused with a non-error exit status or + other special meaning */ + sts = 120; + } #ifdef __INSURE__ /* Insure++ is a memory analysis tool that aids in discovering diff --git a/PC/bdist_wininst/install.c b/PC/bdist_wininst/install.c --- a/PC/bdist_wininst/install.c +++ b/PC/bdist_wininst/install.c @@ -709,7 +709,7 @@ * 1 if the Python-dll does not export the functions we need * 2 if no install-script is specified in pathname * 3 if the install-script file could not be opened - * the return value of PyRun_SimpleString() otherwise, + * the return value of PyRun_SimpleString() or Py_FinalizeEx() otherwise, * which is 0 if everything is ok, -1 if an exception had occurred * in the install-script. */ @@ -722,7 +722,7 @@ DECLPROC(hPython, void, Py_Initialize, (void)); DECLPROC(hPython, int, PySys_SetArgv, (int, wchar_t **)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); - DECLPROC(hPython, void, Py_Finalize, (void)); + DECLPROC(hPython, int, Py_FinalizeEx, (void)); DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...)); DECLPROC(hPython, PyObject *, PyCFunction_New, (PyMethodDef *, PyObject *)); @@ -730,7 +730,7 @@ DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *)); if (!Py_Initialize || !PySys_SetArgv - || !PyRun_SimpleString || !Py_Finalize) + || !PyRun_SimpleString || !Py_FinalizeEx) return 1; if (!Py_BuildValue || !PyArg_ParseTuple || !PyErr_Format) @@ -777,7 +777,9 @@ } } } - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + result = -1; + } close(fh); return result; @@ -839,11 +841,11 @@ int rc; DECLPROC(hPython, void, Py_Initialize, (void)); DECLPROC(hPython, void, Py_SetProgramName, (wchar_t *)); - DECLPROC(hPython, void, Py_Finalize, (void)); + DECLPROC(hPython, int, Py_FinalizeEx, (void)); DECLPROC(hPython, int, PyRun_SimpleString, (char *)); DECLPROC(hPython, void, PyErr_Print, (void)); - if (!Py_Initialize || !Py_SetProgramName || !Py_Finalize || + if (!Py_Initialize || !Py_SetProgramName || !Py_FinalizeEx || !PyRun_SimpleString || !PyErr_Print) return -1; @@ -853,7 +855,9 @@ rc = PyRun_SimpleString(script); if (rc) PyErr_Print(); - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + rc = -1; + } return rc; } diff --git a/PC/python3.def b/PC/python3.def --- a/PC/python3.def +++ b/PC/python3.def @@ -648,6 +648,7 @@ Py_FatalError=python36.Py_FatalError Py_FileSystemDefaultEncoding=python36.Py_FileSystemDefaultEncoding DATA Py_Finalize=python36.Py_Finalize + Py_FinalizeEx=python36.Py_FinalizeEx Py_GetBuildInfo=python36.Py_GetBuildInfo Py_GetCompiler=python36.Py_GetCompiler Py_GetCopyright=python36.Py_GetCopyright diff --git a/Python/frozenmain.c b/Python/frozenmain.c --- a/Python/frozenmain.c +++ b/Python/frozenmain.c @@ -99,7 +99,9 @@ #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + sts = 120; + } error: PyMem_RawFree(argv_copy); diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -154,8 +154,8 @@ return 0; } -/* Global initializations. Can be undone by Py_Finalize(). Don't - call this twice without an intervening Py_Finalize() call. When +/* Global initializations. Can be undone by Py_FinalizeEx(). Don't + call this twice without an intervening Py_FinalizeEx() call. When initializations fail, a fatal error is issued and the function does not return. On return, the first thread and interpreter state have been created. @@ -327,11 +327,11 @@ (void) PyThreadState_Swap(tstate); #ifdef WITH_THREAD - /* We can't call _PyEval_FiniThreads() in Py_Finalize because + /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because destroying the GIL might fail when it is being referenced from another running thread (see issue #9901). Instead we destroy the previously created GIL here, which ensures - that we can call Py_Initialize / Py_Finalize multiple times. */ + that we can call Py_Initialize / Py_FinalizeEx multiple times. */ _PyEval_FiniThreads(); /* Auto-thread-state API */ @@ -477,28 +477,35 @@ return r > 0; } -static void +static int flush_std_files(void) { PyObject *fout = _PySys_GetObjectId(&PyId_stdout); PyObject *ferr = _PySys_GetObjectId(&PyId_stderr); PyObject *tmp; + int status = 0; if (fout != NULL && fout != Py_None && !file_is_closed(fout)) { tmp = _PyObject_CallMethodId(fout, &PyId_flush, ""); - if (tmp == NULL) + if (tmp == NULL) { PyErr_WriteUnraisable(fout); + status = -1; + } else Py_DECREF(tmp); } if (ferr != NULL && ferr != Py_None && !file_is_closed(ferr)) { tmp = _PyObject_CallMethodId(ferr, &PyId_flush, ""); - if (tmp == NULL) + if (tmp == NULL) { PyErr_Clear(); + status = -1; + } else Py_DECREF(tmp); } + + return status; } /* Undo the effect of Py_Initialize(). @@ -515,14 +522,15 @@ */ -void -Py_Finalize(void) +int +Py_FinalizeEx(void) { PyInterpreterState *interp; PyThreadState *tstate; + int status = 0; if (!initialized) - return; + return status; wait_for_thread_shutdown(); @@ -547,7 +555,9 @@ initialized = 0; /* Flush sys.stdout and sys.stderr */ - flush_std_files(); + if (flush_std_files() < 0) { + status = -1; + } /* Disable signal handling */ PyOS_FiniInterrupts(); @@ -576,7 +586,9 @@ PyImport_Cleanup(); /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ - flush_std_files(); + if (flush_std_files() < 0) { + status = -1; + } /* Collect final garbage. This disposes of cycles created by * class definitions, for example. @@ -696,6 +708,13 @@ #endif call_ll_exitfuncs(); + return status; +} + +void +Py_Finalize(void) +{ + Py_FinalizeEx(); } /* Create and initialize a new interpreter and thread, and return the @@ -803,7 +822,7 @@ frames, and that it is its interpreter's only remaining thread. It is a fatal error to violate these constraints. - (Py_Finalize() doesn't have these constraints -- it zaps + (Py_FinalizeEx() doesn't have these constraints -- it zaps everything, regardless.) Locking: as above. @@ -1016,7 +1035,8 @@ mode = "rb"; buf = _PyObject_CallMethodId(io, &PyId_open, "isiOOOi", fd, mode, buffering, - Py_None, Py_None, Py_None, 0); + Py_None, Py_None, /* encoding, errors */ + Py_None, 0); /* newline, closefd */ if (buf == NULL) goto error; @@ -1450,7 +1470,9 @@ void Py_Exit(int sts) { - Py_Finalize(); + if (Py_FinalizeEx() < 0) { + sts = 120; + } exit(sts); } diff --git a/Python/pystate.c b/Python/pystate.c --- a/Python/pystate.c +++ b/Python/pystate.c @@ -686,7 +686,7 @@ } /* Internal initialization/finalization functions called by - Py_Initialize/Py_Finalize + Py_Initialize/Py_FinalizeEx */ void _PyGILState_Init(PyInterpreterState *i, PyThreadState *t) diff --git a/Tools/scripts/combinerefs.py b/Tools/scripts/combinerefs.py --- a/Tools/scripts/combinerefs.py +++ b/Tools/scripts/combinerefs.py @@ -6,7 +6,7 @@ A helper for analyzing PYTHONDUMPREFS output. When the PYTHONDUMPREFS envar is set in a debug build, at Python shutdown -time Py_Finalize() prints the list of all live objects twice: first it +time Py_FinalizeEx() prints the list of all live objects twice: first it prints the repr() of each object while the interpreter is still fully intact. After cleaning up everything it can, it prints all remaining live objects again, but the second time just prints their addresses, refcounts, and type @@ -41,7 +41,7 @@ objects shown in the repr: the repr was captured from the first output block, and some of the containees may have been released since then. For example, it's common for the line showing the dict of interned strings to display -strings that no longer exist at the end of Py_Finalize; this can be recognized +strings that no longer exist at the end of Py_FinalizeEx; this can be recognized (albeit painfully) because such containees don't have a line of their own. The objects are listed in allocation order, with most-recently allocated -- Repository URL: https://hg.python.org/cpython From solipsis at pitrou.net Mon Nov 30 03:42:31 2015 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 30 Nov 2015 08:42:31 +0000 Subject: [Python-checkins] Daily reference leaks (6b08429a3932): sum=28 Message-ID: <20151130084231.59403.6966@psf.io> results for 6b08429a3932 on branch "default" -------------------------------------------- test_functools leaked [0, 2, 2] memory blocks, sum=4 test_pickle leaked [4, 4, 4] references, sum=12 test_pickle leaked [4, 4, 4] memory blocks, sum=12 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogFNst38', '--timeout', '7200'] From python-checkins at python.org Mon Nov 30 10:37:45 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 15:37:45 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Issue_=2325718=3A_Fixed_copying_object_with_state_with_b?= =?utf-8?q?oolean_value_is_false=2E?= Message-ID: <20151130153743.87879.41978@psf.io> https://hg.python.org/cpython/rev/962086677306 changeset: 99395:962086677306 parent: 99391:6b08429a3932 parent: 99394:fecb07050aae user: Serhiy Storchaka date: Mon Nov 30 17:37:13 2015 +0200 summary: Issue #25718: Fixed copying object with state with boolean value is false. files: Lib/copy.py | 4 ++-- Lib/test/test_copy.py | 9 +++++++++ Misc/NEWS | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py --- a/Lib/copy.py +++ b/Lib/copy.py @@ -279,7 +279,7 @@ if n > 2: state = info[2] else: - state = {} + state = None if n > 3: listiter = info[3] else: @@ -293,7 +293,7 @@ y = callable(*args) memo[id(x)] = y - if state: + if state is not None: if deep: state = deepcopy(state, memo) if hasattr(y, '__setstate__'): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -213,6 +213,9 @@ return self.foo == other.foo x = C(42) self.assertEqual(copy.copy(x), x) + # State with boolean value is false (issue #25718) + x = C(0.0) + self.assertEqual(copy.copy(x), x) # The deepcopy() method @@ -517,6 +520,12 @@ self.assertEqual(y, x) self.assertIsNot(y, x) self.assertIsNot(y.foo, x.foo) + # State with boolean value is false (issue #25718) + x = C([]) + y = copy.deepcopy(x) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertIsNot(y.foo, x.foo) def test_deepcopy_reflexive_inst(self): class C: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -107,6 +107,8 @@ Library ------- +- Issue #25718: Fixed copying object with state with boolean value is false. + - Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 10:37:45 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 15:37:45 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMi43KTogSXNzdWUgIzI1NzE4?= =?utf-8?q?=3A_Fixed_copying_object_with_state_with_boolean_value_is_false?= =?utf-8?q?=2E?= Message-ID: <20151130153740.59401.84672@psf.io> https://hg.python.org/cpython/rev/3d39e1e2dcb3 changeset: 99393:3d39e1e2dcb3 branch: 2.7 parent: 99390:436e58ae3bab user: Serhiy Storchaka date: Mon Nov 30 17:20:02 2015 +0200 summary: Issue #25718: Fixed copying object with state with boolean value is false. files: Lib/copy.py | 4 ++-- Lib/test/test_copy.py | 9 +++++++++ Misc/NEWS | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py --- a/Lib/copy.py +++ b/Lib/copy.py @@ -315,7 +315,7 @@ if n > 2: state = info[2] else: - state = {} + state = None if n > 3: listiter = info[3] else: @@ -329,7 +329,7 @@ y = callable(*args) memo[id(x)] = y - if state: + if state is not None: if deep: state = deepcopy(state, memo) if hasattr(y, '__setstate__'): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -165,6 +165,9 @@ return cmp(self.foo, other.foo) x = C(42) self.assertEqual(copy.copy(x), x) + # State with boolean value is false (issue #25718) + x = C(0.0) + self.assertEqual(copy.copy(x), x) # The deepcopy() method @@ -395,6 +398,12 @@ x = C([42]) y = copy.deepcopy(x) self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertIsNot(y.foo, x.foo) + # State with boolean value is false (issue #25718) + x = C([]) + y = copy.deepcopy(x) + self.assertEqual(y, x) self.assertTrue(y is not x) self.assertTrue(y.foo is not x.foo) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -20,6 +20,8 @@ Library ------- +- Issue #25718: Fixed copying object with state with boolean value is false. + - Issue #25742: :func:`locale.setlocale` now accepts a Unicode string for its second parameter. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 10:37:50 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 15:37:50 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325718=3A_Fixed_copying_object_with_state_with_boolean?= =?utf-8?q?_value_is_false=2E?= Message-ID: <20151130153740.676.45559@psf.io> https://hg.python.org/cpython/rev/fecb07050aae changeset: 99394:fecb07050aae branch: 3.5 parent: 99384:4897438543da parent: 99392:095d21df9374 user: Serhiy Storchaka date: Mon Nov 30 17:35:40 2015 +0200 summary: Issue #25718: Fixed copying object with state with boolean value is false. files: Lib/copy.py | 4 ++-- Lib/test/test_copy.py | 9 +++++++++ Misc/NEWS | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py --- a/Lib/copy.py +++ b/Lib/copy.py @@ -279,7 +279,7 @@ if n > 2: state = info[2] else: - state = {} + state = None if n > 3: listiter = info[3] else: @@ -293,7 +293,7 @@ y = callable(*args) memo[id(x)] = y - if state: + if state is not None: if deep: state = deepcopy(state, memo) if hasattr(y, '__setstate__'): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -213,6 +213,9 @@ return self.foo == other.foo x = C(42) self.assertEqual(copy.copy(x), x) + # State with boolean value is false (issue #25718) + x = C(0.0) + self.assertEqual(copy.copy(x), x) # The deepcopy() method @@ -517,6 +520,12 @@ self.assertEqual(y, x) self.assertIsNot(y, x) self.assertIsNot(y.foo, x.foo) + # State with boolean value is false (issue #25718) + x = C([]) + y = copy.deepcopy(x) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertIsNot(y.foo, x.foo) def test_deepcopy_reflexive_inst(self): class C: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -20,6 +20,8 @@ Library ------- +- Issue #25718: Fixed copying object with state with boolean value is false. + - Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 10:37:50 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 15:37:50 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NzE4?= =?utf-8?q?=3A_Fixed_copying_object_with_state_with_boolean_value_is_false?= =?utf-8?q?=2E?= Message-ID: <20151130153740.664.16255@psf.io> https://hg.python.org/cpython/rev/095d21df9374 changeset: 99392:095d21df9374 branch: 3.4 parent: 99382:d47e5b162072 user: Serhiy Storchaka date: Mon Nov 30 17:20:02 2015 +0200 summary: Issue #25718: Fixed copying object with state with boolean value is false. files: Lib/copy.py | 4 ++-- Lib/test/test_copy.py | 9 +++++++++ Misc/NEWS | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Lib/copy.py b/Lib/copy.py --- a/Lib/copy.py +++ b/Lib/copy.py @@ -281,7 +281,7 @@ if n > 2: state = info[2] else: - state = {} + state = None if n > 3: listiter = info[3] else: @@ -295,7 +295,7 @@ y = callable(*args) memo[id(x)] = y - if state: + if state is not None: if deep: state = deepcopy(state, memo) if hasattr(y, '__setstate__'): diff --git a/Lib/test/test_copy.py b/Lib/test/test_copy.py --- a/Lib/test/test_copy.py +++ b/Lib/test/test_copy.py @@ -180,6 +180,9 @@ return self.foo == other.foo x = C(42) self.assertEqual(copy.copy(x), x) + # State with boolean value is false (issue #25718) + x = C(0.0) + self.assertEqual(copy.copy(x), x) # The deepcopy() method @@ -448,6 +451,12 @@ self.assertEqual(y, x) self.assertIsNot(y, x) self.assertIsNot(y.foo, x.foo) + # State with boolean value is false (issue #25718) + x = C([]) + y = copy.deepcopy(x) + self.assertEqual(y, x) + self.assertIsNot(y, x) + self.assertIsNot(y.foo, x.foo) def test_deepcopy_reflexive_inst(self): class C: diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -113,6 +113,8 @@ Library ------- +- Issue #25718: Fixed copying object with state with boolean value is false. + - Issue #10131: Fixed deep copying of minidom documents. Based on patch by Marian Ganisin. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:21:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:21:14 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Fixed_reference_leak_when_read_truncated_pickle=2E?= Message-ID: <20151130222113.29830.41219@psf.io> https://hg.python.org/cpython/rev/0a36c8fe4703 changeset: 99398:0a36c8fe4703 parent: 99395:962086677306 parent: 99397:f0469025df14 user: Serhiy Storchaka date: Tue Dec 01 00:20:49 2015 +0200 summary: Fixed reference leak when read truncated pickle. files: Modules/_pickle.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5247,8 +5247,10 @@ return -1; if ((len = _Unpickler_Readline(self, &s)) >= 0) { - if (len < 2) + if (len < 2) { + Py_DECREF(module_name); return bad_readline(); + } class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); if (class_name != NULL) { cls = find_class(self, module_name, class_name); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:21:14 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:21:14 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Fixed_reference_leak_when_read_truncated_pickle=2E?= Message-ID: <20151130222113.650.37702@psf.io> https://hg.python.org/cpython/rev/f0469025df14 changeset: 99397:f0469025df14 branch: 3.5 parent: 99394:fecb07050aae parent: 99396:67b341701f5e user: Serhiy Storchaka date: Tue Dec 01 00:20:36 2015 +0200 summary: Fixed reference leak when read truncated pickle. files: Modules/_pickle.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5184,8 +5184,10 @@ return -1; if ((len = _Unpickler_Readline(self, &s)) >= 0) { - if (len < 2) + if (len < 2) { + Py_DECREF(module_name); return bad_readline(); + } class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); if (class_name != NULL) { cls = find_class(self, module_name, class_name); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:21:18 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:21:18 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Fixed_referenc?= =?utf-8?q?e_leak_when_read_truncated_pickle=2E?= Message-ID: <20151130222113.87887.60635@psf.io> https://hg.python.org/cpython/rev/67b341701f5e changeset: 99396:67b341701f5e branch: 3.4 parent: 99392:095d21df9374 user: Serhiy Storchaka date: Tue Dec 01 00:18:23 2015 +0200 summary: Fixed reference leak when read truncated pickle. files: Modules/_pickle.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/Modules/_pickle.c b/Modules/_pickle.c --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -5115,8 +5115,10 @@ return -1; if ((len = _Unpickler_Readline(self, &s)) >= 0) { - if (len < 2) + if (len < 2) { + Py_DECREF(module_name); return bad_readline(); + } class_name = PyUnicode_DecodeASCII(s, len - 1, "strict"); if (class_name != NULL) { cls = find_class(self, module_name, class_name); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:33:12 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:33:12 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=282=2E7=29=3A_Fixed_referenc?= =?utf-8?q?e_leak_when_read_truncated_pickle=2E?= Message-ID: <20151130223311.29824.58277@psf.io> https://hg.python.org/cpython/rev/6a35865eded4 changeset: 99399:6a35865eded4 branch: 2.7 parent: 99393:3d39e1e2dcb3 user: Serhiy Storchaka date: Tue Dec 01 00:32:49 2015 +0200 summary: Fixed reference leak when read truncated pickle. files: Modules/cPickle.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/Modules/cPickle.c b/Modules/cPickle.c --- a/Modules/cPickle.c +++ b/Modules/cPickle.c @@ -3969,7 +3969,10 @@ if (!module_name) return -1; if ((len = self->readline_func(self, &s)) >= 0) { - if (len < 2) return bad_readline(); + if (len < 2) { + Py_DECREF(module_name); + return bad_readline(); + } if ((class_name = PyString_FromStringAndSize(s, len - 1))) { class = find_class(module_name, class_name, self->find_class); -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:41:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:41:10 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Removed_debugging_output_of_exception_raised_by_=5F=5Freduce?= =?utf-8?q?=5F=5F_method=2E?= Message-ID: <20151130224109.29812.40774@psf.io> https://hg.python.org/cpython/rev/ef85dc8c0ba0 changeset: 99401:ef85dc8c0ba0 branch: 3.5 parent: 99397:f0469025df14 parent: 99400:65a23d24fd12 user: Serhiy Storchaka date: Tue Dec 01 00:39:45 2015 +0200 summary: Removed debugging output of exception raised by __reduce__ method. files: Lib/pickle.py | 8 +------- 1 files changed, 1 insertions(+), 7 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1391,13 +1391,7 @@ stack = self.stack args = stack.pop() func = stack[-1] - try: - value = func(*args) - except: - print(sys.exc_info()) - print(func, args) - raise - stack[-1] = value + stack[-1] = func(*args) dispatch[REDUCE[0]] = load_reduce def load_pop(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:41:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:41:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Removed_debugging_output_of_exception_raised_by_=5F=5Fre?= =?utf-8?q?duce=5F=5F_method=2E?= Message-ID: <20151130224110.69580.65958@psf.io> https://hg.python.org/cpython/rev/ac0f7ed0e94d changeset: 99402:ac0f7ed0e94d parent: 99398:0a36c8fe4703 parent: 99401:ef85dc8c0ba0 user: Serhiy Storchaka date: Tue Dec 01 00:40:50 2015 +0200 summary: Removed debugging output of exception raised by __reduce__ method. files: Lib/pickle.py | 8 +------- 1 files changed, 1 insertions(+), 7 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1398,13 +1398,7 @@ stack = self.stack args = stack.pop() func = stack[-1] - try: - value = func(*args) - except: - print(sys.exc_info()) - print(func, args) - raise - stack[-1] = value + stack[-1] = func(*args) dispatch[REDUCE[0]] = load_reduce def load_pop(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 17:41:10 2015 From: python-checkins at python.org (serhiy.storchaka) Date: Mon, 30 Nov 2015 22:41:10 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=283=2E4=29=3A_Removed_debugg?= =?utf-8?q?ing_output_of_exception_raised_by_=5F=5Freduce=5F=5F_method=2E?= Message-ID: <20151130224109.13429.93406@psf.io> https://hg.python.org/cpython/rev/65a23d24fd12 changeset: 99400:65a23d24fd12 branch: 3.4 parent: 99396:67b341701f5e user: Serhiy Storchaka date: Tue Dec 01 00:39:25 2015 +0200 summary: Removed debugging output of exception raised by __reduce__ method. files: Lib/pickle.py | 8 +------- 1 files changed, 1 insertions(+), 7 deletions(-) diff --git a/Lib/pickle.py b/Lib/pickle.py --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -1388,13 +1388,7 @@ stack = self.stack args = stack.pop() func = stack[-1] - try: - value = func(*args) - except: - print(sys.exc_info()) - print(func, args) - raise - stack[-1] = value + stack[-1] = func(*args) dispatch[REDUCE[0]] = load_reduce def load_pop(self): -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 23:57:34 2015 From: python-checkins at python.org (zach.ware) Date: Tue, 01 Dec 2015 04:57:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAobWVyZ2UgMy40IC0+IDMuNSk6?= =?utf-8?q?_Issue_=2325767=3A_Merge_with_3=2E4?= Message-ID: <20151201045734.27997.31264@psf.io> https://hg.python.org/cpython/rev/fee19d2d7713 changeset: 99404:fee19d2d7713 branch: 3.5 parent: 99401:ef85dc8c0ba0 parent: 99403:f475379bf22c user: Zachary Ware date: Mon Nov 30 22:57:01 2015 -0600 summary: Issue #25767: Merge with 3.4 files: Doc/library/asyncio-eventloops.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -107,7 +107,7 @@ The resolution of the monotonic clock on Windows is usually around 15.6 msec. The best resolution is 0.5 msec. The resolution depends on the hardware (availability of `HPET -`_) and on the Windows +`_) and on the Windows configuration. See :ref:`asyncio delayed calls `. .. versionchanged:: 3.5 -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 23:57:34 2015 From: python-checkins at python.org (zach.ware) Date: Tue, 01 Dec 2015 04:57:34 +0000 Subject: [Python-checkins] =?utf-8?b?Y3B5dGhvbiAoMy40KTogSXNzdWUgIzI1NzY3?= =?utf-8?q?=3A_Link_to_English_Wikipedia_instead_of_French=2E?= Message-ID: <20151201045734.31415.8012@psf.io> https://hg.python.org/cpython/rev/f475379bf22c changeset: 99403:f475379bf22c branch: 3.4 parent: 99400:65a23d24fd12 user: Zachary Ware date: Mon Nov 30 22:56:17 2015 -0600 summary: Issue #25767: Link to English Wikipedia instead of French. files: Doc/library/asyncio-eventloops.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -109,7 +109,7 @@ The resolution of the monotonic clock on Windows is usually around 15.6 msec. The best resolution is 0.5 msec. The resolution depends on the hardware (availability of `HPET -`_) and on the Windows +`_) and on the Windows configuration. See :ref:`asyncio delayed calls `. -- Repository URL: https://hg.python.org/cpython From python-checkins at python.org Mon Nov 30 23:57:36 2015 From: python-checkins at python.org (zach.ware) Date: Tue, 01 Dec 2015 04:57:36 +0000 Subject: [Python-checkins] =?utf-8?q?cpython_=28merge_3=2E5_-=3E_default?= =?utf-8?q?=29=3A_Closes_=2325767=3A_Merge_with_3=2E5?= Message-ID: <20151201045734.13421.71028@psf.io> https://hg.python.org/cpython/rev/734247d5d0f9 changeset: 99405:734247d5d0f9 parent: 99402:ac0f7ed0e94d parent: 99404:fee19d2d7713 user: Zachary Ware date: Mon Nov 30 22:57:22 2015 -0600 summary: Closes #25767: Merge with 3.5 files: Doc/library/asyncio-eventloops.rst | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Doc/library/asyncio-eventloops.rst b/Doc/library/asyncio-eventloops.rst --- a/Doc/library/asyncio-eventloops.rst +++ b/Doc/library/asyncio-eventloops.rst @@ -107,7 +107,7 @@ The resolution of the monotonic clock on Windows is usually around 15.6 msec. The best resolution is 0.5 msec. The resolution depends on the hardware (availability of `HPET -`_) and on the Windows +`_) and on the Windows configuration. See :ref:`asyncio delayed calls `. .. versionchanged:: 3.5 -- Repository URL: https://hg.python.org/cpython