From solipsis at pitrou.net Mon Jan 1 04:14:17 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 01 Jan 2018 09:14:17 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=2 Message-ID: <20180101091417.1.E733A849134DEC68@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [0, 0, -2] memory blocks, sum=-2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogR6n_56', '--timeout', '7200'] From webhook-mailer at python.org Mon Jan 1 12:39:41 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Mon, 01 Jan 2018 17:39:41 -0000 Subject: [Python-checkins] bpo-32416: Add two new tests in test_sys_settrace. (#5072) Message-ID: https://github.com/python/cpython/commit/e8ed96550c6aa9a1e39c36e67e892994e25e2c41 commit: e8ed96550c6aa9a1e39c36e67e892994e25e2c41 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-01T19:39:38+02:00 summary: bpo-32416: Add two new tests in test_sys_settrace. (#5072) Move other test to more proper place. files: M Lib/test/test_sys_settrace.py diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index b4b578cc9dd..e6eb80ad86a 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -789,6 +789,14 @@ def test_jump_within_except_block(output): output.append(6) output.append(7) + @jump_test(2, 4, [1, 4, 5, -4]) + def test_jump_across_with(output): + output.append(1) + with tracecontext(output, 2): + output.append(3) + with tracecontext(output, 4): + output.append(5) + @jump_test(8, 11, [1, 3, 5, 11, 12]) def test_jump_out_of_complex_nested_blocks(output): output.append(1) @@ -840,6 +848,17 @@ def test_jump_over_break_in_try_finally_block(output): break output.append(13) + @jump_test(1, 7, [7, 8]) + def test_jump_over_for_block_before_else(output): + output.append(1) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) + # The second set of 'jump' tests are for things that are not allowed: @jump_test(2, 3, [1], (ValueError, 'after')) @@ -997,21 +1016,24 @@ def test_no_jump_out_of_finally_block(output): finally: output.append(5) - @jump_test(2, 4, [1, 4, 5, -4]) - def test_jump_across_with(output): + @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) + def test_no_jump_between_with_blocks(output): output.append(1) with tracecontext(output, 2): output.append(3) with tracecontext(output, 4): output.append(5) - @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) - def test_jump_across_with_2(output): + @jump_test(7, 4, [1, 6], (ValueError, 'into')) + def test_no_jump_into_for_block_before_else(output): output.append(1) - with tracecontext(output, 2): - output.append(3) - with tracecontext(output, 4): - output.append(5) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) def test_no_jump_to_non_integers(self): self.run_test(no_jump_to_non_integers, 2, "Spam", [True]) From webhook-mailer at python.org Mon Jan 1 13:51:15 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Mon, 01 Jan 2018 18:51:15 -0000 Subject: [Python-checkins] bpo-32416: Add two new tests in test_sys_settrace. (GH-5072) (#5074) Message-ID: https://github.com/python/cpython/commit/2de47ca109d0418c7c01e451b5614f748ad76ee9 commit: 2de47ca109d0418c7c01e451b5614f748ad76ee9 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-01-01T20:51:12+02:00 summary: bpo-32416: Add two new tests in test_sys_settrace. (GH-5072) (#5074) Move other test to more proper place. (cherry picked from commit e8ed96550c6aa9a1e39c36e67e892994e25e2c41) files: M Lib/test/test_sys_settrace.py diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index e5b380fbe0b..02524588252 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -715,6 +715,14 @@ def test_jump_within_except_block(output): output.append(6) output.append(7) + @jump_test(2, 4, [1, 4, 5, -4]) + def test_jump_across_with(output): + output.append(1) + with tracecontext(output, 2): + output.append(3) + with tracecontext(output, 4): + output.append(5) + @jump_test(8, 11, [1, 3, 5, 11, 12]) def test_jump_out_of_complex_nested_blocks(output): output.append(1) @@ -766,6 +774,17 @@ def test_jump_over_break_in_try_finally_block(output): break output.append(13) + @jump_test(1, 7, [7, 8]) + def test_jump_over_for_block_before_else(output): + output.append(1) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) + # The second set of 'jump' tests are for things that are not allowed: @jump_test(2, 3, [1], (ValueError, 'after')) @@ -911,21 +930,24 @@ def test_no_jump_out_of_finally_block(output): finally: output.append(5) - @jump_test(2, 4, [1, 4, 5, -4]) - def test_jump_across_with(output): + @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) + def test_no_jump_between_with_blocks(output): output.append(1) with tracecontext(output, 2): output.append(3) with tracecontext(output, 4): output.append(5) - @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) - def test_jump_across_with_2(output): + @jump_test(7, 4, [1, 6], (ValueError, 'into')) + def test_no_jump_into_for_block_before_else(output): output.append(1) - with tracecontext(output, 2): - output.append(3) - with tracecontext(output, 4): - output.append(5) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) def test_no_jump_to_non_integers(self): self.run_test(no_jump_to_non_integers, 2, "Spam", [True]) From webhook-mailer at python.org Mon Jan 1 13:51:33 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Mon, 01 Jan 2018 18:51:33 -0000 Subject: [Python-checkins] bpo-32416: Add two new tests in test_sys_settrace. (GH-5072) (#5073) Message-ID: https://github.com/python/cpython/commit/439ce8a93936d92e4f10765c482195a28e93ec76 commit: 439ce8a93936d92e4f10765c482195a28e93ec76 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-01-01T20:51:30+02:00 summary: bpo-32416: Add two new tests in test_sys_settrace. (GH-5072) (#5073) Move other test to more proper place. (cherry picked from commit e8ed96550c6aa9a1e39c36e67e892994e25e2c41) files: M Lib/test/test_sys_settrace.py diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 49fbf4d750d..5b3b0660b89 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -743,6 +743,14 @@ def test_jump_within_except_block(output): output.append(6) output.append(7) + @jump_test(2, 4, [1, 4, 5, -4]) + def test_jump_across_with(output): + output.append(1) + with tracecontext(output, 2): + output.append(3) + with tracecontext(output, 4): + output.append(5) + @jump_test(8, 11, [1, 3, 5, 11, 12]) def test_jump_out_of_complex_nested_blocks(output): output.append(1) @@ -794,6 +802,17 @@ def test_jump_over_break_in_try_finally_block(output): break output.append(13) + @jump_test(1, 7, [7, 8]) + def test_jump_over_for_block_before_else(output): + output.append(1) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) + # The second set of 'jump' tests are for things that are not allowed: @jump_test(2, 3, [1], (ValueError, 'after')) @@ -951,21 +970,24 @@ def test_no_jump_out_of_finally_block(output): finally: output.append(5) - @jump_test(2, 4, [1, 4, 5, -4]) - def test_jump_across_with(output): + @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) + def test_no_jump_between_with_blocks(output): output.append(1) with tracecontext(output, 2): output.append(3) with tracecontext(output, 4): output.append(5) - @jump_test(3, 5, [1, 2, -2], (ValueError, 'into')) - def test_jump_across_with_2(output): + @jump_test(7, 4, [1, 6], (ValueError, 'into')) + def test_no_jump_into_for_block_before_else(output): output.append(1) - with tracecontext(output, 2): - output.append(3) - with tracecontext(output, 4): - output.append(5) + if not output: # always false + for i in [3]: + output.append(4) + else: + output.append(6) + output.append(7) + output.append(8) def test_no_jump_to_non_integers(self): self.run_test(no_jump_to_non_integers, 2, "Spam", [True]) From webhook-mailer at python.org Mon Jan 1 19:38:38 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 02 Jan 2018 00:38:38 -0000 Subject: [Python-checkins] bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (#5078) Message-ID: https://github.com/python/cpython/commit/7cc42c356b0dc5ad9eaa9392789e84bd4aa1c7de commit: 7cc42c356b0dc5ad9eaa9392789e84bd4aa1c7de branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-02T02:38:35+02:00 summary: bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (#5078) files: M Lib/test/test_grammar.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 823315f8cd0..9f26e9c4fb0 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -805,6 +805,80 @@ def g2(): return 1 x = g2() check_syntax_error(self, "class foo:return 1") + def test_break_in_finally(self): + count = 0 + while count < 2: + count += 1 + try: + pass + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + continue + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + 1/0 + finally: + break + self.assertEqual(count, 1) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + pass + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + continue + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + 1/0 + finally: + break + self.assertEqual(count, 0) + + def test_return_in_finally(self): + def g1(): + try: + pass + finally: + return 1 + self.assertEqual(g1(), 1) + + def g2(): + try: + return 2 + finally: + return 3 + self.assertEqual(g2(), 3) + + def g3(): + try: + 1/0 + finally: + return 4 + self.assertEqual(g3(), 4) + def test_yield(self): # Allowed as standalone statement def g(): yield 1 From webhook-mailer at python.org Mon Jan 1 20:34:56 2018 From: webhook-mailer at python.org (R. David Murray) Date: Tue, 02 Jan 2018 01:34:56 -0000 Subject: [Python-checkins] bpo-32452: clarify term 'brackets' in generator tutorial (#5079) Message-ID: https://github.com/python/cpython/commit/f190eb59e60e2ae7a7cbd396458389a7a076e0d3 commit: f190eb59e60e2ae7a7cbd396458389a7a076e0d3 branch: master author: Emily Morehouse committer: R. David Murray date: 2018-01-01T20:34:53-05:00 summary: bpo-32452: clarify term 'brackets' in generator tutorial (#5079) Updates documentation for generator expressions in classes tutorial: Clarify usage of ambiguous term "brackets" by replacing with "square brackets". Updated subsequent lines to respect line breaks. (#5079) files: M Doc/tutorial/classes.rst diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 95141f94d6a..4676ef4b8a6 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -876,9 +876,9 @@ Generator Expressions ===================== Some simple generators can be coded succinctly as expressions using a syntax -similar to list comprehensions but with parentheses instead of brackets. These -expressions are designed for situations where the generator is used right away -by an enclosing function. Generator expressions are more compact but less +similar to list comprehensions but with parentheses instead of square brackets. +These expressions are designed for situations where the generator is used right +away by an enclosing function. Generator expressions are more compact but less versatile than full generator definitions and tend to be more memory friendly than equivalent list comprehensions. From webhook-mailer at python.org Tue Jan 2 03:20:15 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 02 Jan 2018 08:20:15 -0000 Subject: [Python-checkins] bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (GH-5078) (#5083) Message-ID: https://github.com/python/cpython/commit/aea95c2fbdec05dddd8b833a74eeb7ec8dc69706 commit: aea95c2fbdec05dddd8b833a74eeb7ec8dc69706 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-01-02T10:20:12+02:00 summary: bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (GH-5078) (#5083) (cherry picked from commit 7cc42c356b0dc5ad9eaa9392789e84bd4aa1c7de) files: M Lib/test/test_grammar.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 65e26bfd383..62f3251f051 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -805,6 +805,80 @@ def g2(): return 1 x = g2() check_syntax_error(self, "class foo:return 1") + def test_break_in_finally(self): + count = 0 + while count < 2: + count += 1 + try: + pass + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + continue + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + 1/0 + finally: + break + self.assertEqual(count, 1) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + pass + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + continue + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + 1/0 + finally: + break + self.assertEqual(count, 0) + + def test_return_in_finally(self): + def g1(): + try: + pass + finally: + return 1 + self.assertEqual(g1(), 1) + + def g2(): + try: + return 2 + finally: + return 3 + self.assertEqual(g2(), 3) + + def g3(): + try: + 1/0 + finally: + return 4 + self.assertEqual(g3(), 4) + def test_yield(self): # Allowed as standalone statement def g(): yield 1 From webhook-mailer at python.org Tue Jan 2 03:56:48 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 02 Jan 2018 08:56:48 -0000 Subject: [Python-checkins] [2.7] bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (GH-5078). (#5084) Message-ID: https://github.com/python/cpython/commit/b495377a8bdd711e9aab0885c60cd148284156e8 commit: b495377a8bdd711e9aab0885c60cd148284156e8 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-01-02T10:56:40+02:00 summary: [2.7] bpo-32478: Add tests for 'break' and 'return' inside 'finally' clause. (GH-5078). (#5084) (cherry picked from commit 7cc42c356b0dc5ad9eaa9392789e84bd4aa1c7de) files: M Lib/test/test_grammar.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index fc675c35a30..47b6b3e0d15 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -490,6 +490,80 @@ def g2(): return 1 x = g2() check_syntax_error(self, "class foo:return 1") + def test_break_in_finally(self): + count = 0 + while count < 2: + count += 1 + try: + pass + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + continue + finally: + break + self.assertEqual(count, 1) + + count = 0 + while count < 2: + count += 1 + try: + 1/0 + finally: + break + self.assertEqual(count, 1) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + pass + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + continue + finally: + break + self.assertEqual(count, 0) + + for count in [0, 1]: + self.assertEqual(count, 0) + try: + 1/0 + finally: + break + self.assertEqual(count, 0) + + def test_return_in_finally(self): + def g1(): + try: + pass + finally: + return 1 + self.assertEqual(g1(), 1) + + def g2(): + try: + return 2 + finally: + return 3 + self.assertEqual(g2(), 3) + + def g3(): + try: + 1/0 + finally: + return 4 + self.assertEqual(g3(), 4) + def testYield(self): check_syntax_error(self, "class foo:yield 1") From solipsis at pitrou.net Tue Jan 2 04:13:13 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 02 Jan 2018 09:13:13 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=9 Message-ID: <20180102091313.1.7D2263C6DA5098E8@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [0, -2, 2] memory blocks, sum=0 test_multiprocessing_spawn leaked [2, 0, 0] memory blocks, sum=2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogjkuXfD', '--timeout', '7200'] From webhook-mailer at python.org Tue Jan 2 08:36:13 2018 From: webhook-mailer at python.org (R. David Murray) Date: Tue, 02 Jan 2018 13:36:13 -0000 Subject: [Python-checkins] bpo-32452: clarify term 'brackets' in generator tutorial (GH-5079) (#5081) Message-ID: https://github.com/python/cpython/commit/f24c1857a8a1ba3efb3f957d43371bc9499e3c86 commit: f24c1857a8a1ba3efb3f957d43371bc9499e3c86 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: R. David Murray date: 2018-01-02T08:36:06-05:00 summary: bpo-32452: clarify term 'brackets' in generator tutorial (GH-5079) (#5081) Updates documentation for generator expressions in classes tutorial: Clarify usage of ambiguous term "brackets" by replacing with "square brackets". Updated subsequent lines to respect line breaks. (GH-5079) (cherry picked from commit f190eb59e60e2ae7a7cbd396458389a7a076e0d3) files: M Doc/tutorial/classes.rst diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 95141f94d6a..4676ef4b8a6 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -876,9 +876,9 @@ Generator Expressions ===================== Some simple generators can be coded succinctly as expressions using a syntax -similar to list comprehensions but with parentheses instead of brackets. These -expressions are designed for situations where the generator is used right away -by an enclosing function. Generator expressions are more compact but less +similar to list comprehensions but with parentheses instead of square brackets. +These expressions are designed for situations where the generator is used right +away by an enclosing function. Generator expressions are more compact but less versatile than full generator definitions and tend to be more memory friendly than equivalent list comprehensions. From webhook-mailer at python.org Tue Jan 2 10:42:18 2018 From: webhook-mailer at python.org (R. David Murray) Date: Tue, 02 Jan 2018 15:42:18 -0000 Subject: [Python-checkins] bpo-32452: clarify term 'brackets' in generator tutorial (GH-5079) (#5082) Message-ID: https://github.com/python/cpython/commit/0e0d1017a4c8ad6f77ee42d7b640463058037f62 commit: 0e0d1017a4c8ad6f77ee42d7b640463058037f62 branch: 2.7 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: R. David Murray date: 2018-01-02T10:42:12-05:00 summary: bpo-32452: clarify term 'brackets' in generator tutorial (GH-5079) (#5082) Updates documentation for generator expressions in classes tutorial: Clarify usage of ambiguous term "brackets" by replacing with "square brackets". Updated subsequent lines to respect line breaks. (GH-5079) (cherry picked from commit f190eb59e60e2ae7a7cbd396458389a7a076e0d3) files: M Doc/tutorial/classes.rst diff --git a/Doc/tutorial/classes.rst b/Doc/tutorial/classes.rst index 216dcae6b60..7f45c7632d5 100644 --- a/Doc/tutorial/classes.rst +++ b/Doc/tutorial/classes.rst @@ -873,9 +873,9 @@ Generator Expressions ===================== Some simple generators can be coded succinctly as expressions using a syntax -similar to list comprehensions but with parentheses instead of brackets. These -expressions are designed for situations where the generator is used right away -by an enclosing function. Generator expressions are more compact but less +similar to list comprehensions but with parentheses instead of square brackets. +These expressions are designed for situations where the generator is used right +away by an enclosing function. Generator expressions are more compact but less versatile than full generator definitions and tend to be more memory friendly than equivalent list comprehensions. From webhook-mailer at python.org Tue Jan 2 12:25:50 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 02 Jan 2018 17:25:50 -0000 Subject: [Python-checkins] bpo-31530: fix crash when multiple threads iterate over a file, round 2 (#5060) Message-ID: https://github.com/python/cpython/commit/dbf52e02f18dac6f5f0a64f78932f3dc6efc056b commit: dbf52e02f18dac6f5f0a64f78932f3dc6efc056b branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2018-01-02T09:25:41-08:00 summary: bpo-31530: fix crash when multiple threads iterate over a file, round 2 (#5060) Multiple threads iterating over a file can corrupt the file's internal readahead buffer resulting in crashes. To fix this, cache buffer state thread-locally for the duration of a file_iternext call and only update the file's internal state after reading completes. No attempt is made to define or provide "reasonable" semantics for iterating over a file on multiple threads. (Non-crashing) races are still present. Duplicated, corrupt, and missing data will happen. This was originally fixed by 6401e5671781eb217ee1afb4603cc0d1b0367ae6, which raised an exception from seek() and next() when concurrent operations were detected. Alas, this simpler solution breaks legitimate use cases such as capturing the standard streams when multiple threads are logging. files: M Lib/test/test_file2k.py M Misc/NEWS.d/next/Core and Builtins/2017-09-20-18-28-09.bpo-31530.CdLOM7.rst M Objects/fileobject.c diff --git a/Lib/test/test_file2k.py b/Lib/test/test_file2k.py index d8966e034e0..c73e8d8dc45 100644 --- a/Lib/test/test_file2k.py +++ b/Lib/test/test_file2k.py @@ -653,18 +653,15 @@ def io_func(): self._test_close_open_io(io_func) def test_iteration_torture(self): - # bpo-31530: Crash when concurrently iterate over a file. + # bpo-31530 with open(self.filename, "wb") as fp: for i in xrange(2**20): fp.write(b"0"*50 + b"\n") with open(self.filename, "rb") as f: - def iterate(): - try: - for l in f: - pass - except IOError: + def it(): + for l in f: pass - self._run_workers(iterate, 10) + self._run_workers(it, 10) def test_iteration_seek(self): # bpo-31530: Crash when concurrently seek and iterate over a file. @@ -674,17 +671,15 @@ def test_iteration_seek(self): with open(self.filename, "rb") as f: it = iter([1] + [0]*10) # one thread reads, others seek def iterate(): - try: - if next(it): - for l in f: - pass - else: - for i in range(100): - f.seek(i*100, 0) - except IOError: - pass + if next(it): + for l in f: + pass + else: + for i in xrange(100): + f.seek(i*100, 0) self._run_workers(iterate, 10) + @unittest.skipUnless(os.name == 'posix', 'test requires a posix system.') class TestFileSignalEINTR(unittest.TestCase): def _test_reading(self, data_to_write, read_and_verify_code, method_name, diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-09-20-18-28-09.bpo-31530.CdLOM7.rst b/Misc/NEWS.d/next/Core and Builtins/2017-09-20-18-28-09.bpo-31530.CdLOM7.rst index a6cb6c9e9ba..beb09b5ae65 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2017-09-20-18-28-09.bpo-31530.CdLOM7.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2017-09-20-18-28-09.bpo-31530.CdLOM7.rst @@ -1,4 +1 @@ Fixed crashes when iterating over a file on multiple threads. -seek() and next() methods of file objects now raise an exception during -concurrent operation on the same file object. -A lock can be used to prevent the error. diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 8d1c5812f0d..270b28264a8 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -609,7 +609,12 @@ err_iterbuffered(void) return NULL; } -static void drop_readahead(PyFileObject *); +static void +drop_file_readahead(PyFileObject *f) +{ + PyMem_FREE(f->f_buf); + f->f_buf = NULL; +} /* Methods */ @@ -632,7 +637,7 @@ file_dealloc(PyFileObject *f) Py_XDECREF(f->f_mode); Py_XDECREF(f->f_encoding); Py_XDECREF(f->f_errors); - drop_readahead(f); + drop_file_readahead(f); Py_TYPE(f)->tp_free((PyObject *)f); } @@ -767,13 +772,7 @@ file_seek(PyFileObject *f, PyObject *args) if (f->f_fp == NULL) return err_closed(); - if (f->unlocked_count > 0) { - PyErr_SetString(PyExc_IOError, - "seek() called during concurrent " - "operation on the same file object"); - return NULL; - } - drop_readahead(f); + drop_file_readahead(f); whence = 0; if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &whence)) return NULL; @@ -2242,12 +2241,16 @@ static PyGetSetDef file_getsetlist[] = { {0}, }; +typedef struct { + char *buf, *bufptr, *bufend; +} readaheadbuffer; + static void -drop_readahead(PyFileObject *f) +drop_readaheadbuffer(readaheadbuffer *rab) { - if (f->f_buf != NULL) { - PyMem_Free(f->f_buf); - f->f_buf = NULL; + if (rab->buf != NULL) { + PyMem_FREE(rab->buf); + rab->buf = NULL; } } @@ -2255,36 +2258,34 @@ drop_readahead(PyFileObject *f) (unless at EOF) and no more than bufsize. Returns negative value on error, will set MemoryError if bufsize bytes cannot be allocated. */ static int -readahead(PyFileObject *f, Py_ssize_t bufsize) +readahead(PyFileObject *f, readaheadbuffer *rab, Py_ssize_t bufsize) { Py_ssize_t chunksize; - assert(f->unlocked_count == 0); - if (f->f_buf != NULL) { - if( (f->f_bufend - f->f_bufptr) >= 1) + if (rab->buf != NULL) { + if ((rab->bufend - rab->bufptr) >= 1) return 0; else - drop_readahead(f); + drop_readaheadbuffer(rab); } - if ((f->f_buf = (char *)PyMem_Malloc(bufsize)) == NULL) { + if ((rab->buf = PyMem_MALLOC(bufsize)) == NULL) { PyErr_NoMemory(); return -1; } FILE_BEGIN_ALLOW_THREADS(f) errno = 0; - chunksize = Py_UniversalNewlineFread( - f->f_buf, bufsize, f->f_fp, (PyObject *)f); + chunksize = Py_UniversalNewlineFread(rab->buf, bufsize, f->f_fp, (PyObject *)f); FILE_END_ALLOW_THREADS(f) if (chunksize == 0) { if (ferror(f->f_fp)) { PyErr_SetFromErrno(PyExc_IOError); clearerr(f->f_fp); - drop_readahead(f); + drop_readaheadbuffer(rab); return -1; } } - f->f_bufptr = f->f_buf; - f->f_bufend = f->f_buf + chunksize; + rab->bufptr = rab->buf; + rab->bufend = rab->buf + chunksize; return 0; } @@ -2294,51 +2295,43 @@ readahead(PyFileObject *f, Py_ssize_t bufsize) logarithmic buffer growth to about 50 even when reading a 1gb line. */ static PyStringObject * -readahead_get_line_skip(PyFileObject *f, Py_ssize_t skip, Py_ssize_t bufsize) +readahead_get_line_skip(PyFileObject *f, readaheadbuffer *rab, Py_ssize_t skip, Py_ssize_t bufsize) { PyStringObject* s; char *bufptr; char *buf; Py_ssize_t len; - if (f->unlocked_count > 0) { - PyErr_SetString(PyExc_IOError, - "next() called during concurrent " - "operation on the same file object"); - return NULL; - } - if (f->f_buf == NULL) - if (readahead(f, bufsize) < 0) + if (rab->buf == NULL) + if (readahead(f, rab, bufsize) < 0) return NULL; - len = f->f_bufend - f->f_bufptr; + len = rab->bufend - rab->bufptr; if (len == 0) - return (PyStringObject *) - PyString_FromStringAndSize(NULL, skip); - bufptr = (char *)memchr(f->f_bufptr, '\n', len); + return (PyStringObject *)PyString_FromStringAndSize(NULL, skip); + bufptr = (char *)memchr(rab->bufptr, '\n', len); if (bufptr != NULL) { bufptr++; /* Count the '\n' */ - len = bufptr - f->f_bufptr; - s = (PyStringObject *) - PyString_FromStringAndSize(NULL, skip + len); + len = bufptr - rab->bufptr; + s = (PyStringObject *)PyString_FromStringAndSize(NULL, skip + len); if (s == NULL) return NULL; - memcpy(PyString_AS_STRING(s) + skip, f->f_bufptr, len); - f->f_bufptr = bufptr; - if (bufptr == f->f_bufend) - drop_readahead(f); + memcpy(PyString_AS_STRING(s) + skip, rab->bufptr, len); + rab->bufptr = bufptr; + if (bufptr == rab->bufend) + drop_readaheadbuffer(rab); } else { - bufptr = f->f_bufptr; - buf = f->f_buf; - f->f_buf = NULL; /* Force new readahead buffer */ + bufptr = rab->bufptr; + buf = rab->buf; + rab->buf = NULL; /* Force new readahead buffer */ assert(len <= PY_SSIZE_T_MAX - skip); - s = readahead_get_line_skip(f, skip + len, bufsize + (bufsize>>2)); + s = readahead_get_line_skip(f, rab, skip + len, bufsize + (bufsize>>2)); if (s == NULL) { - PyMem_Free(buf); + PyMem_FREE(buf); return NULL; } memcpy(PyString_AS_STRING(s) + skip, bufptr, len); - PyMem_Free(buf); + PyMem_FREE(buf); } return s; } @@ -2356,7 +2349,30 @@ file_iternext(PyFileObject *f) if (!f->readable) return err_mode("reading"); - l = readahead_get_line_skip(f, 0, READAHEAD_BUFSIZE); + { + /* + Multiple threads can enter this method while the GIL is released + during file read and wreak havoc on the file object's readahead + buffer. To avoid dealing with cross-thread coordination issues, we + cache the file buffer state locally and only set it back on the file + object when we're done. + */ + readaheadbuffer rab = {f->f_buf, f->f_bufptr, f->f_bufend}; + f->f_buf = NULL; + l = readahead_get_line_skip(f, &rab, 0, READAHEAD_BUFSIZE); + /* + Make sure the file's internal read buffer is cleared out. This will + only do anything if some other thread interleaved with us during + readahead. We want to drop any changeling buffer, so we don't leak + memory. We may lose data, but that's what you get for reading the same + file object in multiple threads. + */ + drop_file_readahead(f); + f->f_buf = rab.buf; + f->f_bufptr = rab.bufptr; + f->f_bufend = rab.bufend; + } + if (l == NULL || PyString_GET_SIZE(l) == 0) { Py_XDECREF(l); return NULL; From webhook-mailer at python.org Tue Jan 2 18:52:49 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Tue, 02 Jan 2018 23:52:49 -0000 Subject: [Python-checkins] coalesce GILless sections in new_buffersize (#5059) Message-ID: https://github.com/python/cpython/commit/eb08a9290f28e602ba035acfe8c2d3cd2b9965b0 commit: eb08a9290f28e602ba035acfe8c2d3cd2b9965b0 branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2018-01-02T15:52:42-08:00 summary: coalesce GILless sections in new_buffersize (#5059) 830daae1c82ed33deef0086b7b6323e5be0b0cc8 added some new GIL-releasing to new_buffersize. This is fine, but it's better to avoid reacquiring the GIL for as long as possible. Also, it should use FILE_(BEGIN|END)_ALLOW_THREADS to avoid having the file closed from under it. files: M Objects/fileobject.c diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 270b28264a8..b524f09e0a3 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -1015,10 +1015,10 @@ new_buffersize(PyFileObject *f, size_t currentsize) off_t pos, end; struct stat st; int res; + size_t bufsize = 0; - Py_BEGIN_ALLOW_THREADS + FILE_BEGIN_ALLOW_THREADS(f) res = fstat(fileno(f->f_fp), &st); - Py_END_ALLOW_THREADS if (res == 0) { end = st.st_size; @@ -1032,9 +1032,7 @@ new_buffersize(PyFileObject *f, size_t currentsize) need to take the amount of buffered data into account. (Yet another reason why stdio stinks. :-) */ - Py_BEGIN_ALLOW_THREADS pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); - Py_END_ALLOW_THREADS if (pos >= 0) { pos = ftell(f->f_fp); @@ -1042,9 +1040,12 @@ new_buffersize(PyFileObject *f, size_t currentsize) if (pos < 0) clearerr(f->f_fp); if (end > pos && pos >= 0) - return currentsize + end - pos + 1; + bufsize = currentsize + end - pos + 1; /* Add 1 so if the file were to grow we'd notice. */ } + FILE_END_ALLOW_THREADS(f) + if (bufsize != 0) + return bufsize; #endif /* Expand the buffer by an amount proportional to the current size, giving us amortized linear-time behavior. Use a less-than-double From lp_benchmark_robot at intel.com Tue Jan 2 19:19:34 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Tue, 2 Jan 2018 16:19:34 -0800 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-01-02 Message-ID: <20f10ab4-0fd4-4b9c-b4b8-e7eb8d9a6a96@orsmsx104.amr.corp.intel.com> Results for project python/master, build date: 2018-01-02 12:54:41-08:00. - commit: f190eb5 - previous commit: e325608 - revision date: 2018-01-01 20:34:53-05:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.628% | +0.750% | +7.909% | +6.905% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.249% | -1.681% | +22.446% | +10.724% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.021% | -0.797% | +24.941% | +8.176% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.275% | -0.965% | +22.191% | +11.543% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.673% | -0.546% | +8.132% | +12.181% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.870% | -0.329% | +9.353% | +11.350% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.685% | -0.122% | +5.590% | +12.351% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.905% | +0.650% | -0.977% | +8.520% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 1.463% | +0.961% | +11.570% | +16.173% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 2.590% | +0.852% | +12.859% | +13.514% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.231% | -0.141% | +3.629% | +7.408% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.904% | +0.006% | +5.276% | +5.428% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.764% | -0.361% | +1.598% | +8.848% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.154% | -0.846% | +12.084% | +9.207% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.662% | -0.262% | +8.569% | +8.333% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 0.996% | -0.205% | +6.115% | +12.340% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.536% | +0.318% | +10.529% | +10.506% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 3.629% | +0.919% | +7.630% | +10.362% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.121% | -0.568% | +3.155% | +8.066% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 4.018% | -0.971% | -0.795% | +13.669% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.690% | +0.936% | +7.066% | +13.093% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.152% | +1.681% | +47.676% | +11.273% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.685% | +1.534% | +7.929% | +14.336% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.757% | +0.581% | +17.153% | +12.344% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 2.726% | +0.488% | +11.204% | +7.556% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 2.708% | -0.827% | +4.328% | +4.984% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 1.009% | -1.435% | -2.100% | +1.161% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 1.869% | +0.178% | +4.526% | +5.738% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.315% | -1.902% | +0.940% | +11.691% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.253% | +0.803% | +1.149% | +19.569% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 1.104% | +2.406% | +1.800% | +17.925% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.689% | +1.205% | +3.772% | +18.242% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 2.900% | +1.436% | +11.530% | +10.437% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.472% | -0.204% | -0.171% | +9.644% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.142% | +0.224% | +10.670% | +4.839% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.107% | -0.013% | +1.960% | +5.148% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.810% | +0.696% | +10.455% | +14.272% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.326% | -1.118% | +4.950% | +9.056% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.629% | -0.270% | -2.544% | +11.464% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.847% | +1.020% | -5.220% | +5.141% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 1.235% | -0.642% | +3.830% | +6.260% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.137% | +1.298% | +9.088% | +14.883% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.632% | +0.958% | -1.503% | +2.844% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 1.294% | +0.471% | +27.328% | +7.329% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.257% | +0.323% | +4.810% | +5.277% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 0.573% | +0.276% | +14.522% | +8.771% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 0.740% | +0.866% | -2.746% | -1.194% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.439% | +0.436% | +5.850% | +2.336% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.552% | +0.437% | +6.948% | +6.692% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.486% | +0.688% | +6.508% | +5.829% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 5.659% | -1.415% | +19.000% | +6.349% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 1.984% | +0.285% | +12.287% | +5.841% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 2.127% | -0.010% | +9.068% | +6.141% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 4.490% | -0.131% | +11.699% | +7.881% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 5.808% | +0.275% | +10.954% | +7.149% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 4.827% | +1.036% | +20.006% | +11.780% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.958% | -0.017% | +6.104% | +6.524% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.388% | +0.319% | +2.019% | -0.897% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 6.934% | -1.154% | +8.350% | +21.270% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 2.498% | +2.675% | -3.986% | +14.267% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 1.352% | +0.804% | +8.694% | +5.699% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.091% | +0.116% | +1.971% | +10.304% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.406% | +1.191% | +3.710% | +6.418% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 3.522% | +1.823% | -8.935% | +13.501% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.350% | -0.096% | +4.185% | +9.883% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-01-02 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 solipsis at pitrou.net Wed Jan 3 04:16:04 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Wed, 03 Jan 2018 09:16:04 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=2 Message-ID: <20180103091604.1.6EF98A5719944971@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [-1, 1, -2] memory blocks, sum=-2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/refloguFaMBU', '--timeout', '7200'] From webhook-mailer at python.org Wed Jan 3 14:32:31 2018 From: webhook-mailer at python.org (Brett Cannon) Date: Wed, 03 Jan 2018 19:32:31 -0000 Subject: [Python-checkins] Ignore importlib.h for automatic review requests from the import team. (GH-5087) Message-ID: https://github.com/python/cpython/commit/811b2878dfc68dc3ecd81fb4b370c6e1f9ec69c2 commit: 811b2878dfc68dc3ecd81fb4b370c6e1f9ec69c2 branch: master author: Brett Cannon committer: GitHub date: 2018-01-03T11:32:22-08:00 summary: Ignore importlib.h for automatic review requests from the import team. (GH-5087) Otherwise the import team gets flagged for reviews any time the bytecode for importlib.h changes (e.g new bytecode, optimizations, etc.). files: M .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d751a918d0d..b42e1c93d8f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,8 +14,13 @@ **/*hashlib* @python/crypto-team **/*pyhash* @python/crypto-team -# Import (including importlib) -**/*import* @python/import-team +# Import (including importlib). +# Ignoring importlib.h so as to not get flagged on +# all pull requests that change the the emitted +# bytecode. +**/*import*.c @python/import-team +**/*import*.py @python/import-team + # SSL **/*ssl* @python/crypto-team From lp_benchmark_robot at intel.com Wed Jan 3 18:38:31 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Wed, 3 Jan 2018 15:38:31 -0800 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-01-02 Message-ID: No new revisions. Here are the previous results: Results for project python/master, build date: 2018-01-02 20:54:41+00:00. - commit: f190eb5 - previous commit: e325608 - revision date: 2018-01-01 20:34:53-05:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.628% | +0.750% | +7.909% | +6.905% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.249% | -1.681% | +22.446% | +10.724% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.021% | -0.797% | +24.941% | +8.176% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.275% | -0.965% | +22.191% | +11.543% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.673% | -0.546% | +8.132% | +12.181% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.870% | -0.329% | +9.353% | +11.350% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 0.685% | -0.122% | +5.590% | +12.351% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.905% | +0.650% | -0.977% | +8.520% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 1.463% | +0.961% | +11.570% | +16.173% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 2.590% | +0.852% | +12.859% | +13.514% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.231% | -0.141% | +3.629% | +7.408% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.904% | +0.006% | +5.276% | +5.428% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 1.764% | -0.361% | +1.598% | +8.848% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.154% | -0.846% | +12.084% | +9.207% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.662% | -0.262% | +8.569% | +8.333% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 0.996% | -0.205% | +6.115% | +12.340% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.536% | +0.318% | +10.529% | +10.506% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 3.629% | +0.919% | +7.630% | +10.362% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.121% | -0.568% | +3.155% | +8.066% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 4.018% | -0.971% | -0.795% | +13.669% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.690% | +0.936% | +7.066% | +13.093% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.152% | +1.681% | +47.676% | +11.273% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.685% | +1.534% | +7.929% | +14.336% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.757% | +0.581% | +17.153% | +12.344% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 2.726% | +0.488% | +11.204% | +7.556% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 2.708% | -0.827% | +4.328% | +4.984% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 1.009% | -1.435% | -2.100% | +1.161% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 1.869% | +0.178% | +4.526% | +5.738% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.315% | -1.902% | +0.940% | +11.691% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.253% | +0.803% | +1.149% | +19.569% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 1.104% | +2.406% | +1.800% | +17.925% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.689% | +1.205% | +3.772% | +18.242% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 2.900% | +1.436% | +11.530% | +10.437% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.472% | -0.204% | -0.171% | +9.644% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.142% | +0.224% | +10.670% | +4.839% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.107% | -0.013% | +1.960% | +5.148% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.810% | +0.696% | +10.455% | +14.272% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.326% | -1.118% | +4.950% | +9.056% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.629% | -0.270% | -2.544% | +11.464% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.847% | +1.020% | -5.220% | +5.141% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 1.235% | -0.642% | +3.830% | +6.260% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.137% | +1.298% | +9.088% | +14.883% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.632% | +0.958% | -1.503% | +2.844% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 1.294% | +0.471% | +27.328% | +7.329% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.257% | +0.323% | +4.810% | +5.277% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 0.573% | +0.276% | +14.522% | +8.771% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 0.740% | +0.866% | -2.746% | -1.194% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.439% | +0.436% | +5.850% | +2.336% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.552% | +0.437% | +6.948% | +6.692% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.486% | +0.688% | +6.508% | +5.829% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 5.659% | -1.415% | +19.000% | +6.349% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 1.984% | +0.285% | +12.287% | +5.841% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 2.127% | -0.010% | +9.068% | +6.141% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 4.490% | -0.131% | +11.699% | +7.881% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 5.808% | +0.275% | +10.954% | +7.149% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 4.827% | +1.036% | +20.006% | +11.780% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.958% | -0.017% | +6.104% | +6.524% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.388% | +0.319% | +2.019% | -0.897% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 6.934% | -1.154% | +8.350% | +21.270% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 2.498% | +2.675% | -3.986% | +14.267% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 1.352% | +0.804% | +8.694% | +5.699% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.091% | +0.116% | +1.971% | +10.304% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.406% | +1.191% | +3.710% | +6.418% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 3.522% | +1.823% | -8.935% | +13.501% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.350% | -0.096% | +4.185% | +9.883% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-01-02 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 webhook-mailer at python.org Thu Jan 4 03:36:18 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 08:36:18 -0000 Subject: [Python-checkins] bpo-32482: Improve syntax and grammar tests. (#5085) Message-ID: https://github.com/python/cpython/commit/0bcba372bcd564555c98a65be4fb1309ff1ae5d5 commit: 0bcba372bcd564555c98a65be4fb1309ff1ae5d5 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-01-04T10:36:14+02:00 summary: bpo-32482: Improve syntax and grammar tests. (#5085) files: M Lib/test/test_grammar.py M Lib/test/test_syntax.py M Lib/test/test_sys_settrace.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 47b6b3e0d15..23b6ce8d3c5 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -11,7 +11,7 @@ class TokenTests(unittest.TestCase): - def testBackslash(self): + def test_backslash(self): # Backslash means line continuation: x = 1 \ + 1 @@ -21,29 +21,42 @@ def testBackslash(self): x = 0 self.assertEqual(x, 0, 'backslash ending comment') - def testPlainIntegers(self): + def test_plain_integers(self): + self.assertEqual(type(000), type(0)) self.assertEqual(0xff, 255) self.assertEqual(0377, 255) + self.assertEqual(0o377, 255) self.assertEqual(2147483647, 017777777777) + self.assertEqual(2147483647, 0o17777777777) + self.assertEqual(0b1001, 9) # "0x" is not a valid literal self.assertRaises(SyntaxError, eval, "0x") from sys import maxint if maxint == 2147483647: - self.assertEqual(-2147483647-1, -020000000000) + self.assertEqual(-2147483647-1, -0o20000000000) # XXX -2147483648 self.assertTrue(037777777777 > 0) + self.assertTrue(0o37777777777 > 0) self.assertTrue(0xffffffff > 0) - for s in '2147483648', '040000000000', '0x100000000': + self.assertTrue(0b1111111111111111111111111111111 > 0) + for s in ('2147483648', '040000000000', '0o40000000000', + '0x100000000', + '0b10000000000000000000000000000000'): try: x = eval(s) except OverflowError: self.fail("OverflowError on huge integer literal %r" % s) elif maxint == 9223372036854775807: self.assertEqual(-9223372036854775807-1, -01000000000000000000000) + self.assertEqual(-9223372036854775807-1, -0o1000000000000000000000) self.assertTrue(01777777777777777777777 > 0) + self.assertTrue(0o1777777777777777777777 > 0) self.assertTrue(0xffffffffffffffff > 0) + self.assertTrue(0b11111111111111111111111111111111111111111111111111111111111111 > 0) for s in '9223372036854775808', '02000000000000000000000', \ - '0x10000000000000000': + '0o2000000000000000000000', \ + '0x10000000000000000', \ + '0b100000000000000000000000000000000000000000000000000000000000000': try: x = eval(s) except OverflowError: @@ -51,7 +64,7 @@ def testPlainIntegers(self): else: self.fail('Weird maxint value %r' % maxint) - def testLongIntegers(self): + def test_long_integers(self): x = 0L x = 0l x = 0xffffffffffffffffL @@ -61,7 +74,7 @@ def testLongIntegers(self): x = 123456789012345678901234567890L x = 123456789012345678901234567890l - def testFloats(self): + def test_floats(self): x = 3.14 x = 314. x = 0.314 @@ -81,7 +94,7 @@ def test_float_exponent_tokenization(self): self.assertEqual(1 if 0else 0, 0) self.assertRaises(SyntaxError, eval, "0 if 1Else 0") - def testStringLiterals(self): + def test_string_literals(self): x = ''; y = ""; self.assertTrue(len(x) == 0 and x == y) x = '\''; y = "'"; self.assertTrue(len(x) == 1 and x == y and ord(x) == 39) x = '"'; y = "\""; self.assertTrue(len(x) == 1 and x == y and ord(x) == 34) @@ -133,11 +146,11 @@ class GrammarTests(unittest.TestCase): # expr_input: testlist NEWLINE # XXX Hard to test -- used only in calls to input() - def testEvalInput(self): + def test_eval_input(self): # testlist ENDMARKER x = eval('1, 0 or 1') - def testFuncdef(self): + def test_funcdef(self): ### 'def' NAME parameters ':' suite ### parameters: '(' [varargslist] ')' ### varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' ('**'|'*' '*') NAME] @@ -153,9 +166,10 @@ def f1(): pass f1(*(), **{}) def f2(one_argument): pass def f3(two, arguments): pass - # Silence Py3k warning - exec('def f4(two, (compound, (argument, list))): pass') - exec('def f5((compound, first), two): pass') + with check_py3k_warnings(('tuple parameter unpacking has been removed', + SyntaxWarning)): + exec('def f4(two, (compound, (argument, list))): pass') + exec('def f5((compound, first), two): pass') self.assertEqual(f2.func_code.co_varnames, ('one_argument',)) self.assertEqual(f3.func_code.co_varnames, ('two', 'arguments')) if sys.platform.startswith('java'): @@ -174,8 +188,9 @@ def a2(two, args,): pass def v0(*rest): pass def v1(a, *rest): pass def v2(a, b, *rest): pass - # Silence Py3k warning - exec('def v3(a, (b, c), *rest): return a, b, c, rest') + with check_py3k_warnings(('tuple parameter unpacking has been removed', + SyntaxWarning)): + exec('def v3(a, (b, c), *rest): return a, b, c, rest') f1() f2(1) @@ -212,7 +227,9 @@ def d01(a=1): pass d01() d01(1) d01(*(1,)) + d01(*[] or [2]) d01(**{'a':2}) + d01(**{'a':2} or {}) def d11(a, b=1): pass d11(1) d11(1, 2) @@ -280,9 +297,12 @@ def d22v(a, b, c=1, d=2, *rest): pass d22v(*(1, 2, 3, 4)) d22v(1, 2, *(3, 4, 5)) d22v(1, *(2, 3), **{'d': 4}) - # Silence Py3k warning - exec('def d31v((x)): pass') - exec('def d32v((x,)): pass') + with check_py3k_warnings(('parenthesized argument names are invalid', + SyntaxWarning)): + exec('def d31v((x)): pass') + with check_py3k_warnings(('tuple parameter unpacking has been removed', + SyntaxWarning)): + exec('def d32v((x,)): pass') d31v(1) d32v((1,)) @@ -293,12 +313,19 @@ def f(*args, **kwargs): {'x':2, 'y':5})) self.assertRaises(SyntaxError, eval, "f(1, *(2,3), 4)") self.assertRaises(SyntaxError, eval, "f(1, x=2, *(3,4), x=5)") + self.assertEqual(f(**{'eggs':'scrambled', 'spam':'fried'}), + ((), {'eggs':'scrambled', 'spam':'fried'})) + self.assertEqual(f(spam='fried', **{'eggs':'scrambled'}), + ((), {'eggs':'scrambled', 'spam':'fried'})) # Check ast errors in *args and *kwargs check_syntax_error(self, "f(*g(1=2))") check_syntax_error(self, "f(**g(1=2))") - def testLambdef(self): + # Check trailing commas are permitted in funcdef argument list + def f(a,): pass + + def test_lambdef(self): ### lambdef: 'lambda' [varargslist] ':' test l1 = lambda : 0 self.assertEqual(l1(), 0) @@ -311,12 +338,18 @@ def testLambdef(self): self.assertEqual(l5(1, 2), 5) self.assertEqual(l5(1, 2, 3), 6) check_syntax_error(self, "lambda x: x = 2") - check_syntax_error(self, "lambda (None,): None") + with check_py3k_warnings(('tuple parameter unpacking has been removed', + SyntaxWarning)): + check_syntax_error(self, "lambda (None,): None") + + # check that trailing commas are permitted + l10 = lambda a,: 0 + ### stmt: simple_stmt | compound_stmt # Tested below - def testSimpleStmt(self): + def test_simple_stmt(self): ### simple_stmt: small_stmt (';' small_stmt)* [';'] x = 1; pass; del x def foo(): @@ -327,7 +360,7 @@ def foo(): ### small_stmt: expr_stmt | print_stmt | pass_stmt | del_stmt | flow_stmt | import_stmt | global_stmt | access_stmt | exec_stmt # Tested below - def testExprStmt(self): + def test_expr_stmt(self): # (exprlist '=')* exprlist 1 1, 2, 3 @@ -340,7 +373,7 @@ def testExprStmt(self): check_syntax_error(self, "x + 1 = 1") check_syntax_error(self, "a + 1 = b + 2") - def testPrintStmt(self): + def test_print_stmt(self): # 'print' (test ',')* [test] import StringIO @@ -410,7 +443,7 @@ def tellme(file=None): check_syntax_error(self, 'print ,') check_syntax_error(self, 'print >> x,') - def testDelStmt(self): + def test_del_stmt(self): # 'del' exprlist abc = [1,2,3] x, y, z = abc @@ -419,18 +452,18 @@ def testDelStmt(self): del abc del x, y, (z, xyz) - def testPassStmt(self): + def test_pass_stmt(self): # 'pass' pass # flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt # Tested below - def testBreakStmt(self): + def test_break_stmt(self): # 'break' while 1: break - def testContinueStmt(self): + def test_continue_stmt(self): # 'continue' i = 1 while i: i = 0; continue @@ -482,7 +515,7 @@ def test_inner(extra_burning_oil = 1, count=0): self.fail("continue then break in try/except in loop broken!") test_inner() - def testReturn(self): + def test_return(self): # 'return' [testlist] def g1(): return def g2(): return 1 @@ -513,7 +546,7 @@ def test_break_in_finally(self): while count < 2: count += 1 try: - 1/0 + 1.0/0.0 finally: break self.assertEqual(count, 1) @@ -537,7 +570,7 @@ def test_break_in_finally(self): for count in [0, 1]: self.assertEqual(count, 0) try: - 1/0 + 1.0/0.0 finally: break self.assertEqual(count, 0) @@ -559,13 +592,33 @@ def g2(): def g3(): try: - 1/0 + 1.0/0.0 finally: return 4 self.assertEqual(g3(), 4) - def testYield(self): + def test_yield(self): + # Allowed as standalone statement + def g(): yield 1 + # Allowed as RHS of assignment + def g(): x = yield 1 + # Ordinary yield accepts implicit tuples + def g(): yield 1, 1 + def g(): x = yield 1, 1 + # Requires parentheses as subexpression + def g(): 1, (yield 1) + check_syntax_error(self, "def g(): 1, yield 1") + # Requires parentheses as call argument + def g(): f((yield 1)) + def g(): f((yield 1), 1) + check_syntax_error(self, "def g(): f(yield 1)") + check_syntax_error(self, "def g(): f(yield 1, 1)") + # Not allowed at top level + check_syntax_error(self, "yield") + # Not allowed at class scope check_syntax_error(self, "class foo:yield 1") + # Check annotation refleak on SyntaxError + check_syntax_error(self, "def g(a:(yield)): pass") def test_yield_in_comprehensions(self): # Check yield in comprehensions @@ -607,14 +660,14 @@ def check(code, warntext): check("((yield x) for x in ())", "'yield' inside generator expression") - def testRaise(self): + def test_raise(self): # 'raise' test [',' test] try: raise RuntimeError, 'just testing' except RuntimeError: pass try: raise KeyboardInterrupt except KeyboardInterrupt: pass - def testImport(self): + def test_import(self): # 'import' dotted_as_names import sys import time, sys @@ -627,13 +680,13 @@ def testImport(self): from sys import (path, argv) from sys import (path, argv,) - def testGlobal(self): + def test_global(self): # 'global' NAME (',' NAME)* global a global a, b global one, two, three, four, five, six, seven, eight, nine, ten - def testExec(self): + def test_exec(self): # 'exec' expr ['in' expr [',' expr]] z = None del z @@ -665,7 +718,7 @@ def testExec(self): if (g, l) != ({'a':1}, {'b':2}): self.fail('exec ... in g (%s), l (%s)' %(g,l)) - def testAssert(self): + def test_assert(self): # assertTruestmt: 'assert' test [',' test] assert 1 assert 1, 1 @@ -704,7 +757,7 @@ def testAssert2(self): ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef # Tested below - def testIf(self): + def test_if(self): # 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] if 1: pass if 1: pass @@ -717,7 +770,7 @@ def testIf(self): elif 0: pass else: pass - def testWhile(self): + def test_while(self): # 'while' test ':' suite ['else' ':' suite] while 0: pass while 0: pass @@ -732,7 +785,7 @@ def testWhile(self): x = 2 self.assertEqual(x, 2) - def testFor(self): + def test_for(self): # 'for' exprlist 'in' exprlist ':' suite ['else' ':' suite] for i in 1, 2, 3: pass for i, j, k in (): pass @@ -759,30 +812,30 @@ def __getitem__(self, i): result.append(x) self.assertEqual(result, [1, 2, 3]) - def testTry(self): + def test_try(self): ### try_stmt: 'try' ':' suite (except_clause ':' suite)+ ['else' ':' suite] ### | 'try' ':' suite 'finally' ':' suite ### except_clause: 'except' [expr [('as' | ',') expr]] try: - 1/0 + 1/0.0 except ZeroDivisionError: pass else: pass - try: 1/0 + try: 1/0.0 except EOFError: pass except TypeError as msg: pass except RuntimeError, msg: pass except: pass else: pass - try: 1/0 + try: 1/0.0 except (EOFError, TypeError, ZeroDivisionError): pass - try: 1/0 + try: 1/0.0 except (EOFError, TypeError, ZeroDivisionError), msg: pass try: pass finally: pass - def testSuite(self): + def test_suite(self): # simple_stmt | NEWLINE INDENT NEWLINE* (stmt NEWLINE*)+ DEDENT if 1: pass if 1: @@ -797,7 +850,7 @@ def testSuite(self): pass # - def testTest(self): + def test_test(self): ### and_test ('or' and_test)* ### and_test: not_test ('and' not_test)* ### not_test: 'not' not_test | comparison @@ -808,7 +861,7 @@ def testTest(self): if not 1 and 1 and 1: pass if 1 and 1 or 1 and 1 and 1 or not 1 and 1: pass - def testComparison(self): + def test_comparison(self): ### comparison: expr (comp_op expr)* ### comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' if 1: pass @@ -824,40 +877,49 @@ def testComparison(self): if 1 in (): pass if 1 not in (): pass if 1 < 1 > 1 == 1 >= 1 <= 1 != 1 in 1 not in 1 is 1 is not 1: pass - # Silence Py3k warning - if eval('1 <> 1'): pass - if eval('1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1'): pass + with check_py3k_warnings(('<> not supported in 3.x; use !=', + DeprecationWarning)): + if eval('1 <> 1'): pass + with check_py3k_warnings(('<> not supported in 3.x; use !=', + DeprecationWarning)): + if eval('1 < 1 > 1 == 1 >= 1 <= 1 <> 1 != 1 in 1 not in 1 is 1 is not 1'): pass - def testBinaryMaskOps(self): + def test_binary_mask_ops(self): x = 1 & 1 x = 1 ^ 1 x = 1 | 1 - def testShiftOps(self): + def test_shift_ops(self): x = 1 << 1 x = 1 >> 1 x = 1 << 1 >> 1 - def testAdditiveOps(self): + def test_additive_ops(self): x = 1 x = 1 + 1 x = 1 - 1 - 1 x = 1 - 1 + 1 - 1 + 1 - def testMultiplicativeOps(self): + def test_multiplicative_ops(self): x = 1 * 1 - x = 1 / 1 + with check_py3k_warnings(('classic int division', DeprecationWarning)): + x = 1 / 1 + x = 1 / 1.0 x = 1 % 1 - x = 1 / 1 * 1 % 1 + with check_py3k_warnings(('classic int division', DeprecationWarning)): + x = 1 / 1 * 1 % 1 + x = 1 / 1.0 * 1 % 1 - def testUnaryOps(self): + def test_unary_ops(self): x = +1 x = -1 x = ~1 x = ~1 ^ 1 & 1 | 1 & 1 ^ -1 - x = -1*1/1 + 1*1 - ---1*1 + with check_py3k_warnings(('classic int division', DeprecationWarning)): + x = -1*1/1 + 1*1 - ---1*1 + x = -1*1/1.0 + 1*1 - ---1*1 - def testSelectors(self): + def test_selectors(self): ### trailer: '(' [testlist] ')' | '[' subscript ']' | '.' NAME ### subscript: expr | [expr] ':' [expr] @@ -884,10 +946,10 @@ def testSelectors(self): d[1,2] = 3 d[1,2,3] = 4 L = list(d) - L.sort() + L.sort(key=lambda x: (type(x).__name__, x)) self.assertEqual(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') - def testAtoms(self): + def test_atoms(self): ### atom: '(' [testlist] ')' | '[' [testlist] ']' | '{' [dictmaker] '}' | '`' testlist '`' | NAME | NUMBER | STRING ### dictorsetmaker: (test ':' test (',' test ':' test)* [',']) | (test (',' test)* [',']) @@ -914,10 +976,10 @@ def testAtoms(self): x = {'one', 'two', 'three'} x = {2, 3, 4,} - # Silence Py3k warning - x = eval('`x`') - x = eval('`1 or 2 or 3`') - self.assertEqual(eval('`1,2`'), '(1, 2)') + with check_py3k_warnings(('backquote not supported', SyntaxWarning)): + x = eval('`x`') + x = eval('`1 or 2 or 3`') + self.assertEqual(eval('`1,2`'), '(1, 2)') x = x x = 'x' @@ -927,7 +989,7 @@ def testAtoms(self): ### testlist: test (',' test)* [','] # These have been exercised enough above - def testClassdef(self): + def test_classdef(self): # 'class' NAME ['(' [testlist] ')'] ':' suite class B: pass class B2(): pass @@ -938,6 +1000,7 @@ class C: def meth1(self): pass def meth2(self, arg): pass def meth3(self, a1, a2): pass + # decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE # decorators: decorator+ # decorated: decorators (classdef | funcdef) @@ -949,14 +1012,14 @@ class G: pass self.assertEqual(G.decorated, True) - def testDictcomps(self): + def test_dictcomps(self): # dictorsetmaker: ( (test ':' test (comp_for | # (',' test ':' test)* [','])) | # (test (comp_for | (',' test)* [','])) ) nums = [1, 2, 3] self.assertEqual({i:i+1 for i in nums}, {1: 2, 2: 3, 3: 4}) - def testListcomps(self): + def test_listcomps(self): # list comprehension tests nums = [1, 2, 3, 4, 5] strs = ["Apple", "Banana", "Coconut"] @@ -979,7 +1042,7 @@ def testListcomps(self): [[1], [1, 1], [1, 2, 4], [1, 3, 9, 27], [1, 4, 16, 64, 256]]) def test_in_func(l): - return [None < x < 3 for x in l if x > 2] + return [0 < x < 3 for x in l if x > 2] self.assertEqual(test_in_func(nums), [False, False, False]) @@ -1019,7 +1082,7 @@ def test_nested_front(): self.assertEqual(x, [('Boeing', 'Airliner'), ('Boeing', 'Engine'), ('Ford', 'Engine'), ('Macdonalds', 'Cheeseburger')]) - def testGenexps(self): + def test_genexps(self): # generator expression tests g = ([x for x in range(10)] for x in range(1)) self.assertEqual(g.next(), [x for x in range(10)]) @@ -1054,7 +1117,7 @@ def testGenexps(self): check_syntax_error(self, "foo(x for x in range(10), 100)") check_syntax_error(self, "foo(100, x for x in range(10))") - def testComprehensionSpecials(self): + def test_comprehension_specials(self): # test for outmost iterable precomputation x = 10; g = (i for i in range(x)); x = 5 self.assertEqual(len(list(g)), 10) @@ -1093,11 +1156,11 @@ def __exit__(self, *args): with manager() as x, manager(): pass - def testIfElseExpr(self): + def test_if_else_expr(self): # Test ifelse expressions in various cases def _checkeval(msg, ret): "helper to check that evaluation of expressions is done correctly" - print x + print(msg) return ret self.assertEqual([ x() for x in lambda: True, lambda: False if x() ], [True]) @@ -1116,7 +1179,8 @@ def _checkeval(msg, ret): self.assertEqual((6 + 1 if 1 else 2), 7) self.assertEqual((6 - 1 if 1 else 2), 5) self.assertEqual((6 * 2 if 1 else 4), 12) - self.assertEqual((6 / 2 if 1 else 3), 3) + with check_py3k_warnings(('classic int division', DeprecationWarning)): + self.assertEqual((6 / 2 if 1 else 3), 3) self.assertEqual((6 < 4 if 0 else 2), 2) def test_paren_evaluation(self): @@ -1129,13 +1193,7 @@ def test_paren_evaluation(self): def test_main(): - with check_py3k_warnings( - ("backquote not supported", SyntaxWarning), - ("tuple parameter unpacking has been removed", SyntaxWarning), - ("parenthesized argument names are invalid", SyntaxWarning), - ("classic int division", DeprecationWarning), - (".+ not supported in 3.x", DeprecationWarning)): - run_unittest(TokenTests, GrammarTests) + run_unittest(TokenTests, GrammarTests) if __name__ == '__main__': test_main() diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 0a61462a608..103b4c11093 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -73,13 +73,12 @@ >>> "abc" = 1 Traceback (most recent call last): - File "", line 1 + File "", line 1 SyntaxError: can't assign to literal ->>> `1` = 1 +>>> b"" = 1 Traceback (most recent call last): - File "", line 1 -SyntaxError: can't assign to repr +SyntaxError: can't assign to literal If the left-hand side of an assignment is a list or tuple, an illegal expression inside that contain should still cause a syntax error. @@ -148,7 +147,7 @@ From ast_for_call(): ->>> def f(it, *varargs): +>>> def f(it, *varargs, **kwargs): ... return list(it) >>> L = range(10) >>> f(x for x in L) @@ -157,73 +156,179 @@ Traceback (most recent call last): File "", line 1 SyntaxError: Generator expression must be parenthesized if not sole argument +>>> f(x for x in L, y=1) +Traceback (most recent call last): +SyntaxError: Generator expression must be parenthesized if not sole argument +>>> f(L, x for x in L) +Traceback (most recent call last): +SyntaxError: Generator expression must be parenthesized if not sole argument +>>> f(x for x in L, y for y in L) +Traceback (most recent call last): +SyntaxError: Generator expression must be parenthesized if not sole argument +>>> f(x for x in L,) +[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> f((x for x in L), 1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, -... i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, -... i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, -... i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, -... i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, -... i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, -... i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, -... i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, -... i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, -... i100, i101, i102, i103, i104, i105, i106, i107, i108, -... i109, i110, i111, i112, i113, i114, i115, i116, i117, -... i118, i119, i120, i121, i122, i123, i124, i125, i126, -... i127, i128, i129, i130, i131, i132, i133, i134, i135, -... i136, i137, i138, i139, i140, i141, i142, i143, i144, -... i145, i146, i147, i148, i149, i150, i151, i152, i153, -... i154, i155, i156, i157, i158, i159, i160, i161, i162, -... i163, i164, i165, i166, i167, i168, i169, i170, i171, -... i172, i173, i174, i175, i176, i177, i178, i179, i180, -... i181, i182, i183, i184, i185, i186, i187, i188, i189, -... i190, i191, i192, i193, i194, i195, i196, i197, i198, -... i199, i200, i201, i202, i203, i204, i205, i206, i207, -... i208, i209, i210, i211, i212, i213, i214, i215, i216, -... i217, i218, i219, i220, i221, i222, i223, i224, i225, -... i226, i227, i228, i229, i230, i231, i232, i233, i234, -... i235, i236, i237, i238, i239, i240, i241, i242, i243, -... i244, i245, i246, i247, i248, i249, i250, i251, i252, -... i253, i254, i255) +>>> def g(*args, **kwargs): +... print args, sorted(kwargs.items()) +>>> g(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254) # doctest: +ELLIPSIS +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..., 252, 253, 254) [] +>>> g(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254, 255) Traceback (most recent call last): File "", line 1 SyntaxError: more than 255 arguments -The actual error cases counts positional arguments, keyword arguments, -and generator expression arguments separately. This test combines the -three. - ->>> f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, -... i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, -... i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, -... i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, -... i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, -... i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, -... i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, -... i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, -... i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, -... i100, i101, i102, i103, i104, i105, i106, i107, i108, -... i109, i110, i111, i112, i113, i114, i115, i116, i117, -... i118, i119, i120, i121, i122, i123, i124, i125, i126, -... i127, i128, i129, i130, i131, i132, i133, i134, i135, -... i136, i137, i138, i139, i140, i141, i142, i143, i144, -... i145, i146, i147, i148, i149, i150, i151, i152, i153, -... i154, i155, i156, i157, i158, i159, i160, i161, i162, -... i163, i164, i165, i166, i167, i168, i169, i170, i171, -... i172, i173, i174, i175, i176, i177, i178, i179, i180, -... i181, i182, i183, i184, i185, i186, i187, i188, i189, -... i190, i191, i192, i193, i194, i195, i196, i197, i198, -... i199, i200, i201, i202, i203, i204, i205, i206, i207, -... i208, i209, i210, i211, i212, i213, i214, i215, i216, -... i217, i218, i219, i220, i221, i222, i223, i224, i225, -... i226, i227, i228, i229, i230, i231, i232, i233, i234, -... i235, i236, i237, i238, i239, i240, i241, i242, i243, -... (x for x in i244), i245, i246, i247, i248, i249, i250, i251, -... i252=1, i253=1, i254=1, i255=1) -Traceback (most recent call last): - File "", line 1 +>>> g(a000=0, a001=1, a002=2, a003=3, a004=4, a005=5, a006=6, a007=7, a008=8, +... a009=9, a010=10, a011=11, a012=12, a013=13, a014=14, a015=15, a016=16, +... a017=17, a018=18, a019=19, a020=20, a021=21, a022=22, a023=23, a024=24, +... a025=25, a026=26, a027=27, a028=28, a029=29, a030=30, a031=31, a032=32, +... a033=33, a034=34, a035=35, a036=36, a037=37, a038=38, a039=39, a040=40, +... a041=41, a042=42, a043=43, a044=44, a045=45, a046=46, a047=47, a048=48, +... a049=49, a050=50, a051=51, a052=52, a053=53, a054=54, a055=55, a056=56, +... a057=57, a058=58, a059=59, a060=60, a061=61, a062=62, a063=63, a064=64, +... a065=65, a066=66, a067=67, a068=68, a069=69, a070=70, a071=71, a072=72, +... a073=73, a074=74, a075=75, a076=76, a077=77, a078=78, a079=79, a080=80, +... a081=81, a082=82, a083=83, a084=84, a085=85, a086=86, a087=87, a088=88, +... a089=89, a090=90, a091=91, a092=92, a093=93, a094=94, a095=95, a096=96, +... a097=97, a098=98, a099=99, a100=100, a101=101, a102=102, a103=103, +... a104=104, a105=105, a106=106, a107=107, a108=108, a109=109, a110=110, +... a111=111, a112=112, a113=113, a114=114, a115=115, a116=116, a117=117, +... a118=118, a119=119, a120=120, a121=121, a122=122, a123=123, a124=124, +... a125=125, a126=126, a127=127, a128=128, a129=129, a130=130, a131=131, +... a132=132, a133=133, a134=134, a135=135, a136=136, a137=137, a138=138, +... a139=139, a140=140, a141=141, a142=142, a143=143, a144=144, a145=145, +... a146=146, a147=147, a148=148, a149=149, a150=150, a151=151, a152=152, +... a153=153, a154=154, a155=155, a156=156, a157=157, a158=158, a159=159, +... a160=160, a161=161, a162=162, a163=163, a164=164, a165=165, a166=166, +... a167=167, a168=168, a169=169, a170=170, a171=171, a172=172, a173=173, +... a174=174, a175=175, a176=176, a177=177, a178=178, a179=179, a180=180, +... a181=181, a182=182, a183=183, a184=184, a185=185, a186=186, a187=187, +... a188=188, a189=189, a190=190, a191=191, a192=192, a193=193, a194=194, +... a195=195, a196=196, a197=197, a198=198, a199=199, a200=200, a201=201, +... a202=202, a203=203, a204=204, a205=205, a206=206, a207=207, a208=208, +... a209=209, a210=210, a211=211, a212=212, a213=213, a214=214, a215=215, +... a216=216, a217=217, a218=218, a219=219, a220=220, a221=221, a222=222, +... a223=223, a224=224, a225=225, a226=226, a227=227, a228=228, a229=229, +... a230=230, a231=231, a232=232, a233=233, a234=234, a235=235, a236=236, +... a237=237, a238=238, a239=239, a240=240, a241=241, a242=242, a243=243, +... a244=244, a245=245, a246=246, a247=247, a248=248, a249=249, a250=250, +... a251=251, a252=252, a253=253, a254=254) # doctest: +ELLIPSIS +() [('a000', 0), ('a001', 1), ('a002', 2), ..., ('a253', 253), ('a254', 254)] +>>> g(a000=0, a001=1, a002=2, a003=3, a004=4, a005=5, a006=6, a007=7, a008=8, +... a009=9, a010=10, a011=11, a012=12, a013=13, a014=14, a015=15, a016=16, +... a017=17, a018=18, a019=19, a020=20, a021=21, a022=22, a023=23, a024=24, +... a025=25, a026=26, a027=27, a028=28, a029=29, a030=30, a031=31, a032=32, +... a033=33, a034=34, a035=35, a036=36, a037=37, a038=38, a039=39, a040=40, +... a041=41, a042=42, a043=43, a044=44, a045=45, a046=46, a047=47, a048=48, +... a049=49, a050=50, a051=51, a052=52, a053=53, a054=54, a055=55, a056=56, +... a057=57, a058=58, a059=59, a060=60, a061=61, a062=62, a063=63, a064=64, +... a065=65, a066=66, a067=67, a068=68, a069=69, a070=70, a071=71, a072=72, +... a073=73, a074=74, a075=75, a076=76, a077=77, a078=78, a079=79, a080=80, +... a081=81, a082=82, a083=83, a084=84, a085=85, a086=86, a087=87, a088=88, +... a089=89, a090=90, a091=91, a092=92, a093=93, a094=94, a095=95, a096=96, +... a097=97, a098=98, a099=99, a100=100, a101=101, a102=102, a103=103, +... a104=104, a105=105, a106=106, a107=107, a108=108, a109=109, a110=110, +... a111=111, a112=112, a113=113, a114=114, a115=115, a116=116, a117=117, +... a118=118, a119=119, a120=120, a121=121, a122=122, a123=123, a124=124, +... a125=125, a126=126, a127=127, a128=128, a129=129, a130=130, a131=131, +... a132=132, a133=133, a134=134, a135=135, a136=136, a137=137, a138=138, +... a139=139, a140=140, a141=141, a142=142, a143=143, a144=144, a145=145, +... a146=146, a147=147, a148=148, a149=149, a150=150, a151=151, a152=152, +... a153=153, a154=154, a155=155, a156=156, a157=157, a158=158, a159=159, +... a160=160, a161=161, a162=162, a163=163, a164=164, a165=165, a166=166, +... a167=167, a168=168, a169=169, a170=170, a171=171, a172=172, a173=173, +... a174=174, a175=175, a176=176, a177=177, a178=178, a179=179, a180=180, +... a181=181, a182=182, a183=183, a184=184, a185=185, a186=186, a187=187, +... a188=188, a189=189, a190=190, a191=191, a192=192, a193=193, a194=194, +... a195=195, a196=196, a197=197, a198=198, a199=199, a200=200, a201=201, +... a202=202, a203=203, a204=204, a205=205, a206=206, a207=207, a208=208, +... a209=209, a210=210, a211=211, a212=212, a213=213, a214=214, a215=215, +... a216=216, a217=217, a218=218, a219=219, a220=220, a221=221, a222=222, +... a223=223, a224=224, a225=225, a226=226, a227=227, a228=228, a229=229, +... a230=230, a231=231, a232=232, a233=233, a234=234, a235=235, a236=236, +... a237=237, a238=238, a239=239, a240=240, a241=241, a242=242, a243=243, +... a244=244, a245=245, a246=246, a247=247, a248=248, a249=249, a250=250, +... a251=251, a252=252, a253=253, a254=254, a255=255) +Traceback (most recent call last): + File "", line 1 +SyntaxError: more than 255 arguments + +>>> class C: +... def meth(self, *args): +... return args +>>> obj = C() +>>> obj.meth( +... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254) # doctest: +ELLIPSIS +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..., 252, 253, 254) +>>> obj.meth( +... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254, 255) +Traceback (most recent call last): + File "", line 1 SyntaxError: more than 255 arguments >>> f(lambda x: x[0] = 3) @@ -403,6 +508,16 @@ ... SyntaxError: too many statically nested blocks +Misuse of the global statement can lead to a few unique syntax errors. + + >>> def f(x): + ... global x + ... # doctest: +ELLIPSIS + Traceback (most recent call last): + ... + SyntaxError: name 'x' is local and global (, line 1) + + This tests assignment-context; there was a bug in Python 2.5 where compiling a complex 'if' (one with 'elif') would fail to notice an invalid suite, leading to spurious errors. @@ -458,9 +573,21 @@ File "", line 6 SyntaxError: can't assign to function call +Test the "raise X, Y[, Z]" form: + + >>> raise ArithmeticError, 'bad number' + Traceback (most recent call last): + ... + ArithmeticError: bad number + >>> raise ArithmeticError, 'bad number', None + Traceback (most recent call last): + ... + ArithmeticError: bad number + + >>> f(a=23, a=234) Traceback (most recent call last): - ... + ... File "", line 1 SyntaxError: keyword argument repeated @@ -476,6 +603,12 @@ File "", line 1 SyntaxError: can't assign to literal +Corner-case that used to fail to raise the correct error: + + >>> def f(x=lambda __debug__:0): pass + Traceback (most recent call last): + SyntaxError: cannot assign to __debug__ + Corner-case that used to crash: >>> def f(*xx, **__debug__): pass @@ -488,12 +621,12 @@ import unittest import warnings -from test import test_support +from test import support class SyntaxTestCase(unittest.TestCase): def _check_error(self, code, errtext, - filename="", mode="exec", subclass=None): + filename="", mode="exec", subclass=None, lineno=None, offset=None): """Check that compiling code raises SyntaxError with errtext. errtest is a regular expression that must be present in the @@ -501,13 +634,19 @@ def _check_error(self, code, errtext, is the expected subclass of SyntaxError (e.g. IndentationError). """ try: - compile(code, filename, mode) - except SyntaxError, err: + compile(code, filename or "", mode) + except SyntaxError as err: if subclass and not isinstance(err, subclass): self.fail("SyntaxError is not a %s" % subclass.__name__) mo = re.search(errtext, str(err)) if mo is None: self.fail("%s did not contain '%r'" % (err, errtext,)) + if filename is not None: + self.assertEqual(err.filename, filename) + if lineno is not None: + self.assertEqual(err.lineno, lineno) + if offset is not None: + self.assertEqual(err.offset, offset) else: self.fail("compile() did not raise SyntaxError") @@ -515,6 +654,11 @@ def test_paren_arg_with_default(self): self._check_error("def f((x)=23): pass", "parenthesized arg with default") + def test_assign_repr(self): + with support.check_py3k_warnings(('backquote not supported', + SyntaxWarning)): + self._check_error("`1` = 1", "assign to repr") + def test_assign_call(self): self._check_error("f() = 1", "assign") @@ -524,28 +668,48 @@ def test_assign_del(self): def test_global_err_then_warn(self): # Bug tickler: The SyntaxError raised for one global statement # shouldn't be clobbered by a SyntaxWarning issued for a later one. - source = re.sub('(?m)^ *:', '', """\ - :def error(a): - : global a # SyntaxError - :def warning(): - : b = 1 - : global b # SyntaxWarning - :""") - warnings.filterwarnings(action='ignore', category=SyntaxWarning) - self._check_error(source, "global") - warnings.filters.pop(0) + source = """if 1: + def error(a): + global a # SyntaxError + def warning(): + b = 1 + global b # SyntaxWarning + """ + with support.check_warnings((".*assigned to before global declaration", + SyntaxWarning)): + self._check_error(source, "local and global", lineno=2) + + def test_misuse_global(self): + source = """if 1: + def f(): + print(x) + global x + """ + with support.check_warnings(('.*used prior to global declaration', + SyntaxWarning)): + compile(source, '', 'exec') + + def test_misuse_global_2(self): + source = """if 1: + def f(): + x = 1 + global x + """ + with support.check_warnings(('.*assigned to before global declaration', + SyntaxWarning)): + compile(source, '', 'exec') def test_break_outside_loop(self): self._check_error("break", "outside loop") def test_delete_deref(self): - source = re.sub('(?m)^ *:', '', """\ - :def foo(x): - : def bar(): - : print x - : del x - :""") - self._check_error(source, "nested scope") + source = """if 1: + def foo(x): + def bar(): + print(x) + del x + """ + self._check_error(source, "nested scope", filename=None) def test_unexpected_indent(self): self._check_error("foo()\n bar()\n", "unexpected indent", @@ -564,11 +728,9 @@ def test_kwargs_last(self): self._check_error("int(base=10, '2')", "non-keyword arg") def test_main(): - test_support.run_unittest(SyntaxTestCase) + support.run_unittest(SyntaxTestCase) from test import test_syntax - with test_support.check_py3k_warnings(("backquote not supported", - SyntaxWarning)): - test_support.run_doctest(test_syntax, verbosity=True) + support.run_doctest(test_syntax, verbosity=True) if __name__ == "__main__": test_main() diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py index 02524588252..7e1d7a131f5 100644 --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -619,7 +619,7 @@ def test_jump_in_nested_finally(output): def test_jump_in_nested_finally_2(output): try: output.append(2) - 1/0 + 1.0/0.0 return finally: output.append(6) @@ -630,7 +630,7 @@ def test_jump_in_nested_finally_2(output): def test_jump_in_nested_finally_3(output): try: output.append(2) - 1/0 + 1.0/0.0 return finally: output.append(6) @@ -697,7 +697,7 @@ def test_jump_backwards_out_of_try_except_block(output): @jump_test(5, 7, [4, 7, 8]) def test_jump_between_except_blocks(output): try: - 1/0 + 1.0/0.0 except ZeroDivisionError: output.append(4) output.append(5) @@ -708,7 +708,7 @@ def test_jump_between_except_blocks(output): @jump_test(5, 6, [4, 6, 7]) def test_jump_within_except_block(output): try: - 1/0 + 1.0/0.0 except: output.append(4) output.append(5) From webhook-mailer at python.org Thu Jan 4 03:36:38 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 08:36:38 -0000 Subject: [Python-checkins] bpo-32482: Fix suspicious code in tests for syntax and grammar. (#5086) Message-ID: https://github.com/python/cpython/commit/0cc99c8cd70d422e4b345837a907db30e9180ab9 commit: 0cc99c8cd70d422e4b345837a907db30e9180ab9 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-04T10:36:35+02:00 summary: bpo-32482: Fix suspicious code in tests for syntax and grammar. (#5086) files: M Lib/test/test_grammar.py M Lib/test/test_syntax.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 9f26e9c4fb0..88c22b89d44 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -575,6 +575,10 @@ def f(*args, **kwargs): self.assertEqual(f(spam='fried', **{'eggs':'scrambled'}), ((), {'eggs':'scrambled', 'spam':'fried'})) + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + # argument annotation tests def f(x) -> list: pass self.assertEqual(f.__annotations__, {'return': list}) @@ -616,10 +620,6 @@ def f(x=1): return closure def f(*, k=1): return closure def f() -> int: return closure - # Check ast errors in *args and *kwargs - check_syntax_error(self, "f(*g(1=2))") - check_syntax_error(self, "f(**g(1=2))") - # Check trailing commas are permitted in funcdef argument list def f(a,): pass def f(*args,): pass @@ -1091,7 +1091,6 @@ def test_try(self): try: 1/0 except EOFError: pass except TypeError as msg: pass - except RuntimeError as msg: pass except: pass else: pass try: 1/0 @@ -1200,7 +1199,7 @@ def test_selectors(self): d[1,2] = 3 d[1,2,3] = 4 L = list(d) - L.sort(key=lambda x: x if isinstance(x, tuple) else ()) + L.sort(key=lambda x: (type(x).__name__, x)) self.assertEqual(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') def test_atoms(self): diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index e161f56d30f..2b96a94401a 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -668,12 +668,12 @@ def test_kwargs_last(self): "positional argument follows keyword argument") def test_kwargs_last2(self): - self._check_error("int(**{base: 10}, '2')", + self._check_error("int(**{'base': 10}, '2')", "positional argument follows " "keyword argument unpacking") def test_kwargs_last3(self): - self._check_error("int(**{base: 10}, *['2'])", + self._check_error("int(**{'base': 10}, *['2'])", "iterable argument unpacking follows " "keyword argument unpacking") From webhook-mailer at python.org Thu Jan 4 04:06:16 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 09:06:16 -0000 Subject: [Python-checkins] bpo-32308: Replace empty matches adjacent to a previous non-empty match in re.sub(). (#4846) Message-ID: https://github.com/python/cpython/commit/fbb490fd2f38bd817d99c20c05121ad0168a38ee commit: fbb490fd2f38bd817d99c20c05121ad0168a38ee branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-04T11:06:13+02:00 summary: bpo-32308: Replace empty matches adjacent to a previous non-empty match in re.sub(). (#4846) files: A Misc/NEWS.d/next/Library/2017-12-13-20-31-30.bpo-32308.CUbsb2.rst M Doc/howto/regex.rst M Doc/library/re.rst M Doc/whatsnew/3.7.rst M Lib/test/test_re.py M Modules/_sre.c diff --git a/Doc/howto/regex.rst b/Doc/howto/regex.rst index fa8c6939408..87a6b1aba59 100644 --- a/Doc/howto/regex.rst +++ b/Doc/howto/regex.rst @@ -1140,12 +1140,12 @@ new string value and the number of replacements that were performed:: >>> p.subn('colour', 'no colours at all') ('no colours at all', 0) -Empty matches are replaced only when they're not adjacent to a previous match. +Empty matches are replaced only when they're not adjacent to a previous empty match. :: >>> p = re.compile('x*') >>> p.sub('-', 'abxd') - '-a-b-d-' + '-a-b--d-' If *replacement* is a string, any backslash escapes in it are processed. That is, ``\n`` is converted to a single newline character, ``\r`` is converted to a diff --git a/Doc/library/re.rst b/Doc/library/re.rst index dae1d7ea10a..9b175f4e967 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -708,12 +708,15 @@ form. That way, separator components are always found at the same relative indices within the result list. - The pattern can match empty strings. :: + Empty matches for the pattern split the string only when not adjacent + to a previous empty match. >>> re.split(r'\b', 'Words, words, words.') ['', 'Words', ', ', 'words', ', ', 'words', '.'] + >>> re.split(r'\W*', '...words...') + ['', '', 'w', 'o', 'r', 'd', 's', '', ''] >>> re.split(r'(\W*)', '...words...') - ['', '...', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', ''] + ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', ''] .. versionchanged:: 3.1 Added the optional flags argument. @@ -778,8 +781,8 @@ form. The optional argument *count* is the maximum number of pattern occurrences to be replaced; *count* must be a non-negative integer. If omitted or zero, all occurrences will be replaced. Empty matches for the pattern are replaced only - when not adjacent to a previous match, so ``sub('x*', '-', 'abc')`` returns - ``'-a-b-c-'``. + when not adjacent to a previous empty match, so ``sub('x*', '-', 'abxd')`` returns + ``'-a-b--d-'``. In string-type *repl* arguments, in addition to the character escapes and backreferences described above, @@ -805,6 +808,9 @@ form. Unknown escapes in *repl* consisting of ``'\'`` and an ASCII letter now are errors. + Empty matches for the pattern are replaced when adjacent to a previous + non-empty match. + .. function:: subn(pattern, repl, string, count=0, flags=0) diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 1924881219a..1311e9e2016 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -881,8 +881,9 @@ Changes in the Python API * The result of splitting a string on a :mod:`regular expression ` that could match an empty string has been changed. For example splitting on ``r'\s*'`` will now split not only on whitespaces as it - did previously, but also between any pair of non-whitespace - characters. The previous behavior can be restored by changing the pattern + did previously, but also on empty strings before all non-whitespace + characters and just before the end of the string. + The previous behavior can be restored by changing the pattern to ``r'\s+'``. A :exc:`FutureWarning` was emitted for such patterns since Python 3.5. @@ -893,7 +894,13 @@ Changes in the Python API positions 2--3. To match only blank lines, the pattern should be rewritten as ``r'(?m)^[^\S\n]*$'``. - (Contributed by Serhiy Storchaka in :issue:`25054`.) + :func:`re.sub()` now replaces empty matches adjacent to a previous + non-empty match. For example ``re.sub('x*', '-', 'abxd')`` returns now + ``'-a-b--d-'`` instead of ``'-a-b--d-'`` (the first minus between 'b' and + 'd' replaces 'x', and the second minus replaces an empty string between + 'x' and 'd'). + + (Contributed by Serhiy Storchaka in :issue:`25054` and :issue:`32308`.) * :class:`tracemalloc.Traceback` frames are now sorted from oldest to most recent to be more consistent with :mod:`traceback`. diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index aaed3d893aa..9fed4bef880 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -213,11 +213,6 @@ def test_bug_114660(self): self.assertEqual(re.sub(r'(\S)\s+(\S)', r'\1 \2', 'hello there'), 'hello there') - def test_bug_462270(self): - # Test for empty sub() behaviour, see SF bug #462270 - self.assertEqual(re.sub('x*', '-', 'abxd'), '-a-b-d-') - self.assertEqual(re.sub('x+', '-', 'abxd'), 'ab-d') - def test_symbolic_groups(self): re.compile(r'(?Px)(?P=a)(?(a)y)') re.compile(r'(?Px)(?P=a1)(?(a1)y)') @@ -331,10 +326,10 @@ def test_re_split(self): ['', 'a', '', '', 'c']) for sep, expected in [ - (':*', ['', 'a', 'b', 'c', '']), - ('(?::*)', ['', 'a', 'b', 'c', '']), - ('(:*)', ['', ':', 'a', ':', 'b', '::', 'c', '', '']), - ('(:)*', ['', ':', 'a', ':', 'b', ':', 'c', None, '']), + (':*', ['', '', 'a', '', 'b', '', 'c', '']), + ('(?::*)', ['', '', 'a', '', 'b', '', 'c', '']), + ('(:*)', ['', ':', '', '', 'a', ':', '', '', 'b', '::', '', '', 'c', '', '']), + ('(:)*', ['', ':', '', None, 'a', ':', '', None, 'b', ':', '', None, 'c', None, '']), ]: with self.subTest(sep=sep): self.assertTypedEqual(re.split(sep, ':a:b::c'), expected) @@ -357,7 +352,7 @@ def test_qualified_re_split(self): self.assertEqual(re.split("(:+)", ":a:b::c", maxsplit=2), ['', ':', 'a', ':', 'b::c']) self.assertEqual(re.split("(:*)", ":a:b::c", maxsplit=2), - ['', ':', 'a', ':', 'b::c']) + ['', ':', '', '', 'a:b::c']) def test_re_findall(self): self.assertEqual(re.findall(":+", "abc"), []) @@ -1753,13 +1748,13 @@ def test_match_repr(self): def test_zerowidth(self): # Issues 852532, 1647489, 3262, 25054. self.assertEqual(re.split(r"\b", "a::bc"), ['', 'a', '::', 'bc', '']) - self.assertEqual(re.split(r"\b|:+", "a::bc"), ['', 'a', '', 'bc', '']) - self.assertEqual(re.split(r"(? https://github.com/python/cpython/commit/1e6d8525f9dd3dcdc83adb93b164082c8b95d17a commit: 1e6d8525f9dd3dcdc83adb93b164082c8b95d17a branch: 3.6 author: Serhiy Storchaka committer: GitHub date: 2018-01-04T11:08:24+02:00 summary: bpo-32211: Document the existing bug in re.findall() and re.finditer(). (#4695) files: M Doc/library/re.rst diff --git a/Doc/library/re.rst b/Doc/library/re.rst index fae8945f8b8..874c8ddce67 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -719,14 +719,21 @@ form. Splitting on a pattern that could match an empty string now raises a warning. Patterns that can only match empty strings are now rejected. + .. function:: findall(pattern, string, flags=0) Return all non-overlapping matches of *pattern* in *string*, as a list of strings. The *string* is scanned left-to-right, and matches are returned in the order found. If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than - one group. Empty matches are included in the result unless they touch the - beginning of another match. + one group. Empty matches are included in the result. + + .. note:: + + Due to the limitation of the current implementation the character + following an empty match is not included in a next match, so + ``findall(r'^|\w+', 'two words')`` returns ``['', 'wo', 'words']`` + (note missed "t"). This is changed in Python 3.7. .. function:: finditer(pattern, string, flags=0) @@ -734,8 +741,7 @@ form. Return an :term:`iterator` yielding :ref:`match objects ` over all non-overlapping matches for the RE *pattern* in *string*. The *string* is scanned left-to-right, and matches are returned in the order found. Empty - matches are included in the result unless they touch the beginning of another - match. + matches are included in the result. See also the note about :func:`findall`. .. function:: sub(pattern, repl, string, count=0, flags=0) From solipsis at pitrou.net Thu Jan 4 04:08:56 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Thu, 04 Jan 2018 09:08:56 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=10 Message-ID: <20180104090856.1.A18E564691E79EAD@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 0, 7] memory blocks, sum=7 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [-2, 2, -1] memory blocks, sum=-1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogg7TW73', '--timeout', '7200'] From webhook-mailer at python.org Thu Jan 4 04:15:47 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 09:15:47 -0000 Subject: [Python-checkins] bpo-31778: Make ast.literal_eval() more strict. (#4035) Message-ID: https://github.com/python/cpython/commit/d8ac4d1d5ac256ebf3d8d38c226049abec82a2a0 commit: d8ac4d1d5ac256ebf3d8d38c226049abec82a2a0 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-04T11:15:39+02:00 summary: bpo-31778: Make ast.literal_eval() more strict. (#4035) Addition and subtraction of arbitrary numbers no longer allowed. files: A Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst M Lib/ast.py M Lib/test/test_ast.py M Lib/test/test_inspect.py diff --git a/Lib/ast.py b/Lib/ast.py index 070c2bee7f9..2ecb03f38bc 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -35,8 +35,6 @@ def parse(source, filename='', mode='exec'): return compile(source, filename, mode, PyCF_ONLY_AST) -_NUM_TYPES = (int, float, complex) - def literal_eval(node_or_string): """ Safely evaluate an expression node or a string containing a Python @@ -48,6 +46,21 @@ def literal_eval(node_or_string): node_or_string = parse(node_or_string, mode='eval') if isinstance(node_or_string, Expression): node_or_string = node_or_string.body + def _convert_num(node): + if isinstance(node, Constant): + if isinstance(node.value, (int, float, complex)): + return node.value + elif isinstance(node, Num): + return node.n + raise ValueError('malformed node or string: ' + repr(node)) + def _convert_signed_num(node): + if isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)): + operand = _convert_num(node.operand) + if isinstance(node.op, UAdd): + return + operand + else: + return - operand + return _convert_num(node) def _convert(node): if isinstance(node, Constant): return node.value @@ -62,26 +75,19 @@ def _convert(node): elif isinstance(node, Set): return set(map(_convert, node.elts)) elif isinstance(node, Dict): - return dict((_convert(k), _convert(v)) for k, v - in zip(node.keys, node.values)) + return dict(zip(map(_convert, node.keys), + map(_convert, node.values))) elif isinstance(node, NameConstant): return node.value - elif isinstance(node, UnaryOp) and isinstance(node.op, (UAdd, USub)): - operand = _convert(node.operand) - if isinstance(operand, _NUM_TYPES): - if isinstance(node.op, UAdd): - return + operand - else: - return - operand elif isinstance(node, BinOp) and isinstance(node.op, (Add, Sub)): - left = _convert(node.left) - right = _convert(node.right) - if isinstance(left, _NUM_TYPES) and isinstance(right, _NUM_TYPES): + left = _convert_signed_num(node.left) + right = _convert_num(node.right) + if isinstance(left, (int, float)) and isinstance(right, complex): if isinstance(node.op, Add): return left + right else: return left - right - raise ValueError('malformed node or string: ' + repr(node)) + return _convert_signed_num(node) return _convert(node_or_string) diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index aa53503e3b5..67f363ad31f 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -551,14 +551,37 @@ def test_literal_eval(self): self.assertEqual(ast.literal_eval('{1, 2, 3}'), {1, 2, 3}) self.assertEqual(ast.literal_eval('b"hi"'), b"hi") self.assertRaises(ValueError, ast.literal_eval, 'foo()') + self.assertEqual(ast.literal_eval('6'), 6) + self.assertEqual(ast.literal_eval('+6'), 6) self.assertEqual(ast.literal_eval('-6'), -6) - self.assertEqual(ast.literal_eval('-6j+3'), 3-6j) self.assertEqual(ast.literal_eval('3.25'), 3.25) - - def test_literal_eval_issue4907(self): - self.assertEqual(ast.literal_eval('2j'), 2j) - self.assertEqual(ast.literal_eval('10 + 2j'), 10 + 2j) - self.assertEqual(ast.literal_eval('1.5 - 2j'), 1.5 - 2j) + self.assertEqual(ast.literal_eval('+3.25'), 3.25) + self.assertEqual(ast.literal_eval('-3.25'), -3.25) + self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0') + self.assertRaises(ValueError, ast.literal_eval, '++6') + self.assertRaises(ValueError, ast.literal_eval, '+True') + self.assertRaises(ValueError, ast.literal_eval, '2+3') + + def test_literal_eval_complex(self): + # Issue #4907 + self.assertEqual(ast.literal_eval('6j'), 6j) + self.assertEqual(ast.literal_eval('-6j'), -6j) + self.assertEqual(ast.literal_eval('6.75j'), 6.75j) + self.assertEqual(ast.literal_eval('-6.75j'), -6.75j) + self.assertEqual(ast.literal_eval('3+6j'), 3+6j) + self.assertEqual(ast.literal_eval('-3+6j'), -3+6j) + self.assertEqual(ast.literal_eval('3-6j'), 3-6j) + self.assertEqual(ast.literal_eval('-3-6j'), -3-6j) + self.assertEqual(ast.literal_eval('3.25+6.75j'), 3.25+6.75j) + self.assertEqual(ast.literal_eval('-3.25+6.75j'), -3.25+6.75j) + self.assertEqual(ast.literal_eval('3.25-6.75j'), 3.25-6.75j) + self.assertEqual(ast.literal_eval('-3.25-6.75j'), -3.25-6.75j) + self.assertEqual(ast.literal_eval('(3+6j)'), 3+6j) + self.assertRaises(ValueError, ast.literal_eval, '-6j+3') + self.assertRaises(ValueError, ast.literal_eval, '-6j+3j') + self.assertRaises(ValueError, ast.literal_eval, '3+-6j') + self.assertRaises(ValueError, ast.literal_eval, '3+(0+6j)') + self.assertRaises(ValueError, ast.literal_eval, '-(3+6j)') def test_bad_integer(self): # issue13436: Bad error message with invalid numeric values @@ -1077,11 +1100,11 @@ def test_literal_eval(self): ast.copy_location(new_left, binop.left) binop.left = new_left - new_right = ast.Constant(value=20) + new_right = ast.Constant(value=20j) ast.copy_location(new_right, binop.right) binop.right = new_right - self.assertEqual(ast.literal_eval(binop), 30) + self.assertEqual(ast.literal_eval(binop), 10+20j) def main(): diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index e8eddbedf7e..cb51f8aff29 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -2074,7 +2074,7 @@ def p(name): return signature.parameters[name].default self.assertEqual(p('f'), False) self.assertEqual(p('local'), 3) self.assertEqual(p('sys'), sys.maxsize) - self.assertEqual(p('exp'), sys.maxsize - 1) + self.assertNotIn('exp', signature.parameters) test_callable(object) diff --git a/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst b/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst new file mode 100644 index 00000000000..452ad6e4bd2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst @@ -0,0 +1,2 @@ +ast.literal_eval() is now more strict. Addition and subtraction of +arbitrary numbers no longer allowed. From webhook-mailer at python.org Thu Jan 4 04:32:55 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 09:32:55 -0000 Subject: [Python-checkins] bpo-32482: Fix suspicious code in tests for syntax and grammar. (GH-5086) (#5095) Message-ID: https://github.com/python/cpython/commit/a70d5ff992e5e123a3fa6f0e7f672026db8ed1f7 commit: a70d5ff992e5e123a3fa6f0e7f672026db8ed1f7 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-01-04T11:32:53+02:00 summary: bpo-32482: Fix suspicious code in tests for syntax and grammar. (GH-5086) (#5095) (cherry picked from commit 0cc99c8cd70d422e4b345837a907db30e9180ab9) files: M Lib/test/test_grammar.py M Lib/test/test_syntax.py diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 62f3251f051..ac8d85a3c41 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -575,6 +575,10 @@ def f(*args, **kwargs): self.assertEqual(f(spam='fried', **{'eggs':'scrambled'}), ((), {'eggs':'scrambled', 'spam':'fried'})) + # Check ast errors in *args and *kwargs + check_syntax_error(self, "f(*g(1=2))") + check_syntax_error(self, "f(**g(1=2))") + # argument annotation tests def f(x) -> list: pass self.assertEqual(f.__annotations__, {'return': list}) @@ -616,10 +620,6 @@ def f(x=1): return closure def f(*, k=1): return closure def f() -> int: return closure - # Check ast errors in *args and *kwargs - check_syntax_error(self, "f(*g(1=2))") - check_syntax_error(self, "f(**g(1=2))") - # Check trailing commas are permitted in funcdef argument list def f(a,): pass def f(*args,): pass @@ -1056,7 +1056,6 @@ def test_try(self): try: 1/0 except EOFError: pass except TypeError as msg: pass - except RuntimeError as msg: pass except: pass else: pass try: 1/0 @@ -1165,7 +1164,7 @@ def test_selectors(self): d[1,2] = 3 d[1,2,3] = 4 L = list(d) - L.sort(key=lambda x: x if isinstance(x, tuple) else ()) + L.sort(key=lambda x: (type(x).__name__, x)) self.assertEqual(str(L), '[1, (1,), (1, 2), (1, 2, 3)]') def test_atoms(self): diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index b7095a2cdb0..26f508316b6 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -600,12 +600,12 @@ def test_kwargs_last(self): "positional argument follows keyword argument") def test_kwargs_last2(self): - self._check_error("int(**{base: 10}, '2')", + self._check_error("int(**{'base': 10}, '2')", "positional argument follows " "keyword argument unpacking") def test_kwargs_last3(self): - self._check_error("int(**{base: 10}, *['2'])", + self._check_error("int(**{'base': 10}, *['2'])", "iterable argument unpacking follows " "keyword argument unpacking") From webhook-mailer at python.org Thu Jan 4 05:24:52 2018 From: webhook-mailer at python.org (Berker Peksag) Date: Thu, 04 Jan 2018 10:24:52 -0000 Subject: [Python-checkins] Fix outdated comment in typeobject.c (GH-5090) Message-ID: https://github.com/python/cpython/commit/78e24d4415c37e9e9951920bc31e9ee4868d86cb commit: 78e24d4415c37e9e9951920bc31e9ee4868d86cb branch: master author: Berker Peksag committer: GitHub date: 2018-01-04T13:24:45+03:00 summary: Fix outdated comment in typeobject.c (GH-5090) The comment was added in 3abca127fe1565ec80f6b0a1ae48d65186ad887d. In d78448e912126410117723c7d240bbdfff06df16, it was changed to use PyArg_ParseTuple instead. files: M Objects/typeobject.c diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 40c8fadc52e..e570c4145df 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2372,7 +2372,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } /* SF bug 475327 -- if that didn't trigger, we need 3 - arguments. but PyArg_ParseTupleAndKeywords below may give + arguments. but PyArg_ParseTuple below may give a msg saying type() needs exactly 3. */ if (nargs != 3) { PyErr_SetString(PyExc_TypeError, From webhook-mailer at python.org Thu Jan 4 06:06:51 2018 From: webhook-mailer at python.org (Berker Peksag) Date: Thu, 04 Jan 2018 11:06:51 -0000 Subject: [Python-checkins] Fix outdated comment in typeobject.c (GH-5090) Message-ID: https://github.com/python/cpython/commit/78e43a59acd2c5c2325e52f37ddd59d2079391ee commit: 78e43a59acd2c5c2325e52f37ddd59d2079391ee branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Berker Peksag date: 2018-01-04T14:06:47+03:00 summary: Fix outdated comment in typeobject.c (GH-5090) The comment was added in 3abca127fe1565ec80f6b0a1ae48d65186ad887d. In d78448e912126410117723c7d240bbdfff06df16, it was changed to use PyArg_ParseTuple instead. (cherry picked from commit 78e24d4415c37e9e9951920bc31e9ee4868d86cb) files: M Objects/typeobject.c diff --git a/Objects/typeobject.c b/Objects/typeobject.c index cb5e235628d..5a231c81d4e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2313,7 +2313,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) } /* SF bug 475327 -- if that didn't trigger, we need 3 - arguments. but PyArg_ParseTupleAndKeywords below may give + arguments. but PyArg_ParseTuple below may give a msg saying type() needs exactly 3. */ if (nargs != 3) { PyErr_SetString(PyExc_TypeError, From webhook-mailer at python.org Thu Jan 4 07:08:34 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 12:08:34 -0000 Subject: [Python-checkins] [2.7] bpo-32211: Document the existing bug in re.findall() and re.finditer(). (GH-4695). (#5096) Message-ID: https://github.com/python/cpython/commit/ca54740f257086393106d242644d450485180b96 commit: ca54740f257086393106d242644d450485180b96 branch: 2.7 author: Serhiy Storchaka committer: GitHub date: 2018-01-04T14:08:27+02:00 summary: [2.7] bpo-32211: Document the existing bug in re.findall() and re.finditer(). (GH-4695). (#5096) (cherry picked from commit 1e6d8525f9dd3dcdc83adb93b164082c8b95d17a) files: M Doc/library/re.rst diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 22340818e26..c424230e13a 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -611,14 +611,21 @@ form. Added the optional flags argument. + .. function:: findall(pattern, string, flags=0) Return all non-overlapping matches of *pattern* in *string*, as a list of strings. The *string* is scanned left-to-right, and matches are returned in the order found. If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than - one group. Empty matches are included in the result unless they touch the - beginning of another match. + one group. Empty matches are included in the result. + + .. note:: + + Due to the limitation of the current implementation the character + following an empty match is not included in a next match, so + ``findall(r'^|\w+', 'two words')`` returns ``['', 'wo', 'words']`` + (note missed "t"). This is changed in Python 3.7. .. versionadded:: 1.5.2 @@ -631,8 +638,7 @@ form. Return an :term:`iterator` yielding :class:`MatchObject` instances over all non-overlapping matches for the RE *pattern* in *string*. The *string* is scanned left-to-right, and matches are returned in the order found. Empty - matches are included in the result unless they touch the beginning of another - match. + matches are included in the result. See also the note about :func:`findall`. .. versionadded:: 2.2 From webhook-mailer at python.org Thu Jan 4 12:20:15 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 17:20:15 -0000 Subject: [Python-checkins] bpo-31672: Restore the former behavior when override flags in Template. (#5099) Message-ID: https://github.com/python/cpython/commit/87be28f4a1c5b76926c71a3d9f92503f9eb82d51 commit: 87be28f4a1c5b76926c71a3d9f92503f9eb82d51 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-04T19:20:11+02:00 summary: bpo-31672: Restore the former behavior when override flags in Template. (#5099) Overriding flags to 0 will make the default pattern matching only lower case letters. files: M Doc/library/string.rst M Lib/string.py M Lib/test/test_string.py diff --git a/Doc/library/string.rst b/Doc/library/string.rst index e9606783ef7..fc3d94bfbfc 100644 --- a/Doc/library/string.rst +++ b/Doc/library/string.rst @@ -755,19 +755,14 @@ attributes: * *idpattern* -- This is the regular expression describing the pattern for non-braced placeholders. The default value is the regular expression - ``(?a:[_a-zA-Z][_a-zA-Z0-9]*)``. If this is given and *braceidpattern* is + ``(?a:[_a-z][_a-z0-9]*)``. If this is given and *braceidpattern* is ``None`` this pattern will also apply to braced placeholders. .. note:: Since default *flags* is ``re.IGNORECASE``, pattern ``[a-z]`` can match with some non-ASCII characters. That's why we use the local ``a`` flag - here. Further, with the default *flags* value, including ``A-Z`` in the - ranges is redundant, but required for backward compatibility. - - While *flags* is kept to ``re.IGNORECASE`` for backward compatibility, - you can override it to ``0`` or ``re.IGNORECASE | re.ASCII`` when - subclassing. + here. .. versionchanged:: 3.7 *braceidpattern* can be used to define separate patterns used inside and diff --git a/Lib/string.py b/Lib/string.py index fd4b1f7a62f..b9d6f5eb567 100644 --- a/Lib/string.py +++ b/Lib/string.py @@ -82,11 +82,8 @@ class Template(metaclass=_TemplateMetaclass): # r'[a-z]' matches to non-ASCII letters when used with IGNORECASE, but # without the ASCII flag. We can't add re.ASCII to flags because of # backward compatibility. So we use the ?a local flag and [a-z] pattern. - # We also can't remove the A-Z ranges, because although they are - # technically redundant with the IGNORECASE flag, the value is part of the - # publicly documented API. # See https://bugs.python.org/issue31672 - idpattern = r'(?a:[_a-zA-Z][_a-zA-Z0-9]*)' + idpattern = r'(?a:[_a-z][_a-z0-9]*)' braceidpattern = None flags = _re.IGNORECASE diff --git a/Lib/test/test_string.py b/Lib/test/test_string.py index 3480459c282..0be28fdb609 100644 --- a/Lib/test/test_string.py +++ b/Lib/test/test_string.py @@ -219,6 +219,16 @@ def test_regular_templates_with_braces(self): self.assertRaises(KeyError, s.substitute, dict(who='tim', what='ham')) + def test_regular_templates_with_upper_case(self): + s = Template('$WHO likes ${WHAT} for ${MEAL}') + d = dict(WHO='tim', WHAT='ham', MEAL='dinner') + self.assertEqual(s.substitute(d), 'tim likes ham for dinner') + + def test_regular_templates_with_non_letters(self): + s = Template('$_wh0_ likes ${_w_h_a_t_} for ${mea1}') + d = dict(_wh0_='tim', _w_h_a_t_='ham', mea1='dinner') + self.assertEqual(s.substitute(d), 'tim likes ham for dinner') + def test_escapes(self): eq = self.assertEqual s = Template('$who likes to eat a bag of $$what worth $$100') @@ -288,6 +298,14 @@ class PathPattern(Template): s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what') self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') + def test_flags_override(self): + class MyPattern(Template): + flags = 0 + s = MyPattern('$wHO likes ${WHAT} for ${meal}') + d = dict(wHO='tim', WHAT='ham', meal='dinner', w='fred') + self.assertRaises(ValueError, s.substitute, d) + self.assertEqual(s.safe_substitute(d), 'fredHO likes ${WHAT} for dinner') + def test_idpattern_override_inside_outside(self): # bpo-1198569: Allow the regexp inside and outside braces to be # different when deriving from Template. From webhook-mailer at python.org Thu Jan 4 17:21:50 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Thu, 04 Jan 2018 22:21:50 -0000 Subject: [Python-checkins] bpo-32226: Make __class_getitem__ an automatic class method. (#5098) Message-ID: https://github.com/python/cpython/commit/ce5b0e9db1b9698e6ffc43ae41cf3a22ca5a6ba6 commit: ce5b0e9db1b9698e6ffc43ae41cf3a22ca5a6ba6 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-05T00:21:41+02:00 summary: bpo-32226: Make __class_getitem__ an automatic class method. (#5098) files: A Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst M Lib/test/test_genericclass.py M Modules/_testcapimodule.c M Objects/abstract.c M Objects/typeobject.c diff --git a/Lib/test/test_genericclass.py b/Lib/test/test_genericclass.py index 2057fc000c0..37e755b1167 100644 --- a/Lib/test/test_genericclass.py +++ b/Lib/test/test_genericclass.py @@ -183,12 +183,21 @@ def __class_getitem__(cls, item): self.assertEqual(D[int], 'D[int]') self.assertEqual(D[D], 'D[D]') + def test_class_getitem_classmethod(self): + class C: + @classmethod + def __class_getitem__(cls, item): + return f'{cls.__name__}[{item.__name__}]' + class D(C): ... + self.assertEqual(D[int], 'D[int]') + self.assertEqual(D[D], 'D[D]') + def test_class_getitem_patched(self): class C: def __init_subclass__(cls): def __class_getitem__(cls, item): return f'{cls.__name__}[{item.__name__}]' - cls.__class_getitem__ = __class_getitem__ + cls.__class_getitem__ = classmethod(__class_getitem__) class D(C): ... self.assertEqual(D[int], 'D[int]') self.assertEqual(D[D], 'D[D]') @@ -254,7 +263,7 @@ class CAPITest(unittest.TestCase): def test_c_class(self): from _testcapi import Generic, GenericAlias - self.assertIsInstance(Generic.__class_getitem__(Generic, int), GenericAlias) + self.assertIsInstance(Generic.__class_getitem__(int), GenericAlias) IntGeneric = Generic[int] self.assertIs(type(IntGeneric), GenericAlias) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst new file mode 100644 index 00000000000..842775f3b93 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst @@ -0,0 +1 @@ +``__class_getitem__`` is now an automatic class method. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 47b50640f5d..7b2e2a3e5a4 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5104,17 +5104,13 @@ typedef struct { } PyGenericObject; static PyObject * -generic_class_getitem(PyObject *self, PyObject *args) +generic_class_getitem(PyObject *type, PyObject *item) { - PyObject *type, *item; - if (!PyArg_UnpackTuple(args, "__class_getitem__", 2, 2, &type, &item)) { - return NULL; - } return generic_alias_new(item); } static PyMethodDef generic_methods[] = { - {"__class_getitem__", generic_class_getitem, METH_VARARGS|METH_STATIC, NULL}, + {"__class_getitem__", generic_class_getitem, METH_O|METH_CLASS, NULL}, {NULL} /* sentinel */ }; diff --git a/Objects/abstract.c b/Objects/abstract.c index 0105c5d1696..a68253bdb43 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -169,11 +169,11 @@ PyObject_GetItem(PyObject *o, PyObject *key) } if (PyType_Check(o)) { - PyObject *meth, *result, *stack[2] = {o, key}; + PyObject *meth, *result, *stack[1] = {key}; _Py_IDENTIFIER(__class_getitem__); meth = _PyObject_GetAttrId(o, &PyId___class_getitem__); if (meth) { - result = _PyObject_FastCall(meth, stack, 2); + result = _PyObject_FastCall(meth, stack, 1); Py_DECREF(meth); return result; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index e570c4145df..0c8f0adfb78 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -55,6 +55,7 @@ static size_t method_cache_collisions = 0; /* alphabetical order */ _Py_IDENTIFIER(__abstractmethods__); _Py_IDENTIFIER(__class__); +_Py_IDENTIFIER(__class_getitem__); _Py_IDENTIFIER(__delitem__); _Py_IDENTIFIER(__dict__); _Py_IDENTIFIER(__doc__); @@ -2694,8 +2695,8 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) Py_DECREF(tmp); } - /* Special-case __init_subclass__: if it's a plain function, - make it a classmethod */ + /* Special-case __init_subclass__ and __class_getitem__: + if they are plain functions, make them classmethods */ tmp = _PyDict_GetItemId(dict, &PyId___init_subclass__); if (tmp != NULL && PyFunction_Check(tmp)) { tmp = PyClassMethod_New(tmp); @@ -2708,6 +2709,18 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) Py_DECREF(tmp); } + tmp = _PyDict_GetItemId(dict, &PyId___class_getitem__); + if (tmp != NULL && PyFunction_Check(tmp)) { + tmp = PyClassMethod_New(tmp); + if (tmp == NULL) + goto error; + if (_PyDict_SetItemId(dict, &PyId___class_getitem__, tmp) < 0) { + Py_DECREF(tmp); + goto error; + } + Py_DECREF(tmp); + } + /* Add descriptors for custom slots from __slots__, or for __dict__ */ mp = PyHeapType_GET_MEMBERS(et); slotoffset = base->tp_basicsize; From lp_benchmark_robot at intel.com Thu Jan 4 17:52:15 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Thu, 4 Jan 2018 14:52:15 -0800 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-01-04 Message-ID: Results for project python/master, build date: 2018-01-04 03:04:09-08:00. - commit: 78e24d4 - previous commit: f190eb5 - revision date: 2018-01-04 13:24:45+03:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.797% | +0.133% | +8.032% | +6.092% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 1.105% | +0.028% | +22.468% | +11.210% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.876% | -0.275% | +24.734% | +9.827% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 0.988% | +0.233% | +22.372% | +10.117% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 2.518% | +1.300% | +9.326% | +12.009% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.844% | +0.137% | +9.478% | +14.814% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 2.200% | +0.357% | +5.928% | +11.537% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.616% | +0.250% | -0.725% | +9.190% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 0.988% | -0.169% | +11.421% | +16.770% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 2.348% | +1.230% | +13.931% | +13.320% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.217% | -0.220% | +3.417% | +6.512% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.353% | -0.635% | +4.675% | +6.306% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 0.706% | +0.801% | +2.386% | +6.078% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.284% | +0.169% | +12.233% | +10.870% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.323% | -0.603% | +8.018% | +10.753% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 1.060% | +0.108% | +6.217% | +11.330% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.767% | -0.035% | +10.498% | +11.191% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 3.773% | -0.508% | +7.161% | +10.447% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 2.057% | -1.026% | +2.161% | +10.118% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 1.319% | +0.606% | -0.184% | +12.863% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.657% | +1.078% | +8.068% | +11.898% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.877% | -0.956% | +47.176% | +13.350% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.741% | +1.404% | +9.222% | +13.028% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.703% | -0.039% | +17.121% | +12.590% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 1.545% | +0.594% | +11.732% | +6.808% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 2.454% | -0.270% | +4.070% | +5.999% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.409% | -1.703% | -3.838% | +2.823% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 2.173% | -0.228% | +4.309% | +8.196% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.174% | -0.220% | +0.722% | +13.097% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.295% | +0.128% | +1.276% | +20.244% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.420% | +0.276% | +2.071% | +22.753% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.817% | -0.030% | +3.743% | +21.988% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 3.435% | -0.327% | +11.240% | +10.329% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.052% | +0.091% | -0.080% | +10.317% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.136% | +0.028% | +10.695% | +4.989% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.108% | +0.067% | +2.025% | +5.068% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 1.210% | -0.022% | +10.435% | +13.817% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.521% | -0.279% | +4.685% | +11.187% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.487% | +0.054% | -2.489% | +12.251% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.374% | -0.070% | -5.294% | +7.086% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 1.061% | -0.050% | +3.782% | +8.280% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.975% | -0.305% | +8.811% | +15.339% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 2.590% | -0.975% | -2.493% | +3.452% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 1.813% | -0.845% | +26.714% | +8.635% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.560% | -0.653% | +4.189% | +7.086% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 0.929% | -0.254% | +14.304% | +7.591% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.776% | -0.630% | -3.393% | -2.623% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.580% | -0.528% | +5.353% | +4.259% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.593% | +0.282% | +7.210% | +5.771% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 2.974% | +0.689% | +7.152% | +3.229% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 3.729% | +0.393% | +19.319% | +8.864% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 1.926% | +0.099% | +12.374% | +5.317% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 2.095% | -0.203% | +8.883% | +6.382% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 3.460% | +0.604% | +12.232% | +7.890% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.381% | -1.832% | +9.323% | +10.574% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 5.579% | -0.893% | +19.292% | +12.342% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.998% | +0.233% | +6.324% | +5.886% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 1.090% | +0.335% | +2.347% | +3.000% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 8.031% | -1.749% | +6.747% | +23.029% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 2.646% | +0.220% | -3.757% | +17.204% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 0.861% | -0.189% | +8.522% | +6.625% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.037% | +0.195% | +2.162% | +12.480% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.382% | -0.192% | +3.526% | +7.787% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 2.581% | +0.508% | -8.382% | +12.486% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.286% | +0.241% | +4.416% | +11.897% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-01-04 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 webhook-mailer at python.org Fri Jan 5 01:34:23 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 05 Jan 2018 06:34:23 -0000 Subject: [Python-checkins] advance copyright years to 2018 (#5094) Message-ID: https://github.com/python/cpython/commit/65f2a6dcc2bc28a8566b74c8e9273f982331ec48 commit: 65f2a6dcc2bc28a8566b74c8e9273f982331ec48 branch: master author: Benjamin Peterson committer: GitHub date: 2018-01-04T22:34:19-08:00 summary: advance copyright years to 2018 (#5094) files: M Doc/copyright.rst M Doc/license.rst M LICENSE M Mac/IDLE/IDLE.app/Contents/Info.plist M Mac/PythonLauncher/Info.plist.in M Mac/Resources/app/Info.plist.in M Mac/Resources/framework/Info.plist.in M Python/getcopyright.c M README.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 2b5400cd9fb..540ff5ef059 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright ? 2001-2017 Python Software Foundation. All rights reserved. +Copyright ? 2001-2018 Python Software Foundation. All rights reserved. Copyright ? 2000 BeOpen.com. All rights reserved. diff --git a/Doc/license.rst b/Doc/license.rst index cd018689f87..aa4b1450e91 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright ? 2001-2017 Python Software Foundation; All Rights + copyright, i.e., "Copyright ? 2001-2018 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/LICENSE b/LICENSE index 529349e4b38..1afbedba92b 100644 --- a/LICENSE +++ b/LICENSE @@ -73,9 +73,9 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights -Reserved" are retained in Python alone or in any derivative version prepared by -Licensee. +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All +Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index 5507687e90e..826d3793f75 100644 --- a/Mac/IDLE/IDLE.app/Contents/Info.plist +++ b/Mac/IDLE/IDLE.app/Contents/Info.plist @@ -36,7 +36,7 @@ CFBundleExecutable IDLE CFBundleGetInfoString - %version%, ? 2001-2017 Python Software Foundation + %version%, ? 2001-2018 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index f1ab79f3d44..5fa346ed4d3 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable Python Launcher CFBundleGetInfoString - %VERSION%, ? 2001-2017 Python Software Foundation + %VERSION%, ? 2001-2018 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index a23166e6d32..abe9ae23e34 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2017 Python Software Foundation. + %version%, (c) 2001-2018 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index 7a64619e295..c1ea9f68892 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Python/getcopyright.c b/Python/getcopyright.c index cac647c3ce4..51772ecef31 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2017 Python Software Foundation.\n\ +Copyright (c) 2001-2018 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/README.rst b/README.rst index d60fcac35d5..346eb4a32db 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ This is Python version 3.7.0 alpha 3+ :target: https://codecov.io/gh/python/cpython Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. See the end of this file for further copyright and license information. @@ -233,7 +233,7 @@ Copyright and License Information --------------------------------- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. All rights reserved. From webhook-mailer at python.org Fri Jan 5 02:02:14 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Fri, 05 Jan 2018 07:02:14 -0000 Subject: [Python-checkins] [2.7] advance copyright years to 2018 (GH-5094). (#5105) Message-ID: https://github.com/python/cpython/commit/e13698172f5da96c2639224c216efb05b48ceac9 commit: e13698172f5da96c2639224c216efb05b48ceac9 branch: 2.7 author: Benjamin Peterson committer: GitHub date: 2018-01-04T23:02:11-08:00 summary: [2.7] advance copyright years to 2018 (GH-5094). (#5105) (cherry picked from commit 65f2a6dcc2bc28a8566b74c8e9273f982331ec48) files: M Doc/copyright.rst M Doc/license.rst M LICENSE M Mac/PythonLauncher/Info.plist.in M Mac/Resources/app/Info.plist.in M Mac/Resources/framework/Info.plist.in M Python/getcopyright.c M README diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 22d7705846e..540ff5ef059 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright ? 2001-2016 Python Software Foundation. All rights reserved. +Copyright ? 2001-2018 Python Software Foundation. All rights reserved. Copyright ? 2000 BeOpen.com. All rights reserved. diff --git a/Doc/license.rst b/Doc/license.rst index 942ad20e47b..f33495ab1ef 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright ? 2001-2017 Python Software Foundation; All Rights + copyright, i.e., "Copyright ? 2001-2018 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/LICENSE b/LICENSE index 529349e4b38..1afbedba92b 100644 --- a/LICENSE +++ b/LICENSE @@ -73,9 +73,9 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights -Reserved" are retained in Python alone or in any derivative version prepared by -Licensee. +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All +Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index 1a8e2b44553..b84fffeec64 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable PythonLauncher CFBundleGetInfoString - %VERSION%, ? 2001-2017 Python Software Foundation + %VERSION%, ? 2001-2018 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index a23166e6d32..abe9ae23e34 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2017 Python Software Foundation. + %version%, (c) 2001-2018 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index 7a64619e295..c1ea9f68892 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Python/getcopyright.c b/Python/getcopyright.c index c37f8fa81cb..1b69012fbc1 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static char cprt[] = "\ -Copyright (c) 2001-2017 Python Software Foundation.\n\ +Copyright (c) 2001-2018 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/README b/README index 00a6b394655..387b437cc29 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ This is Python version 2.7.14 ============================= Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. From solipsis at pitrou.net Fri Jan 5 04:14:17 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Fri, 05 Jan 2018 09:14:17 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=9 Message-ID: <20180105091417.1.18E93BB5250E5A0D@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_asyncio leaked [0, 0, 3] memory blocks, sum=3 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_forkserver leaked [0, 0, 2] memory blocks, sum=2 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogzzquDX', '--timeout', '7200'] From webhook-mailer at python.org Fri Jan 5 05:15:58 2018 From: webhook-mailer at python.org (Antoine Pitrou) Date: Fri, 05 Jan 2018 10:15:58 -0000 Subject: [Python-checkins] bpo-31699 Deadlocks in `concurrent.futures.ProcessPoolExecutor` with pickling error (#3895) Message-ID: https://github.com/python/cpython/commit/94459fd7dc25ce19096f2080eb7339497d319eb0 commit: 94459fd7dc25ce19096f2080eb7339497d319eb0 branch: master author: Thomas Moreau committer: Antoine Pitrou date: 2018-01-05T11:15:54+01:00 summary: bpo-31699 Deadlocks in `concurrent.futures.ProcessPoolExecutor` with pickling error (#3895) Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when task arguments or results cause pickling or unpickling errors. This should make sure that calls to the :class:`ProcessPoolExecutor` API always eventually return. files: A Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst M Lib/concurrent/futures/process.py M Lib/multiprocessing/queues.py M Lib/test/_test_multiprocessing.py M Lib/test/test_concurrent_futures.py diff --git a/Lib/concurrent/futures/process.py b/Lib/concurrent/futures/process.py index 35af65d0bee..aaa5151e017 100644 --- a/Lib/concurrent/futures/process.py +++ b/Lib/concurrent/futures/process.py @@ -8,10 +8,10 @@ |======================= In-process =====================|== Out-of-process ==| +----------+ +----------+ +--------+ +-----------+ +---------+ -| | => | Work Ids | => | | => | Call Q | => | | -| | +----------+ | | +-----------+ | | -| | | ... | | | | ... | | | -| | | 6 | | | | 5, call() | | | +| | => | Work Ids | | | | Call Q | | Process | +| | +----------+ | | +-----------+ | Pool | +| | | ... | | | | ... | +---------+ +| | | 6 | => | | => | 5, call() | => | | | | | 7 | | | | ... | | | | Process | | ... | | Local | +-----------+ | Process | | Pool | +----------+ | Worker | | #1..n | @@ -52,6 +52,7 @@ from queue import Full import multiprocessing as mp from multiprocessing.connection import wait +from multiprocessing.queues import Queue import threading import weakref from functools import partial @@ -72,16 +73,31 @@ # workers to exit when their work queues are empty and then waits until the # threads/processes finish. -_threads_queues = weakref.WeakKeyDictionary() +_threads_wakeups = weakref.WeakKeyDictionary() _global_shutdown = False + +class _ThreadWakeup: + __slot__ = ["_state"] + + def __init__(self): + self._reader, self._writer = mp.Pipe(duplex=False) + + def wakeup(self): + self._writer.send_bytes(b"") + + def clear(self): + while self._reader.poll(): + self._reader.recv_bytes() + + def _python_exit(): global _global_shutdown _global_shutdown = True - items = list(_threads_queues.items()) - for t, q in items: - q.put(None) - for t, q in items: + items = list(_threads_wakeups.items()) + for _, thread_wakeup in items: + thread_wakeup.wakeup() + for t, _ in items: t.join() # Controls how many more calls than processes will be queued in the call queue. @@ -90,6 +106,7 @@ def _python_exit(): # (Futures in the call queue cannot be cancelled). EXTRA_QUEUED_CALLS = 1 + # Hack to embed stringification of remote traceback in local traceback class _RemoteTraceback(Exception): @@ -132,6 +149,25 @@ def __init__(self, work_id, fn, args, kwargs): self.kwargs = kwargs +class _SafeQueue(Queue): + """Safe Queue set exception to the future object linked to a job""" + def __init__(self, max_size=0, *, ctx, pending_work_items): + self.pending_work_items = pending_work_items + super().__init__(max_size, ctx=ctx) + + def _on_queue_feeder_error(self, e, obj): + if isinstance(obj, _CallItem): + tb = traceback.format_exception(type(e), e, e.__traceback__) + e.__cause__ = _RemoteTraceback('\n"""\n{}"""'.format(''.join(tb))) + work_item = self.pending_work_items.pop(obj.work_id, None) + # work_item can be None if another process terminated. In this case, + # the queue_manager_thread fails all work_items with BrokenProcessPool + if work_item is not None: + work_item.future.set_exception(e) + else: + super()._on_queue_feeder_error(e, obj) + + def _get_chunks(*iterables, chunksize): """ Iterates over zip()ed iterables in chunks. """ it = zip(*iterables) @@ -152,6 +188,17 @@ def _process_chunk(fn, chunk): """ return [fn(*args) for args in chunk] + +def _sendback_result(result_queue, work_id, result=None, exception=None): + """Safely send back the given result or exception""" + try: + result_queue.put(_ResultItem(work_id, result=result, + exception=exception)) + except BaseException as e: + exc = _ExceptionWithTraceback(e, e.__traceback__) + result_queue.put(_ResultItem(work_id, exception=exc)) + + def _process_worker(call_queue, result_queue, initializer, initargs): """Evaluates calls from call_queue and places the results in result_queue. @@ -183,10 +230,9 @@ def _process_worker(call_queue, result_queue, initializer, initargs): r = call_item.fn(*call_item.args, **call_item.kwargs) except BaseException as e: exc = _ExceptionWithTraceback(e, e.__traceback__) - result_queue.put(_ResultItem(call_item.work_id, exception=exc)) + _sendback_result(result_queue, call_item.work_id, exception=exc) else: - result_queue.put(_ResultItem(call_item.work_id, - result=r)) + _sendback_result(result_queue, call_item.work_id, result=r) # Liberate the resource as soon as possible, to avoid holding onto # open files or shared memory that is not needed anymore @@ -230,12 +276,14 @@ def _add_call_item_to_queue(pending_work_items, del pending_work_items[work_id] continue + def _queue_management_worker(executor_reference, processes, pending_work_items, work_ids_queue, call_queue, - result_queue): + result_queue, + thread_wakeup): """Manages the communication between this process and the worker processes. This function is run in a local thread. @@ -253,6 +301,9 @@ def _queue_management_worker(executor_reference, derived from _WorkItems for processing by the process workers. result_queue: A ctx.SimpleQueue of _ResultItems generated by the process workers. + thread_wakeup: A _ThreadWakeup to allow waking up the + queue_manager_thread from the main Thread and avoid deadlocks + caused by permanently locked queues. """ executor = None @@ -261,10 +312,21 @@ def shutting_down(): or executor._shutdown_thread) def shutdown_worker(): - # This is an upper bound - nb_children_alive = sum(p.is_alive() for p in processes.values()) - for i in range(0, nb_children_alive): - call_queue.put_nowait(None) + # This is an upper bound on the number of children alive. + n_children_alive = sum(p.is_alive() for p in processes.values()) + n_children_to_stop = n_children_alive + n_sentinels_sent = 0 + # Send the right number of sentinels, to make sure all children are + # properly terminated. + while n_sentinels_sent < n_children_to_stop and n_children_alive > 0: + for i in range(n_children_to_stop - n_sentinels_sent): + try: + call_queue.put_nowait(None) + n_sentinels_sent += 1 + except Full: + break + n_children_alive = sum(p.is_alive() for p in processes.values()) + # Release the queue's resources as soon as possible. call_queue.close() # If .join() is not called on the created processes then @@ -272,19 +334,37 @@ def shutdown_worker(): for p in processes.values(): p.join() - reader = result_queue._reader + result_reader = result_queue._reader + wakeup_reader = thread_wakeup._reader + readers = [result_reader, wakeup_reader] while True: _add_call_item_to_queue(pending_work_items, work_ids_queue, call_queue) - sentinels = [p.sentinel for p in processes.values()] - assert sentinels - ready = wait([reader] + sentinels) - if reader in ready: - result_item = reader.recv() - else: + # Wait for a result to be ready in the result_queue while checking + # that all worker processes are still running, or for a wake up + # signal send. The wake up signals come either from new tasks being + # submitted, from the executor being shutdown/gc-ed, or from the + # shutdown of the python interpreter. + worker_sentinels = [p.sentinel for p in processes.values()] + ready = wait(readers + worker_sentinels) + + cause = None + is_broken = True + if result_reader in ready: + try: + result_item = result_reader.recv() + is_broken = False + except BaseException as e: + cause = traceback.format_exception(type(e), e, e.__traceback__) + + elif wakeup_reader in ready: + is_broken = False + result_item = None + thread_wakeup.clear() + if is_broken: # Mark the process pool broken so that submits fail right now. executor = executor_reference() if executor is not None: @@ -293,14 +373,15 @@ def shutdown_worker(): 'usable anymore') executor._shutdown_thread = True executor = None + bpe = BrokenProcessPool("A process in the process pool was " + "terminated abruptly while the future was " + "running or pending.") + if cause is not None: + bpe.__cause__ = _RemoteTraceback( + f"\n'''\n{''.join(cause)}'''") # All futures in flight must be marked failed for work_id, work_item in pending_work_items.items(): - work_item.future.set_exception( - BrokenProcessPool( - "A process in the process pool was " - "terminated abruptly while the future was " - "running or pending." - )) + work_item.future.set_exception(bpe) # Delete references to object. See issue16284 del work_item pending_work_items.clear() @@ -329,6 +410,9 @@ def shutdown_worker(): work_item.future.set_result(result_item.result) # Delete references to object. See issue16284 del work_item + # Delete reference to result_item + del result_item + # Check whether we should start shutting down. executor = executor_reference() # No more work items can be added if: @@ -348,8 +432,11 @@ def shutdown_worker(): pass executor = None + _system_limits_checked = False _system_limited = None + + def _check_system_limits(): global _system_limits_checked, _system_limited if _system_limits_checked: @@ -369,7 +456,8 @@ def _check_system_limits(): # minimum number of semaphores available # according to POSIX return - _system_limited = "system provides too few semaphores (%d available, 256 necessary)" % nsems_max + _system_limited = ("system provides too few semaphores (%d" + " available, 256 necessary)" % nsems_max) raise NotImplementedError(_system_limited) @@ -415,6 +503,7 @@ def __init__(self, max_workers=None, mp_context=None, raise ValueError("max_workers must be greater than 0") self._max_workers = max_workers + if mp_context is None: mp_context = mp.get_context() self._mp_context = mp_context @@ -424,34 +513,52 @@ def __init__(self, max_workers=None, mp_context=None, self._initializer = initializer self._initargs = initargs + # Management thread + self._queue_management_thread = None + + # Map of pids to processes + self._processes = {} + + # Shutdown is a two-step process. + self._shutdown_thread = False + self._shutdown_lock = threading.Lock() + self._broken = False + self._queue_count = 0 + self._pending_work_items = {} + + # Create communication channels for the executor # Make the call queue slightly larger than the number of processes to # prevent the worker processes from idling. But don't make it too big # because futures in the call queue cannot be cancelled. queue_size = self._max_workers + EXTRA_QUEUED_CALLS - self._call_queue = mp_context.Queue(queue_size) + self._call_queue = _SafeQueue( + max_size=queue_size, ctx=self._mp_context, + pending_work_items=self._pending_work_items) # Killed worker processes can produce spurious "broken pipe" # tracebacks in the queue's own worker thread. But we detect killed # processes anyway, so silence the tracebacks. self._call_queue._ignore_epipe = True self._result_queue = mp_context.SimpleQueue() self._work_ids = queue.Queue() - self._queue_management_thread = None - # Map of pids to processes - self._processes = {} - # Shutdown is a two-step process. - self._shutdown_thread = False - self._shutdown_lock = threading.Lock() - self._broken = False - self._queue_count = 0 - self._pending_work_items = {} + # _ThreadWakeup is a communication channel used to interrupt the wait + # of the main loop of queue_manager_thread from another thread (e.g. + # when calling executor.submit or executor.shutdown). We do not use the + # _result_queue to send the wakeup signal to the queue_manager_thread + # as it could result in a deadlock if a worker process dies with the + # _result_queue write lock still acquired. + self._queue_management_thread_wakeup = _ThreadWakeup() def _start_queue_management_thread(self): - # When the executor gets lost, the weakref callback will wake up - # the queue management thread. - def weakref_cb(_, q=self._result_queue): - q.put(None) if self._queue_management_thread is None: + # When the executor gets garbarge collected, the weakref callback + # will wake up the queue management thread so that it can terminate + # if there is no pending work item. + def weakref_cb(_, + thread_wakeup=self._queue_management_thread_wakeup): + mp.util.debug('Executor collected: triggering callback for' + ' QueueManager wakeup') + thread_wakeup.wakeup() # Start the processes so that their sentinels are known. self._adjust_process_count() self._queue_management_thread = threading.Thread( @@ -461,10 +568,13 @@ def weakref_cb(_, q=self._result_queue): self._pending_work_items, self._work_ids, self._call_queue, - self._result_queue)) + self._result_queue, + self._queue_management_thread_wakeup), + name="QueueManagerThread") self._queue_management_thread.daemon = True self._queue_management_thread.start() - _threads_queues[self._queue_management_thread] = self._result_queue + _threads_wakeups[self._queue_management_thread] = \ + self._queue_management_thread_wakeup def _adjust_process_count(self): for _ in range(len(self._processes), self._max_workers): @@ -491,7 +601,7 @@ def submit(self, fn, *args, **kwargs): self._work_ids.put(self._queue_count) self._queue_count += 1 # Wake up queue management thread - self._result_queue.put(None) + self._queue_management_thread_wakeup.wakeup() self._start_queue_management_thread() return f @@ -531,7 +641,7 @@ def shutdown(self, wait=True): self._shutdown_thread = True if self._queue_management_thread: # Wake up queue management thread - self._result_queue.put(None) + self._queue_management_thread_wakeup.wakeup() if wait: self._queue_management_thread.join() # To reduce the risk of opening too many files, remove references to diff --git a/Lib/multiprocessing/queues.py b/Lib/multiprocessing/queues.py index 328efbd95fe..d66d37a5c3e 100644 --- a/Lib/multiprocessing/queues.py +++ b/Lib/multiprocessing/queues.py @@ -160,9 +160,10 @@ def _start_thread(self): self._thread = threading.Thread( target=Queue._feed, args=(self._buffer, self._notempty, self._send_bytes, - self._wlock, self._writer.close, self._ignore_epipe), + self._wlock, self._writer.close, self._ignore_epipe, + self._on_queue_feeder_error), name='QueueFeederThread' - ) + ) self._thread.daemon = True debug('doing self._thread.start()') @@ -201,7 +202,8 @@ def _finalize_close(buffer, notempty): notempty.notify() @staticmethod - def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): + def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe, + onerror): debug('starting thread to feed data to pipe') nacquire = notempty.acquire nrelease = notempty.release @@ -253,8 +255,17 @@ def _feed(buffer, notempty, send_bytes, writelock, close, ignore_epipe): info('error in queue thread: %s', e) return else: - import traceback - traceback.print_exc() + onerror(e, obj) + + @staticmethod + def _on_queue_feeder_error(e, obj): + """ + Private API hook called when feeding data in the background thread + raises an exception. For overriding by concurrent.futures. + """ + import traceback + traceback.print_exc() + _sentinel = object() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index 7575c5d3681..05166b91ba8 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -1029,6 +1029,43 @@ def __reduce__(self): self.assertTrue(q.get(timeout=1.0)) close_queue(q) + def test_queue_feeder_on_queue_feeder_error(self): + # bpo-30006: verify feeder handles exceptions using the + # _on_queue_feeder_error hook. + if self.TYPE != 'processes': + self.skipTest('test not appropriate for {}'.format(self.TYPE)) + + class NotSerializable(object): + """Mock unserializable object""" + def __init__(self): + self.reduce_was_called = False + self.on_queue_feeder_error_was_called = False + + def __reduce__(self): + self.reduce_was_called = True + raise AttributeError + + class SafeQueue(multiprocessing.queues.Queue): + """Queue with overloaded _on_queue_feeder_error hook""" + @staticmethod + def _on_queue_feeder_error(e, obj): + if (isinstance(e, AttributeError) and + isinstance(obj, NotSerializable)): + obj.on_queue_feeder_error_was_called = True + + not_serializable_obj = NotSerializable() + # The captured_stderr reduces the noise in the test report + with test.support.captured_stderr(): + q = SafeQueue(ctx=multiprocessing.get_context()) + q.put(not_serializable_obj) + + # Verify that q is still functionning correctly + q.put(True) + self.assertTrue(q.get(timeout=1.0)) + + # Assert that the serialization and the hook have been called correctly + self.assertTrue(not_serializable_obj.reduce_was_called) + self.assertTrue(not_serializable_obj.on_queue_feeder_error_was_called) # # # diff --git a/Lib/test/test_concurrent_futures.py b/Lib/test/test_concurrent_futures.py index 76878992f9a..675cd7ae05e 100644 --- a/Lib/test/test_concurrent_futures.py +++ b/Lib/test/test_concurrent_futures.py @@ -18,6 +18,7 @@ import time import unittest import weakref +from pickle import PicklingError from concurrent import futures from concurrent.futures._base import ( @@ -394,16 +395,17 @@ def test_del_shutdown(self): queue_management_thread = executor._queue_management_thread processes = executor._processes call_queue = executor._call_queue + queue_management_thread = executor._queue_management_thread del executor + # Make sure that all the executor ressources were properly cleaned by + # the shutdown process queue_management_thread.join() for p in processes.values(): p.join() - call_queue.close() call_queue.join_thread() - create_executor_tests(ProcessPoolShutdownTest, executor_mixins=(ProcessPoolForkMixin, ProcessPoolForkserverMixin, @@ -784,6 +786,172 @@ def test_ressources_gced_in_workers(self): ProcessPoolForkserverMixin, ProcessPoolSpawnMixin)) +def hide_process_stderr(): + import io + sys.stderr = io.StringIO() + + +def _crash(delay=None): + """Induces a segfault.""" + if delay: + time.sleep(delay) + import faulthandler + faulthandler.disable() + faulthandler._sigsegv() + + +def _exit(): + """Induces a sys exit with exitcode 1.""" + sys.exit(1) + + +def _raise_error(Err): + """Function that raises an Exception in process.""" + hide_process_stderr() + raise Err() + + +def _return_instance(cls): + """Function that returns a instance of cls.""" + hide_process_stderr() + return cls() + + +class CrashAtPickle(object): + """Bad object that triggers a segfault at pickling time.""" + def __reduce__(self): + _crash() + + +class CrashAtUnpickle(object): + """Bad object that triggers a segfault at unpickling time.""" + def __reduce__(self): + return _crash, () + + +class ExitAtPickle(object): + """Bad object that triggers a process exit at pickling time.""" + def __reduce__(self): + _exit() + + +class ExitAtUnpickle(object): + """Bad object that triggers a process exit at unpickling time.""" + def __reduce__(self): + return _exit, () + + +class ErrorAtPickle(object): + """Bad object that triggers an error at pickling time.""" + def __reduce__(self): + from pickle import PicklingError + raise PicklingError("Error in pickle") + + +class ErrorAtUnpickle(object): + """Bad object that triggers an error at unpickling time.""" + def __reduce__(self): + from pickle import UnpicklingError + return _raise_error, (UnpicklingError, ) + + +class ExecutorDeadlockTest: + TIMEOUT = 15 + + @classmethod + def _sleep_id(cls, x, delay): + time.sleep(delay) + return x + + def _fail_on_deadlock(self, executor): + # If we did not recover before TIMEOUT seconds, consider that the + # executor is in a deadlock state and forcefully clean all its + # composants. + import faulthandler + from tempfile import TemporaryFile + with TemporaryFile(mode="w+") as f: + faulthandler.dump_traceback(file=f) + f.seek(0) + tb = f.read() + for p in executor._processes.values(): + p.terminate() + # This should be safe to call executor.shutdown here as all possible + # deadlocks should have been broken. + executor.shutdown(wait=True) + print(f"\nTraceback:\n {tb}", file=sys.__stderr__) + self.fail(f"Executor deadlock:\n\n{tb}") + + + def test_crash(self): + # extensive testing for deadlock caused by crashes in a pool. + self.executor.shutdown(wait=True) + crash_cases = [ + # Check problem occuring while pickling a task in + # the task_handler thread + (id, (ErrorAtPickle(),), PicklingError, "error at task pickle"), + # Check problem occuring while unpickling a task on workers + (id, (ExitAtUnpickle(),), BrokenProcessPool, + "exit at task unpickle"), + (id, (ErrorAtUnpickle(),), BrokenProcessPool, + "error at task unpickle"), + (id, (CrashAtUnpickle(),), BrokenProcessPool, + "crash at task unpickle"), + # Check problem occuring during func execution on workers + (_crash, (), BrokenProcessPool, + "crash during func execution on worker"), + (_exit, (), SystemExit, + "exit during func execution on worker"), + (_raise_error, (RuntimeError, ), RuntimeError, + "error during func execution on worker"), + # Check problem occuring while pickling a task result + # on workers + (_return_instance, (CrashAtPickle,), BrokenProcessPool, + "crash during result pickle on worker"), + (_return_instance, (ExitAtPickle,), SystemExit, + "exit during result pickle on worker"), + (_return_instance, (ErrorAtPickle,), PicklingError, + "error during result pickle on worker"), + # Check problem occuring while unpickling a task in + # the result_handler thread + (_return_instance, (ErrorAtUnpickle,), BrokenProcessPool, + "error during result unpickle in result_handler"), + (_return_instance, (ExitAtUnpickle,), BrokenProcessPool, + "exit during result unpickle in result_handler") + ] + for func, args, error, name in crash_cases: + with self.subTest(name): + # The captured_stderr reduces the noise in the test report + with test.support.captured_stderr(): + executor = self.executor_type( + max_workers=2, mp_context=get_context(self.ctx)) + res = executor.submit(func, *args) + with self.assertRaises(error): + try: + res.result(timeout=self.TIMEOUT) + except futures.TimeoutError: + # If we did not recover before TIMEOUT seconds, + # consider that the executor is in a deadlock state + self._fail_on_deadlock(executor) + executor.shutdown(wait=True) + + def test_shutdown_deadlock(self): + # Test that the pool calling shutdown do not cause deadlock + # if a worker fails after the shutdown call. + self.executor.shutdown(wait=True) + with self.executor_type(max_workers=2, + mp_context=get_context(self.ctx)) as executor: + self.executor = executor # Allow clean up in fail_on_deadlock + f = executor.submit(_crash, delay=.1) + executor.shutdown(wait=True) + with self.assertRaises(BrokenProcessPool): + f.result() + + +create_executor_tests(ExecutorDeadlockTest, + executor_mixins=(ProcessPoolForkMixin, + ProcessPoolForkserverMixin, + ProcessPoolSpawnMixin)) + class FutureTests(BaseTestCase): def test_done_callback_with_result(self): diff --git a/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst b/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst new file mode 100644 index 00000000000..49cbbb3b920 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst @@ -0,0 +1,4 @@ +Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when +task arguments or results cause pickling or unpickling errors. +This should make sure that calls to the :class:`ProcessPoolExecutor` API +always eventually return. From webhook-mailer at python.org Fri Jan 5 07:02:05 2018 From: webhook-mailer at python.org (xdegaye) Date: Fri, 05 Jan 2018 12:02:05 -0000 Subject: [Python-checkins] bpo-32390: Fix compilation failure on AIX after f_fsid was added to os.statvfs() (#4972) Message-ID: https://github.com/python/cpython/commit/502d551c6d782963d26957a9e5ff1588946f233f commit: 502d551c6d782963d26957a9e5ff1588946f233f branch: master author: Michael Felt committer: xdegaye date: 2018-01-05T13:01:58+01:00 summary: bpo-32390: Fix compilation failure on AIX after f_fsid was added to os.statvfs() (#4972) files: A Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst M Modules/posixmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst new file mode 100644 index 00000000000..0e9c1bff540 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst @@ -0,0 +1 @@ +Fix the compilation failure on AIX after the f_fsid field has been added to the object returned by os.statvfs() (issue #32143). Original patch by Michael Felt. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 47b79fcc798..b0e48dabbd5 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -9336,7 +9336,13 @@ _pystatvfs_fromstructstatvfs(struct statvfs st) { PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag)); PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax)); #endif +/* The _ALL_SOURCE feature test macro defines f_fsid as a structure + * (issue #32390). */ +#if defined(_AIX) && defined(_ALL_SOURCE) + PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid.val[0])); +#else PyStructSequence_SET_ITEM(v, 10, PyLong_FromUnsignedLong(st.f_fsid)); +#endif if (PyErr_Occurred()) { Py_DECREF(v); return NULL; From lp_benchmark_robot at intel.com Fri Jan 5 19:21:56 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Fri, 5 Jan 2018 16:21:56 -0800 Subject: [Python-checkins] [65 flat] Results for Python (master branch) 2018-01-05 Message-ID: <51d53f93-fbbd-4b69-a4b4-50d75f9b9ec9@orsmsx102.amr.corp.intel.com> Results for project python/master, build date: 2018-01-05 03:04:11-08:00. - commit: 94459fd - previous commit: 78e24d4 - revision date: 2018-01-05 11:15:54+01:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.864% | -1.048% | +7.068% | +7.453% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 0.637% | -1.039% | +21.662% | +11.220% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 0.371% | -1.213% | +23.821% | +9.994% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 0.450% | -1.248% | +21.403% | +9.771% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.279% | -1.787% | +7.706% | +13.773% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.758% | -0.181% | +9.314% | +12.805% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 1.560% | -1.177% | +4.821% | +12.284% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.716% | +0.006% | -0.718% | +8.480% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 2.442% | -2.020% | +9.631% | +17.588% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 2.758% | -1.983% | +12.224% | +15.307% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.234% | -0.081% | +3.339% | +6.863% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.666% | -0.021% | +4.655% | +5.399% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 0.697% | +0.221% | +2.602% | +7.150% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.180% | -0.216% | +12.043% | +11.046% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.396% | +1.045% | +8.979% | +10.103% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 0.933% | +0.173% | +6.379% | +11.780% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 1.287% | -0.586% | +9.973% | +11.274% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 3.763% | -0.993% | +6.239% | +11.801% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.987% | +0.726% | +2.872% | +10.298% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 1.232% | -0.382% | -0.566% | +13.569% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.543% | +0.474% | +8.504% | +10.989% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.740% | -0.629% | +46.843% | +12.828% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.657% | +0.213% | +9.415% | +12.412% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.802% | +0.371% | +17.429% | +13.394% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 2.885% | -0.002% | +11.730% | +6.939% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 1.807% | -1.723% | +2.417% | +6.687% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.795% | -1.184% | -5.068% | +5.783% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 2.168% | +0.020% | +4.328% | +8.456% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.338% | +0.315% | +1.034% | +12.977% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle| 1.138% | -0.351% | +0.929% | +19.859% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_dict| 0.551% | -0.350% | +1.728% | +20.824% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 0.677% | -0.266% | +3.487% | +21.061% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 1.090% | +0.907% | +12.046% | +10.328% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.252% | +0.041% | -0.039% | +10.884% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.143% | +0.038% | +10.729% | +5.242% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.115% | +0.039% | +2.063% | +5.290% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.782% | -0.145% | +10.305% | +13.857% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 5.997% | -3.427% | +1.418% | +13.637% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.533% | +1.468% | -0.985% | +9.388% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 2.198% | +1.173% | -4.058% | +1.978% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 2.424% | +1.405% | +5.133% | +4.866% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.219% | -0.091% | +8.727% | +14.729% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.843% | -0.576% | -3.083% | +5.794% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 1.655% | -1.013% | +25.971% | +10.630% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.279% | +0.715% | +4.874% | +6.938% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 0.303% | +0.081% | +14.374% | +9.510% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 1.143% | -2.008% | -5.470% | -0.788% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.401% | +0.660% | +5.978% | +2.501% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.146% | -1.150% | +6.143% | +8.080% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.589% | -2.078% | +5.223% | +6.500% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 6.116% | -1.086% | +18.443% | +10.180% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 2.945% | -1.420% | +11.129% | +7.136% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 2.250% | -0.612% | +8.325% | +8.001% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 4.463% | -0.862% | +11.475% | +9.276% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 5.670% | +1.937% | +11.079% | +9.735% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 2.877% | +0.285% | +19.522% | +11.200% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 1.235% | -0.272% | +6.069% | +7.393% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 7.344% | -0.834% | +1.532% | +1.665% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 5.504% | -0.252% | +6.512% | +22.397% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 2.451% | -1.121% | -4.920% | +19.375% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 1.619% | +0.054% | +8.572% | +7.640% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.234% | -0.707% | +1.470% | +12.707% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 1.840% | -0.598% | +2.949% | +8.183% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 3.556% | +0.091% | -8.284% | +13.168% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.287% | -0.482% | +3.955% | +12.228% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/65-flat-results-for-python-master-branch-2018-01-05 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 webhook-mailer at python.org Sat Jan 6 02:12:17 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Sat, 06 Jan 2018 07:12:17 -0000 Subject: [Python-checkins] advance copyright years to 2018 (GH-5094) (#5104) Message-ID: https://github.com/python/cpython/commit/e29573910c2c442c39def7396b7a54ae1487e686 commit: e29573910c2c442c39def7396b7a54ae1487e686 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Benjamin Peterson date: 2018-01-05T23:12:14-08:00 summary: advance copyright years to 2018 (GH-5094) (#5104) (cherry picked from commit 65f2a6dcc2bc28a8566b74c8e9273f982331ec48) files: M Doc/copyright.rst M Doc/license.rst M LICENSE M Mac/IDLE/IDLE.app/Contents/Info.plist M Mac/PythonLauncher/Info.plist.in M Mac/Resources/app/Info.plist.in M Mac/Resources/framework/Info.plist.in M Python/getcopyright.c M README.rst diff --git a/Doc/copyright.rst b/Doc/copyright.rst index 2b5400cd9fb..540ff5ef059 100644 --- a/Doc/copyright.rst +++ b/Doc/copyright.rst @@ -4,7 +4,7 @@ Copyright Python and this documentation is: -Copyright ? 2001-2017 Python Software Foundation. All rights reserved. +Copyright ? 2001-2018 Python Software Foundation. All rights reserved. Copyright ? 2000 BeOpen.com. All rights reserved. diff --git a/Doc/license.rst b/Doc/license.rst index 49d29cee314..e8dbeb1ef28 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -87,7 +87,7 @@ PSF LICENSE AGREEMENT FOR PYTHON |release| analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python |release| alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of - copyright, i.e., "Copyright ? 2001-2017 Python Software Foundation; All Rights + copyright, i.e., "Copyright ? 2001-2018 Python Software Foundation; All Rights Reserved" are retained in Python |release| alone or in any derivative version prepared by Licensee. diff --git a/LICENSE b/LICENSE index 529349e4b38..1afbedba92b 100644 --- a/LICENSE +++ b/LICENSE @@ -73,9 +73,9 @@ analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, -2011, 2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation; All Rights -Reserved" are retained in Python alone or in any derivative version prepared by -Licensee. +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation; All +Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make diff --git a/Mac/IDLE/IDLE.app/Contents/Info.plist b/Mac/IDLE/IDLE.app/Contents/Info.plist index 5507687e90e..826d3793f75 100644 --- a/Mac/IDLE/IDLE.app/Contents/Info.plist +++ b/Mac/IDLE/IDLE.app/Contents/Info.plist @@ -36,7 +36,7 @@ CFBundleExecutable IDLE CFBundleGetInfoString - %version%, ? 2001-2017 Python Software Foundation + %version%, ? 2001-2018 Python Software Foundation CFBundleIconFile IDLE.icns CFBundleIdentifier diff --git a/Mac/PythonLauncher/Info.plist.in b/Mac/PythonLauncher/Info.plist.in index f1ab79f3d44..5fa346ed4d3 100644 --- a/Mac/PythonLauncher/Info.plist.in +++ b/Mac/PythonLauncher/Info.plist.in @@ -40,7 +40,7 @@ CFBundleExecutable Python Launcher CFBundleGetInfoString - %VERSION%, ? 2001-2017 Python Software Foundation + %VERSION%, ? 2001-2018 Python Software Foundation CFBundleIconFile PythonLauncher.icns CFBundleIdentifier diff --git a/Mac/Resources/app/Info.plist.in b/Mac/Resources/app/Info.plist.in index a23166e6d32..abe9ae23e34 100644 --- a/Mac/Resources/app/Info.plist.in +++ b/Mac/Resources/app/Info.plist.in @@ -37,7 +37,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - %version%, (c) 2001-2017 Python Software Foundation. + %version%, (c) 2001-2018 Python Software Foundation. CFBundleName Python CFBundlePackageType diff --git a/Mac/Resources/framework/Info.plist.in b/Mac/Resources/framework/Info.plist.in index 7a64619e295..c1ea9f68892 100644 --- a/Mac/Resources/framework/Info.plist.in +++ b/Mac/Resources/framework/Info.plist.in @@ -17,9 +17,9 @@ CFBundlePackageType FMWK CFBundleShortVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleLongVersionString - %VERSION%, (c) 2001-2017 Python Software Foundation. + %VERSION%, (c) 2001-2018 Python Software Foundation. CFBundleSignature ???? CFBundleVersion diff --git a/Python/getcopyright.c b/Python/getcopyright.c index cac647c3ce4..51772ecef31 100644 --- a/Python/getcopyright.c +++ b/Python/getcopyright.c @@ -4,7 +4,7 @@ static const char cprt[] = "\ -Copyright (c) 2001-2017 Python Software Foundation.\n\ +Copyright (c) 2001-2018 Python Software Foundation.\n\ All Rights Reserved.\n\ \n\ Copyright (c) 2000 BeOpen.com.\n\ diff --git a/README.rst b/README.rst index 05c31da8f2a..30e694e6462 100644 --- a/README.rst +++ b/README.rst @@ -14,7 +14,7 @@ This is Python version 3.6.4 :target: https://codecov.io/gh/python/cpython Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. See the end of this file for further copyright and license information. @@ -232,7 +232,7 @@ Copyright and License Information --------------------------------- Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, -2012, 2013, 2014, 2015, 2016, 2017 Python Software Foundation. All rights +2012, 2013, 2014, 2015, 2016, 2017, 2018 Python Software Foundation. All rights reserved. Copyright (c) 2000 BeOpen.com. All rights reserved. From webhook-mailer at python.org Sat Jan 6 02:15:37 2018 From: webhook-mailer at python.org (Benjamin Peterson) Date: Sat, 06 Jan 2018 07:15:37 -0000 Subject: [Python-checkins] bpo-29137: Remove fpectl module (#4789) Message-ID: https://github.com/python/cpython/commit/735ae8d139a673b30b321dc10acfd3d14f0d633b commit: 735ae8d139a673b30b321dc10acfd3d14f0d633b branch: master author: Nathaniel J. Smith committer: Benjamin Peterson date: 2018-01-05T23:15:34-08:00 summary: bpo-29137: Remove fpectl module (#4789) This module has never been enabled by default, never worked correctly on x86-64, and caused ABI problems that caused C extension compatibility. See bpo-29137 for details/discussion. files: A Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst D Doc/library/fpectl.rst D Modules/fpectlmodule.c D Modules/fpetestmodule.c M Doc/library/exceptions.rst M Doc/library/python.rst M Doc/license.rst M Include/pyfpe.h M Modules/Setup.dist M Python/pyfpe.c M aclocal.m4 M configure M configure.ac M pyconfig.h.in diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index a6b20a5ac95..c8d32cff4e0 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -154,10 +154,7 @@ The following exceptions are the exceptions that are usually raised. .. exception:: FloatingPointError - Raised when a floating point operation fails. This exception is always defined, - but can only be raised when Python is configured with the - ``--with-fpectl`` option, or the :const:`WANT_SIGFPE_HANDLER` symbol is - defined in the :file:`pyconfig.h` file. + Not currently used. .. exception:: GeneratorExit diff --git a/Doc/library/fpectl.rst b/Doc/library/fpectl.rst deleted file mode 100644 index 96607165ba4..00000000000 --- a/Doc/library/fpectl.rst +++ /dev/null @@ -1,121 +0,0 @@ -:mod:`fpectl` --- Floating point exception control -================================================== - -.. module:: fpectl - :platform: Unix - :synopsis: Provide control for floating point exception handling. - -.. moduleauthor:: Lee Busby -.. sectionauthor:: Lee Busby - -.. note:: - - The :mod:`fpectl` module is not built by default, and its usage is discouraged - and may be dangerous except in the hands of experts. See also the section - :ref:`fpectl-limitations` on limitations for more details. - -.. index:: single: IEEE-754 - --------------- - -Most computers carry out floating point operations in conformance with the -so-called IEEE-754 standard. On any real computer, some floating point -operations produce results that cannot be expressed as a normal floating point -value. For example, try :: - - >>> import math - >>> math.exp(1000) - inf - >>> math.exp(1000) / math.exp(1000) - nan - -(The example above will work on many platforms. DEC Alpha may be one exception.) -"Inf" is a special, non-numeric value in IEEE-754 that stands for "infinity", -and "nan" means "not a number." Note that, other than the non-numeric results, -nothing special happened when you asked Python to carry out those calculations. -That is in fact the default behaviour prescribed in the IEEE-754 standard, and -if it works for you, stop reading now. - -In some circumstances, it would be better to raise an exception and stop -processing at the point where the faulty operation was attempted. The -:mod:`fpectl` module is for use in that situation. It provides control over -floating point units from several hardware manufacturers, allowing the user to -turn on the generation of :const:`SIGFPE` whenever any of the IEEE-754 -exceptions Division by Zero, Overflow, or Invalid Operation occurs. In tandem -with a pair of wrapper macros that are inserted into the C code comprising your -python system, :const:`SIGFPE` is trapped and converted into the Python -:exc:`FloatingPointError` exception. - -The :mod:`fpectl` module defines the following functions and may raise the given -exception: - - -.. function:: turnon_sigfpe() - - Turn on the generation of :const:`SIGFPE`, and set up an appropriate signal - handler. - - -.. function:: turnoff_sigfpe() - - Reset default handling of floating point exceptions. - - -.. exception:: FloatingPointError - - After :func:`turnon_sigfpe` has been executed, a floating point operation that - raises one of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid - operation will in turn raise this standard Python exception. - - -.. _fpectl-example: - -Example -------- - -The following example demonstrates how to start up and test operation of the -:mod:`fpectl` module. :: - - >>> import fpectl - >>> import fpetest - >>> fpectl.turnon_sigfpe() - >>> fpetest.test() - overflow PASS - FloatingPointError: Overflow - - div by 0 PASS - FloatingPointError: Division by zero - [ more output from test elided ] - >>> import math - >>> math.exp(1000) - Traceback (most recent call last): - File "", line 1, in - FloatingPointError: in math_1 - - -.. _fpectl-limitations: - -Limitations and other considerations ------------------------------------- - -Setting up a given processor to trap IEEE-754 floating point errors currently -requires custom code on a per-architecture basis. You may have to modify -:mod:`fpectl` to control your particular hardware. - -Conversion of an IEEE-754 exception to a Python exception requires that the -wrapper macros ``PyFPE_START_PROTECT`` and ``PyFPE_END_PROTECT`` be inserted -into your code in an appropriate fashion. Python itself has been modified to -support the :mod:`fpectl` module, but many other codes of interest to numerical -analysts have not. - -The :mod:`fpectl` module is not thread-safe. - - -.. seealso:: - - Some files in the source distribution may be interesting in learning more about - how this module operates. The include file :file:`Include/pyfpe.h` discusses the - implementation of this module at some length. :file:`Modules/fpetestmodule.c` - gives several examples of use. Many additional examples can be found in - :file:`Objects/floatobject.c`. - diff --git a/Doc/library/python.rst b/Doc/library/python.rst index f307d7db6db..440dc6632b8 100644 --- a/Doc/library/python.rst +++ b/Doc/library/python.rst @@ -24,4 +24,3 @@ overview: gc.rst inspect.rst site.rst - fpectl.rst diff --git a/Doc/license.rst b/Doc/license.rst index aa4b1450e91..5f78240002f 100644 --- a/Doc/license.rst +++ b/Doc/license.rst @@ -349,48 +349,6 @@ Project, http://www.wide.ad.jp/. :: SUCH DAMAGE. -Floating point exception control --------------------------------- - -The source for the :mod:`fpectl` module includes the following notice:: - - --------------------------------------------------------------------- - / Copyright (c) 1996. \ - | The Regents of the University of California. | - | All rights reserved. | - | | - | Permission to use, copy, modify, and distribute this software for | - | any purpose without fee is hereby granted, provided that this en- | - | tire notice is included in all copies of any software which is or | - | includes a copy or modification of this software and in all | - | copies of the supporting documentation for such software. | - | | - | This work was produced at the University of California, Lawrence | - | Livermore National Laboratory under contract no. W-7405-ENG-48 | - | between the U.S. Department of Energy and The Regents of the | - | University of California for the operation of UC LLNL. | - | | - | DISCLAIMER | - | | - | This software was prepared as an account of work sponsored by an | - | agency of the United States Government. Neither the United States | - | Government nor the University of California nor any of their em- | - | ployees, makes any warranty, express or implied, or assumes any | - | liability or responsibility for the accuracy, completeness, or | - | usefulness of any information, apparatus, product, or process | - | disclosed, or represents that its use would not infringe | - | privately-owned rights. Reference herein to any specific commer- | - | cial products, process, or service by trade name, trademark, | - | manufacturer, or otherwise, does not necessarily constitute or | - | imply its endorsement, recommendation, or favoring by the United | - | States Government or the University of California. The views and | - | opinions of authors expressed herein do not necessarily state or | - | reflect those of the United States Government or the University | - | of California, and shall not be used for advertising or product | - \ endorsement purposes. / - --------------------------------------------------------------------- - - Asynchronous socket services ---------------------------- diff --git a/Include/pyfpe.h b/Include/pyfpe.h index d86cb7486ce..5a99e397931 100644 --- a/Include/pyfpe.h +++ b/Include/pyfpe.h @@ -1,176 +1,12 @@ #ifndef Py_PYFPE_H #define Py_PYFPE_H -#ifdef __cplusplus -extern "C" { -#endif -/* - --------------------------------------------------------------------- - / Copyright (c) 1996. \ - | The Regents of the University of California. | - | All rights reserved. | - | | - | Permission to use, copy, modify, and distribute this software for | - | any purpose without fee is hereby granted, provided that this en- | - | tire notice is included in all copies of any software which is or | - | includes a copy or modification of this software and in all | - | copies of the supporting documentation for such software. | - | | - | This work was produced at the University of California, Lawrence | - | Livermore National Laboratory under contract no. W-7405-ENG-48 | - | between the U.S. Department of Energy and The Regents of the | - | University of California for the operation of UC LLNL. | - | | - | DISCLAIMER | - | | - | This software was prepared as an account of work sponsored by an | - | agency of the United States Government. Neither the United States | - | Government nor the University of California nor any of their em- | - | ployees, makes any warranty, express or implied, or assumes any | - | liability or responsibility for the accuracy, completeness, or | - | usefulness of any information, apparatus, product, or process | - | disclosed, or represents that its use would not infringe | - | privately-owned rights. Reference herein to any specific commer- | - | cial products, process, or service by trade name, trademark, | - | manufacturer, or otherwise, does not necessarily constitute or | - | imply its endorsement, recommendation, or favoring by the United | - | States Government or the University of California. The views and | - | opinions of authors expressed herein do not necessarily state or | - | reflect those of the United States Government or the University | - | of California, and shall not be used for advertising or product | - \ endorsement purposes. / - --------------------------------------------------------------------- -*/ -/* - * Define macros for handling SIGFPE. - * Lee Busby, LLNL, November, 1996 - * busby1 at llnl.gov - * - ********************************************* - * Overview of the system for handling SIGFPE: - * - * This file (Include/pyfpe.h) defines a couple of "wrapper" macros for - * insertion into your Python C code of choice. Their proper use is - * discussed below. The file Python/pyfpe.c defines a pair of global - * variables PyFPE_jbuf and PyFPE_counter which are used by the signal - * handler for SIGFPE to decide if a particular exception was protected - * by the macros. The signal handler itself, and code for enabling the - * generation of SIGFPE in the first place, is in a (new) Python module - * named fpectl. This module is standard in every respect. It can be loaded - * either statically or dynamically as you choose, and like any other - * Python module, has no effect until you import it. - * - * In the general case, there are three steps toward handling SIGFPE in any - * Python code: - * - * 1) Add the *_PROTECT macros to your C code as required to protect - * dangerous floating point sections. - * - * 2) Turn on the inclusion of the code by adding the ``--with-fpectl'' - * flag at the time you run configure. If the fpectl or other modules - * which use the *_PROTECT macros are to be dynamically loaded, be - * sure they are compiled with WANT_SIGFPE_HANDLER defined. - * - * 3) When python is built and running, import fpectl, and execute - * fpectl.turnon_sigfpe(). This sets up the signal handler and enables - * generation of SIGFPE whenever an exception occurs. From this point - * on, any properly trapped SIGFPE should result in the Python - * FloatingPointError exception. - * - * Step 1 has been done already for the Python kernel code, and should be - * done soon for the NumPy array package. Step 2 is usually done once at - * python install time. Python's behavior with respect to SIGFPE is not - * changed unless you also do step 3. Thus you can control this new - * facility at compile time, or run time, or both. - * - ******************************** - * Using the macros in your code: - * - * static PyObject *foobar(PyObject *self,PyObject *args) - * { - * .... - * PyFPE_START_PROTECT("Error in foobar", return 0) - * result = dangerous_op(somearg1, somearg2, ...); - * PyFPE_END_PROTECT(result) - * .... - * } - * - * If a floating point error occurs in dangerous_op, foobar returns 0 (NULL), - * after setting the associated value of the FloatingPointError exception to - * "Error in foobar". ``Dangerous_op'' can be a single operation, or a block - * of code, function calls, or any combination, so long as no alternate - * return is possible before the PyFPE_END_PROTECT macro is reached. - * - * The macros can only be used in a function context where an error return - * can be recognized as signaling a Python exception. (Generally, most - * functions that return a PyObject * will qualify.) - * - * Guido's original design suggestion for PyFPE_START_PROTECT and - * PyFPE_END_PROTECT had them open and close a local block, with a locally - * defined jmp_buf and jmp_buf pointer. This would allow recursive nesting - * of the macros. The Ansi C standard makes it clear that such local - * variables need to be declared with the "volatile" type qualifier to keep - * setjmp from corrupting their values. Some current implementations seem - * to be more restrictive. For example, the HPUX man page for setjmp says - * - * Upon the return from a setjmp() call caused by a longjmp(), the - * values of any non-static local variables belonging to the routine - * from which setjmp() was called are undefined. Code which depends on - * such values is not guaranteed to be portable. - * - * I therefore decided on a more limited form of nesting, using a counter - * variable (PyFPE_counter) to keep track of any recursion. If an exception - * occurs in an ``inner'' pair of macros, the return will apparently - * come from the outermost level. - * +/* These macros used to do something when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them though, + * to avoid breaking API users. */ -#ifdef WANT_SIGFPE_HANDLER -#include -#include -#include -extern jmp_buf PyFPE_jbuf; -extern int PyFPE_counter; -extern double PyFPE_dummy(void *); - -#define PyFPE_START_PROTECT(err_string, leave_stmt) \ -if (!PyFPE_counter++ && setjmp(PyFPE_jbuf)) { \ - PyErr_SetString(PyExc_FloatingPointError, err_string); \ - PyFPE_counter = 0; \ - leave_stmt; \ -} - -/* - * This (following) is a heck of a way to decrement a counter. However, - * unless the macro argument is provided, code optimizers will sometimes move - * this statement so that it gets executed *before* the unsafe expression - * which we're trying to protect. That pretty well messes things up, - * of course. - * - * If the expression(s) you're trying to protect don't happen to return a - * value, you will need to manufacture a dummy result just to preserve the - * correct ordering of statements. Note that the macro passes the address - * of its argument (so you need to give it something which is addressable). - * If your expression returns multiple results, pass the last such result - * to PyFPE_END_PROTECT. - * - * Note that PyFPE_dummy returns a double, which is cast to int. - * This seeming insanity is to tickle the Floating Point Unit (FPU). - * If an exception has occurred in a preceding floating point operation, - * some architectures (notably Intel 80x86) will not deliver the interrupt - * until the *next* floating point operation. This is painful if you've - * already decremented PyFPE_counter. - */ -#define PyFPE_END_PROTECT(v) PyFPE_counter -= (int)PyFPE_dummy(&(v)); - -#else - #define PyFPE_START_PROTECT(err_string, leave_stmt) #define PyFPE_END_PROTECT(v) -#endif - -#ifdef __cplusplus -} -#endif #endif /* !Py_PYFPE_H */ diff --git a/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst b/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst new file mode 100644 index 00000000000..85f3df5c8f5 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst @@ -0,0 +1,3 @@ +The ``fpectl`` library has been removed. It was never enabled by default, +never worked correctly on x86-64, and it changed the Python ABI in ways that +caused unexpected breakage of C extensions. diff --git a/Modules/Setup.dist b/Modules/Setup.dist index 9c3e1bed30c..1f2d56c0655 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -334,20 +334,6 @@ _symtable symtablemodule.c #parser parsermodule.c -# Lee Busby's SIGFPE modules. -# The library to link fpectl with is platform specific. -# Choose *one* of the options below for fpectl: - -# For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2): -# (Without the compiler you don't have -lsunmath.) -#fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm - -# For other systems: see instructions in fpectlmodule.c. -#fpectl fpectlmodule.c ... - -# Test module for fpectl. No extra libraries needed. -#fpetest fpetestmodule.c - # Andrew Kuchling's zlib module. # This require zlib 1.1.3 (or later). # See http://www.gzip.org/zlib/ diff --git a/Modules/fpectlmodule.c b/Modules/fpectlmodule.c deleted file mode 100644 index 42ef0f6072e..00000000000 --- a/Modules/fpectlmodule.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - --------------------------------------------------------------------- - / Copyright (c) 1996. \ - | The Regents of the University of California. | - | All rights reserved. | - | | - | Permission to use, copy, modify, and distribute this software for | - | any purpose without fee is hereby granted, provided that this en- | - | tire notice is included in all copies of any software which is or | - | includes a copy or modification of this software and in all | - | copies of the supporting documentation for such software. | - | | - | This work was produced at the University of California, Lawrence | - | Livermore National Laboratory under contract no. W-7405-ENG-48 | - | between the U.S. Department of Energy and The Regents of the | - | University of California for the operation of UC LLNL. | - | | - | DISCLAIMER | - | | - | This software was prepared as an account of work sponsored by an | - | agency of the United States Government. Neither the United States | - | Government nor the University of California nor any of their em- | - | ployees, makes any warranty, express or implied, or assumes any | - | liability or responsibility for the accuracy, completeness, or | - | usefulness of any information, apparatus, product, or process | - | disclosed, or represents that its use would not infringe | - | privately-owned rights. Reference herein to any specific commer- | - | cial products, process, or service by trade name, trademark, | - | manufacturer, or otherwise, does not necessarily constitute or | - | imply its endorsement, recommendation, or favoring by the United | - | States Government or the University of California. The views and | - | opinions of authors expressed herein do not necessarily state or | - | reflect those of the United States Government or the University | - | of California, and shall not be used for advertising or product | - \ endorsement purposes. / - --------------------------------------------------------------------- -*/ - -/* - Floating point exception control module. - - This Python module provides bare-bones control over floating point - units from several hardware manufacturers. Specifically, it allows - the user to turn on the generation of SIGFPE whenever any of the - three serious IEEE 754 exceptions (Division by Zero, Overflow, - Invalid Operation) occurs. We currently ignore Underflow and - Inexact Result exceptions, although those could certainly be added - if desired. - - The module also establishes a signal handler for SIGFPE during - initialization. This builds on code found in the Python - distribution at Include/pyfpe.h and Python/pyfpe.c. If those files - are not in your Python distribution, find them in a patch at - ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz. - - This module is only useful to you if it happens to include code - specific for your hardware and software environment. If you can - contribute OS-specific code for new platforms, or corrections for - the code provided, it will be greatly appreciated. - - ** Version 1.0: September 20, 1996. Lee Busby, LLNL. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "Python.h" -#include - -#if defined(__FreeBSD__) -# include -#endif - -#ifndef WANT_SIGFPE_HANDLER -/* Define locally if they are not defined in Python. This gives only - * the limited control to induce a core dump in case of an exception. - */ -#include -static jmp_buf PyFPE_jbuf; -static int PyFPE_counter = 0; -#endif - -typedef void Sigfunc(int); -static Sigfunc sigfpe_handler; -static void fpe_reset(Sigfunc *); - -static PyObject *fpe_error; - -PyMODINIT_FUNC PyInit_fpectl(void); -static PyObject *turnon_sigfpe (PyObject *self,PyObject *args); -static PyObject *turnoff_sigfpe (PyObject *self,PyObject *args); - -static PyMethodDef fpectl_methods[] = { - {"turnon_sigfpe", (PyCFunction) turnon_sigfpe, METH_VARARGS}, - {"turnoff_sigfpe", (PyCFunction) turnoff_sigfpe, METH_VARARGS}, - {0,0} -}; - -static PyObject *turnon_sigfpe(PyObject *self,PyObject *args) -{ - /* Do any architecture-specific one-time only initialization here. */ - - fpe_reset(sigfpe_handler); - Py_RETURN_NONE; -} - -static void fpe_reset(Sigfunc *handler) -{ - /* Reset the exception handling machinery, and reset the signal - * handler for SIGFPE to the given handler. - */ - -/*-- SunOS and Solaris ----------------------------------------------------*/ -#if defined(sun) - /* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags - man pages (SunOS or Solaris) - cc -c -I/usr/local/python/include fpectlmodule.c - ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm - */ -#include -#ifndef _SUNMATH_H - extern void nonstandard_arithmetic(void); - extern int ieee_flags(const char*, const char*, const char*, char **); - extern long ieee_handler(const char*, const char*, sigfpe_handler_type); -#endif - - const char *mode="exception", *in="all"; - char *out; - (void) nonstandard_arithmetic(); - (void) ieee_flags("clearall",mode,in,&out); - (void) ieee_handler("set","common",(sigfpe_handler_type)handler); - PyOS_setsig(SIGFPE, handler); - -/*-- HPUX -----------------------------------------------------------------*/ -#elif defined(__hppa) || defined(hppa) - /* References: fpsetmask man page */ - /* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */ - /* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */ -#include - fpsetdefaults(); - PyOS_setsig(SIGFPE, handler); - -/*-- IBM AIX --------------------------------------------------------------*/ -#elif defined(__AIX) || defined(_AIX) - /* References: fp_trap, fp_enable man pages */ -#include - fp_trap(FP_TRAP_SYNC); - fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW); - PyOS_setsig(SIGFPE, handler); - -/*-- DEC ALPHA LINUX ------------------------------------------------------*/ -#elif defined(__alpha) && defined(linux) -#include - unsigned long fp_control = - IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF; - ieee_set_fp_control(fp_control); - PyOS_setsig(SIGFPE, handler); - -/*-- Cray Unicos ----------------------------------------------------------*/ -#elif defined(cray) - /* UNICOS delivers SIGFPE by default, but no matherr */ -#ifdef HAS_LIBMSET - libmset(-1); -#endif - PyOS_setsig(SIGFPE, handler); - -/*-- FreeBSD ----------------------------------------------------------------*/ -#elif defined(__FreeBSD__) - fpresetsticky(fpgetsticky()); - fpsetmask(FP_X_INV | FP_X_DZ | FP_X_OFL); - PyOS_setsig(SIGFPE, handler); - -/*-- Linux ----------------------------------------------------------------*/ -#elif defined(linux) -#ifdef __GLIBC__ -#include -#else -#include -#endif -#ifdef _FPU_SETCW - { - fpu_control_t cw = 0x1372; - _FPU_SETCW(cw); - } -#else - __setfpucw(0x1372); -#endif - PyOS_setsig(SIGFPE, handler); - -/*-- Microsoft Windows, NT ------------------------------------------------*/ -#elif defined(_MSC_VER) - /* Reference: Visual C++ Books Online 4.2, - Run-Time Library Reference, _control87, _controlfp */ -#include - unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW; - (void)_controlfp(0, cw); - PyOS_setsig(SIGFPE, handler); - -/*-- Give Up --------------------------------------------------------------*/ -#else - fputs("Operation not implemented\n", stderr); -#endif - -} - -static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args) -{ -#ifdef __FreeBSD__ - fpresetsticky(fpgetsticky()); - fpsetmask(0); -#else - fputs("Operation not implemented\n", stderr); -#endif - Py_RETURN_NONE; -} - -static void sigfpe_handler(int signo) -{ - fpe_reset(sigfpe_handler); - if(PyFPE_counter) { - longjmp(PyFPE_jbuf, 1); - } else { - Py_FatalError("Unprotected floating point exception"); - } -} - -static struct PyModuleDef fpectlmodule = { - PyModuleDef_HEAD_INIT, - "fpectl", - NULL, - -1, - fpectl_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_fpectl(void) -{ - PyObject *m, *d; - m = PyModule_Create(&fpectlmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - fpe_error = PyErr_NewException("fpectl.error", NULL, NULL); - if (fpe_error != NULL) - PyDict_SetItemString(d, "error", fpe_error); - return m; -} - -#ifdef __cplusplus -} -#endif diff --git a/Modules/fpetestmodule.c b/Modules/fpetestmodule.c deleted file mode 100644 index 1c232c98316..00000000000 --- a/Modules/fpetestmodule.c +++ /dev/null @@ -1,199 +0,0 @@ -/* - --------------------------------------------------------------------- - / Copyright (c) 1996. \ - | The Regents of the University of California. | - | All rights reserved. | - | | - | Permission to use, copy, modify, and distribute this software for | - | any purpose without fee is hereby granted, provided that this en- | - | tire notice is included in all copies of any software which is or | - | includes a copy or modification of this software and in all | - | copies of the supporting documentation for such software. | - | | - | This work was produced at the University of California, Lawrence | - | Livermore National Laboratory under contract no. W-7405-ENG-48 | - | between the U.S. Department of Energy and The Regents of the | - | University of California for the operation of UC LLNL. | - | | - | DISCLAIMER | - | | - | This software was prepared as an account of work sponsored by an | - | agency of the United States Government. Neither the United States | - | Government nor the University of California nor any of their em- | - | ployees, makes any warranty, express or implied, or assumes any | - | liability or responsibility for the accuracy, completeness, or | - | usefulness of any information, apparatus, product, or process | - | disclosed, or represents that its use would not infringe | - | privately-owned rights. Reference herein to any specific commer- | - | cial products, process, or service by trade name, trademark, | - | manufacturer, or otherwise, does not necessarily constitute or | - | imply its endorsement, recommendation, or favoring by the United | - | States Government or the University of California. The views and | - | opinions of authors expressed herein do not necessarily state or | - | reflect those of the United States Government or the University | - | of California, and shall not be used for advertising or product | - \ endorsement purposes. / - --------------------------------------------------------------------- -*/ - -/* - Floating point exception test module. - - */ - -#include "Python.h" - -static PyObject *fpe_error; - -PyMODINIT_FUNC PyInit_fpetest(void); -static PyObject *test(PyObject *self,PyObject *args); -static double db0(double); -static double overflow(double); -static double nest1(int, double); -static double nest2(int, double); -static double nest3(double); -static void printerr(double); - -static PyMethodDef fpetest_methods[] = { - {"test", (PyCFunction) test, METH_VARARGS}, - {0,0} -}; - -static PyObject *test(PyObject *self,PyObject *args) -{ - double r; - - fprintf(stderr,"overflow"); - r = overflow(1.e160); - printerr(r); - - fprintf(stderr,"\ndiv by 0"); - r = db0(0.0); - printerr(r); - - fprintf(stderr,"\nnested outer"); - r = nest1(0, 0.0); - printerr(r); - - fprintf(stderr,"\nnested inner"); - r = nest1(1, 1.0); - printerr(r); - - fprintf(stderr,"\ntrailing outer"); - r = nest1(2, 2.0); - printerr(r); - - fprintf(stderr,"\nnested prior"); - r = nest2(0, 0.0); - printerr(r); - - fprintf(stderr,"\nnested interior"); - r = nest2(1, 1.0); - printerr(r); - - fprintf(stderr,"\nnested trailing"); - r = nest2(2, 2.0); - printerr(r); - - Py_RETURN_NONE; -} - -static void printerr(double r) -{ - if(r == 3.1416){ - fprintf(stderr,"\tPASS\n"); - PyErr_Print(); - }else{ - fprintf(stderr,"\tFAIL\n"); - } - PyErr_Clear(); -} - -static double nest1(int i, double x) -{ - double a = 1.0; - - PyFPE_START_PROTECT("Division by zero, outer zone", return 3.1416) - if(i == 0){ - a = 1./x; - }else if(i == 1){ - /* This (following) message is never seen. */ - PyFPE_START_PROTECT("Division by zero, inner zone", return 3.1416) - a = 1./(1. - x); - PyFPE_END_PROTECT(a) - }else if(i == 2){ - a = 1./(2. - x); - } - PyFPE_END_PROTECT(a) - - return a; -} - -static double nest2(int i, double x) -{ - double a = 1.0; - PyFPE_START_PROTECT("Division by zero, prior error", return 3.1416) - if(i == 0){ - a = 1./x; - }else if(i == 1){ - a = nest3(x); - }else if(i == 2){ - a = 1./(2. - x); - } - PyFPE_END_PROTECT(a) - return a; -} - -static double nest3(double x) -{ - double result; - /* This (following) message is never seen. */ - PyFPE_START_PROTECT("Division by zero, nest3 error", return 3.1416) - result = 1./(1. - x); - PyFPE_END_PROTECT(result) - return result; -} - -static double db0(double x) -{ - double a; - PyFPE_START_PROTECT("Division by zero", return 3.1416) - a = 1./x; - PyFPE_END_PROTECT(a) - return a; -} - -static double overflow(double b) -{ - double a; - PyFPE_START_PROTECT("Overflow", return 3.1416) - a = b*b; - PyFPE_END_PROTECT(a) - return a; -} - -static struct PyModuleDef fpetestmodule = { - PyModuleDef_HEAD_INIT, - "fpetest", - NULL, - -1, - fpetest_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC PyInit_fpetest(void) -{ - PyObject *m, *d; - - m = PyModule_Create(&fpetestmodule); - if (m == NULL) - return NULL; - d = PyModule_GetDict(m); - fpe_error = PyErr_NewException("fpetest.error", NULL, NULL); - if (fpe_error != NULL) - PyDict_SetItemString(d, "error", fpe_error); - return m; -} diff --git a/Python/pyfpe.c b/Python/pyfpe.c index 925fa4654d9..31ef5d73b70 100644 --- a/Python/pyfpe.c +++ b/Python/pyfpe.c @@ -1,20 +1,12 @@ -#include "pyconfig.h" -#include "pyfpe.h" -/* - * The signal handler for SIGFPE is actually declared in an external - * module fpectl, or as preferred by the user. These variable - * definitions are required in order to compile Python without - * getting missing externals, but to actually handle SIGFPE requires - * defining a handler and enabling generation of SIGFPE. +/* These variables used to be used when Python was built with --with-fpectl, + * but support for that was dropped in 3.7. We continue to define them, + * though, because they may be referenced by extensions using the stable ABI. */ -#ifdef WANT_SIGFPE_HANDLER -jmp_buf PyFPE_jbuf; -int PyFPE_counter = 0; -#endif +#include "setjmp.h" -/* Have this outside the above #ifdef, since some picky ANSI compilers issue a - warning when compiling an empty file. */ +jmp_buf PyFPE_jbuf; +int PyFPE_counter; double PyFPE_dummy(void *dummy) diff --git a/aclocal.m4 b/aclocal.m4 index 4eb2dc3bbe2..61b2539d2e9 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.15.1 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2017 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -13,7 +13,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -dnl serial 11 (pkg-config-0.29.1) +dnl serial 11 (pkg-config-0.29) dnl dnl Copyright ? 2004 Scott James Remnant . dnl Copyright ? 2012-2015 Dan Nicholson @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -170,7 +170,7 @@ if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else + else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs diff --git a/configure b/configure index da2c43fe7a2..afffc190751 100755 --- a/configure +++ b/configure @@ -832,7 +832,6 @@ with_c_locale_coercion with_c_locale_warning with_valgrind with_dtrace -with_fpectl with_libm with_libc enable_big_digits @@ -1539,7 +1538,6 @@ Optional Packages: locale --with-valgrind Enable Valgrind support --with(out)-dtrace disable/enable DTrace support - --with-fpectl enable SIGFPE catching --with-libm=STRING math library --with-libc=STRING C library --with(out)-computed-gotos @@ -13691,29 +13689,6 @@ fi fi -# Check for --with-fpectl -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-fpectl" >&5 -$as_echo_n "checking for --with-fpectl... " >&6; } - -# Check whether --with-fpectl was given. -if test "${with_fpectl+set}" = set; then : - withval=$with_fpectl; -if test "$withval" != no -then - -$as_echo "#define WANT_SIGFPE_HANDLER 1" >>confdefs.h - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - # check for --with-libm=... case $ac_sys_system in diff --git a/configure.ac b/configure.ac index 9a84e90e34c..0a48e41d5c3 100644 --- a/configure.ac +++ b/configure.ac @@ -4135,20 +4135,6 @@ AC_CHECK_FUNC(__fpu_control, [AC_CHECK_LIB(ieee, __fpu_control) ]) -# Check for --with-fpectl -AC_MSG_CHECKING(for --with-fpectl) -AC_ARG_WITH(fpectl, - AS_HELP_STRING([--with-fpectl], [enable SIGFPE catching]), -[ -if test "$withval" != no -then - AC_DEFINE(WANT_SIGFPE_HANDLER, 1, - [Define if you want SIGFPE handled (see Include/pyfpe.h).]) - AC_MSG_RESULT(yes) -else AC_MSG_RESULT(no) -fi], -[AC_MSG_RESULT(no)]) - # check for --with-libm=... AC_SUBST(LIBM) case $ac_sys_system in diff --git a/pyconfig.h.in b/pyconfig.h.in index 4cf2f035c23..7d366562b0c 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -500,7 +500,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_IEEEFP_H -/* Define to 1 if you have the 'if_nameindex' function. */ +/* Define to 1 if you have the `if_nameindex' function. */ #undef HAVE_IF_NAMEINDEX /* Define if you have the 'inet_aton' function. */ @@ -1413,9 +1413,6 @@ #endif -/* Define if you want SIGFPE handled (see Include/pyfpe.h). */ -#undef WANT_SIGFPE_HANDLER - /* Define if WINDOW in curses.h offers a field _flags. */ #undef WINDOW_HAS_FLAGS From webhook-mailer at python.org Sat Jan 6 02:53:10 2018 From: webhook-mailer at python.org (Nick Coghlan) Date: Sat, 06 Jan 2018 07:53:10 -0000 Subject: [Python-checkins] bpo-32206: Pdb can now run modules (GH-4752) Message-ID: https://github.com/python/cpython/commit/9f1e5f1b7f074e026843a5d70834233a95a6bf9d commit: 9f1e5f1b7f074e026843a5d70834233a95a6bf9d branch: master author: Mario Corchero committer: Nick Coghlan date: 2018-01-06T17:53:05+10:00 summary: bpo-32206: Pdb can now run modules (GH-4752) Add a new argument "-m" to the pdb module to allow users to run `python -m pdb -m my_module_name`. This relies on private APIs in the runpy module to work, but we can get away with that since they're both part of the standard library and can be updated together if the runpy internals get refactored. files: A Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst M Doc/library/pdb.rst M Doc/whatsnew/3.7.rst M Lib/pdb.py M Lib/test/test_pdb.py diff --git a/Doc/library/pdb.rst b/Doc/library/pdb.rst index 4f3148fb5c3..e81c195782d 100644 --- a/Doc/library/pdb.rst +++ b/Doc/library/pdb.rst @@ -61,6 +61,12 @@ useful than quitting the debugger upon program's exit. :file:`pdb.py` now accepts a ``-c`` option that executes commands as if given in a :file:`.pdbrc` file, see :ref:`debugger-commands`. +.. versionadded:: 3.7 + :file:`pdb.py` now accepts a ``-m`` option that execute modules similar to the way + ``python3 -m`` does. As with a script, the debugger will pause execution just + before the first line of the module. + + The typical usage to break into the debugger from a running program is to insert :: diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 1311e9e2016..9785d599dd3 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -426,6 +426,10 @@ pdb argument. If given, this is printed to the console just before debugging begins. (Contributed by Barry Warsaw in :issue:`31389`.) +pdb command line now accepts `-m module_name` as an alternative to +script file. (Contributed by Mario Corchero in :issue:`32206`.) + + re -- diff --git a/Lib/pdb.py b/Lib/pdb.py index 8dd4dedb220..d1a74bb7d7b 100755 --- a/Lib/pdb.py +++ b/Lib/pdb.py @@ -1521,6 +1521,24 @@ def lookupmodule(self, filename): return fullname return None + def _runmodule(self, module_name): + self._wait_for_mainpyfile = True + self._user_requested_quit = False + import runpy + mod_name, mod_spec, code = runpy._get_module_details(module_name) + self.mainpyfile = self.canonic(code.co_filename) + import __main__ + __main__.__dict__.clear() + __main__.__dict__.update({ + "__name__": "__main__", + "__file__": self.mainpyfile, + "__package__": module_name, + "__loader__": mod_spec.loader, + "__spec__": mod_spec, + "__builtins__": __builtins__, + }) + self.run(code) + def _runscript(self, filename): # The script has to run in __main__ namespace (or imports from # __main__ will break). @@ -1635,29 +1653,33 @@ def help(): def main(): import getopt - opts, args = getopt.getopt(sys.argv[1:], 'hc:', ['--help', '--command=']) + opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['--help', '--command=']) if not args: print(_usage) sys.exit(2) commands = [] + run_as_module = False for opt, optarg in opts: if opt in ['-h', '--help']: print(_usage) sys.exit() elif opt in ['-c', '--command']: commands.append(optarg) + elif opt in ['-m']: + run_as_module = True mainpyfile = args[0] # Get script filename - if not os.path.exists(mainpyfile): + if not run_as_module and not os.path.exists(mainpyfile): print('Error:', mainpyfile, 'does not exist') sys.exit(1) sys.argv[:] = args # Hide "pdb.py" and pdb options from argument list # Replace pdb's dir with script's dir in front of module search path. - sys.path[0] = os.path.dirname(mainpyfile) + if not run_as_module: + sys.path[0] = os.path.dirname(mainpyfile) # Note on saving/restoring sys.argv: it's a good idea when sys.argv was # modified by the script being debugged. It's a bad idea when it was @@ -1667,7 +1689,10 @@ def main(): pdb.rcLines.extend(commands) while True: try: - pdb._runscript(mainpyfile) + if run_as_module: + pdb._runmodule(mainpyfile) + else: + pdb._runscript(mainpyfile) if pdb._user_requested_quit: break print("The program finished and will be restarted") diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 71d8203fc56..0cd235e98ae 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -938,26 +938,47 @@ def test_pdb_issue_20766(): pdb 2: """ + class PdbTestCase(unittest.TestCase): + def tearDown(self): + support.unlink(support.TESTFN) - def run_pdb(self, script, commands): - """Run 'script' lines with pdb and the pdb 'commands'.""" - filename = 'main.py' - with open(filename, 'w') as f: - f.write(textwrap.dedent(script)) - self.addCleanup(support.unlink, filename) + def _run_pdb(self, pdb_args, commands): self.addCleanup(support.rmtree, '__pycache__') - cmd = [sys.executable, '-m', 'pdb', filename] - stdout = stderr = None - with subprocess.Popen(cmd, stdout=subprocess.PIPE, - stdin=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) as proc: + cmd = [sys.executable, '-m', 'pdb'] + pdb_args + with subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stdin=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) as proc: stdout, stderr = proc.communicate(str.encode(commands)) stdout = stdout and bytes.decode(stdout) stderr = stderr and bytes.decode(stderr) return stdout, stderr + def run_pdb_script(self, script, commands): + """Run 'script' lines with pdb and the pdb 'commands'.""" + filename = 'main.py' + with open(filename, 'w') as f: + f.write(textwrap.dedent(script)) + self.addCleanup(support.unlink, filename) + return self._run_pdb([filename], commands) + + def run_pdb_module(self, script, commands): + """Runs the script code as part of a module""" + self.module_name = 't_main' + support.rmtree(self.module_name) + main_file = self.module_name + '/__main__.py' + init_file = self.module_name + '/__init__.py' + os.mkdir(self.module_name) + with open(init_file, 'w') as f: + pass + with open(main_file, 'w') as f: + f.write(textwrap.dedent(script)) + self.addCleanup(support.rmtree, self.module_name) + return self._run_pdb(['-m', self.module_name], commands) + def _assert_find_function(self, file_content, func_name, expected): file_content = textwrap.dedent(file_content) @@ -1034,7 +1055,7 @@ def bar(): with open('bar.py', 'w') as f: f.write(textwrap.dedent(bar)) self.addCleanup(support.unlink, 'bar.py') - stdout, stderr = self.run_pdb(script, commands) + stdout, stderr = self.run_pdb_script(script, commands) self.assertTrue( any('main.py(5)foo()->None' in l for l in stdout.splitlines()), 'Fail to step into the caller after a return') @@ -1071,7 +1092,7 @@ def test_issue16180(self): script = "def f: pass\n" commands = '' expected = "SyntaxError:" - stdout, stderr = self.run_pdb(script, commands) + stdout, stderr = self.run_pdb_script(script, commands) self.assertIn(expected, stdout, '\n\nExpected:\n{}\nGot:\n{}\n' 'Fail to handle a syntax error in the debuggee.' @@ -1119,13 +1140,119 @@ def test_header(self): pdb.set_trace(header=header) self.assertEqual(stdout.getvalue(), header + '\n') - def tearDown(self): - support.unlink(support.TESTFN) + def test_run_module(self): + script = """print("SUCCESS")""" + commands = """ + continue + quit + """ + stdout, stderr = self.run_pdb_module(script, commands) + self.assertTrue(any("SUCCESS" in l for l in stdout.splitlines()), stdout) + + def test_module_is_run_as_main(self): + script = """ + if __name__ == '__main__': + print("SUCCESS") + """ + commands = """ + continue + quit + """ + stdout, stderr = self.run_pdb_module(script, commands) + self.assertTrue(any("SUCCESS" in l for l in stdout.splitlines()), stdout) + + def test_breakpoint(self): + script = """ + if __name__ == '__main__': + pass + print("SUCCESS") + pass + """ + commands = """ + b 3 + quit + """ + stdout, stderr = self.run_pdb_module(script, commands) + self.assertTrue(any("Breakpoint 1 at" in l for l in stdout.splitlines()), stdout) + self.assertTrue(all("SUCCESS" not in l for l in stdout.splitlines()), stdout) + + def test_run_pdb_with_pdb(self): + commands = """ + c + quit + """ + stdout, stderr = self._run_pdb(["-m", "pdb"], commands) + self.assertIn("Debug the Python program given by pyfile.", stdout.splitlines()) + + def test_module_without_a_main(self): + module_name = 't_main' + support.rmtree(module_name) + init_file = module_name + '/__init__.py' + os.mkdir(module_name) + with open(init_file, 'w') as f: + pass + self.addCleanup(support.rmtree, module_name) + stdout, stderr = self._run_pdb(['-m', module_name], "") + self.assertIn("ImportError: No module named t_main.__main__", + stdout.splitlines()) + + def test_blocks_at_first_code_line(self): + script = """ + #This is a comment, on line 2 + + print("SUCCESS") + """ + commands = """ + quit + """ + stdout, stderr = self.run_pdb_module(script, commands) + self.assertTrue(any("__main__.py(4)()" + in l for l in stdout.splitlines()), stdout) + + def test_relative_imports(self): + self.module_name = 't_main' + support.rmtree(self.module_name) + main_file = self.module_name + '/__main__.py' + init_file = self.module_name + '/__init__.py' + module_file = self.module_name + '/module.py' + self.addCleanup(support.rmtree, self.module_name) + os.mkdir(self.module_name) + with open(init_file, 'w') as f: + f.write(textwrap.dedent(""" + top_var = "VAR from top" + """)) + with open(main_file, 'w') as f: + f.write(textwrap.dedent(""" + from . import top_var + from .module import var + from . import module + pass # We'll stop here and print the vars + """)) + with open(module_file, 'w') as f: + f.write(textwrap.dedent(""" + var = "VAR from module" + var2 = "second var" + """)) + commands = """ + b 5 + c + p top_var + p var + p module.var2 + quit + """ + stdout, _ = self._run_pdb(['-m', self.module_name], commands) + self.assertTrue(any("VAR from module" in l for l in stdout.splitlines())) + self.assertTrue(any("VAR from top" in l for l in stdout.splitlines())) + self.assertTrue(any("second var" in l for l in stdout.splitlines())) def load_tests(*args): from test import test_pdb - suites = [unittest.makeSuite(PdbTestCase), doctest.DocTestSuite(test_pdb)] + suites = [ + unittest.makeSuite(PdbTestCase), + doctest.DocTestSuite(test_pdb) + ] return unittest.TestSuite(suites) diff --git a/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst b/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst new file mode 100644 index 00000000000..20d7eeace87 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst @@ -0,0 +1 @@ +Add support to run modules with pdb From solipsis at pitrou.net Sat Jan 6 04:12:43 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sat, 06 Jan 2018 09:12:43 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=15 Message-ID: <20180106091243.1.CC6245E9C269F732@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [7, -7, 8] memory blocks, sum=8 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [3, -1, 1] memory blocks, sum=3 test_multiprocessing_forkserver leaked [0, -2, 2] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogvj9Fba', '--timeout', '7200'] From webhook-mailer at python.org Sat Jan 6 08:25:42 2018 From: webhook-mailer at python.org (Andrew Svetlov) Date: Sat, 06 Jan 2018 13:25:42 -0000 Subject: [Python-checkins] Cleanup grammar in unittest.mock.seal documentation (#5107) Message-ID: https://github.com/python/cpython/commit/85ac726a40707ae68a23d568c322868e353217ce commit: 85ac726a40707ae68a23d568c322868e353217ce branch: master author: Paul Ganssle committer: Andrew Svetlov date: 2018-01-06T15:25:34+02:00 summary: Cleanup grammar in unittest.mock.seal documentation (#5107) files: M Doc/library/unittest.mock.rst diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst index b6eb8ccb59d..ac9dd3b6f79 100644 --- a/Doc/library/unittest.mock.rst +++ b/Doc/library/unittest.mock.rst @@ -2370,12 +2370,12 @@ Sealing mocks .. function:: seal(mock) - Seal will disable the creation of mock children by preventing to get or set - any new attribute on the sealed mock. The sealing process is performed recursively. + Seal will disable the creation of mock children by preventing getting or setting + of any new attribute on the sealed mock. The sealing process is performed recursively. If a mock instance is assigned to an attribute instead of being dynamically created - it won't be considered in the sealing chain. This allows to prevent seal from fixing - part of the mock object. + it won't be considered in the sealing chain. This allows one to prevent seal from + fixing part of the mock object. >>> mock = Mock() >>> mock.submock.attribute1 = 2 From webhook-mailer at python.org Sat Jan 6 10:18:57 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sat, 06 Jan 2018 15:18:57 -0000 Subject: [Python-checkins] bpo-31993: Do not allocate large temporary buffers in pickle dump. (#4353) Message-ID: https://github.com/python/cpython/commit/3cd7c6e6eb43dbd7d7180503265772a67953e682 commit: 3cd7c6e6eb43dbd7d7180503265772a67953e682 branch: master author: Olivier Grisel committer: Serhiy Storchaka date: 2018-01-06T17:18:54+02:00 summary: bpo-31993: Do not allocate large temporary buffers in pickle dump. (#4353) The picklers do no longer allocate temporary memory when dumping large bytes and str objects into a file object. Instead the data is directly streamed into the underlying file object. Previously the C implementation would buffer all content and issue a single call to file.write() at the end of the dump. With protocol 4 this behavior has changed to issue one call to file.write() per frame. The Python pickler with protocol 4 now dumps each frame content as a memoryview to an IOBytes instance that is never reused and the memoryview is no longer released after the call to write. This makes it possible for the file object to delay access to the memoryview of previous frames without forcing any additional memory copy as was already possible with the C pickler. files: A Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst M Lib/pickle.py M Lib/pickletools.py M Lib/test/pickletester.py M Lib/test/test_pickletools.py M Modules/_pickle.c diff --git a/Lib/pickle.py b/Lib/pickle.py index 350d4a46c06..301e8cf5589 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -201,14 +201,24 @@ def commit_frame(self, force=False): if self.current_frame: f = self.current_frame if f.tell() >= self._FRAME_SIZE_TARGET or force: - with f.getbuffer() as data: - n = len(data) - write = self.file_write - write(FRAME) - write(pack("= 1 @@ -699,7 +725,9 @@ def save_bytes(self, obj): if n <= 0xff: self.write(SHORT_BINBYTES + pack(" 0xffffffff and self.proto >= 4: - self.write(BINBYTES8 + pack("= self.framer._FRAME_SIZE_TARGET: + self._write_large_bytes(BINBYTES + pack("= 4: self.write(SHORT_BINUNICODE + pack(" 0xffffffff and self.proto >= 4: - self.write(BINUNICODE8 + pack("= self.framer._FRAME_SIZE_TARGET: + self._write_large_bytes(BINUNICODE + pack(" proto: proto = arg if pos == 0: - protoheader = p[pos: end_pos] + protoheader = p[pos:end_pos] else: opcodes.append((pos, end_pos)) else: @@ -2295,6 +2295,7 @@ def optimize(p): pickler.framer.start_framing() idx = 0 for op, arg in opcodes: + frameless = False if op is put: if arg not in newids: continue @@ -2305,8 +2306,12 @@ def optimize(p): data = pickler.get(newids[arg]) else: data = p[op:arg] - pickler.framer.commit_frame() - pickler.write(data) + frameless = len(data) > pickler.framer._FRAME_SIZE_TARGET + pickler.framer.commit_frame(force=frameless) + if frameless: + pickler.framer.file_write(data) + else: + pickler.write(data) pickler.framer.end_framing() return out.getvalue() diff --git a/Lib/test/pickletester.py b/Lib/test/pickletester.py index bf6116b2dfb..5d983eb617f 100644 --- a/Lib/test/pickletester.py +++ b/Lib/test/pickletester.py @@ -2042,21 +2042,40 @@ def test_setitems_on_non_dicts(self): def check_frame_opcodes(self, pickled): """ Check the arguments of FRAME opcodes in a protocol 4+ pickle. + + Note that binary objects that are larger than FRAME_SIZE_TARGET are not + framed by default and are therefore considered a frame by themselves in + the following consistency check. """ - frame_opcode_size = 9 - last_arg = last_pos = None + last_arg = last_pos = last_frame_opcode_size = None + frameless_opcode_sizes = { + 'BINBYTES': 5, + 'BINUNICODE': 5, + 'BINBYTES8': 9, + 'BINUNICODE8': 9, + } for op, arg, pos in pickletools.genops(pickled): - if op.name != 'FRAME': + if op.name in frameless_opcode_sizes: + if len(arg) > self.FRAME_SIZE_TARGET: + frame_opcode_size = frameless_opcode_sizes[op.name] + arg = len(arg) + else: + continue + elif op.name == 'FRAME': + frame_opcode_size = 9 + else: continue + if last_pos is not None: # The previous frame's size should be equal to the number # of bytes up to the current frame. - frame_size = pos - last_pos - frame_opcode_size + frame_size = pos - last_pos - last_frame_opcode_size self.assertEqual(frame_size, last_arg) last_arg, last_pos = arg, pos + last_frame_opcode_size = frame_opcode_size # The last frame's size should be equal to the number of bytes up # to the pickle's end. - frame_size = len(pickled) - last_pos - frame_opcode_size + frame_size = len(pickled) - last_pos - last_frame_opcode_size self.assertEqual(frame_size, last_arg) def test_framing_many_objects(self): @@ -2076,15 +2095,36 @@ def test_framing_many_objects(self): def test_framing_large_objects(self): N = 1024 * 1024 - obj = [b'x' * N, b'y' * N, b'z' * N] + obj = [b'x' * N, b'y' * N, 'z' * N] for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): - with self.subTest(proto=proto): - pickled = self.dumps(obj, proto) - unpickled = self.loads(pickled) - self.assertEqual(obj, unpickled) - n_frames = count_opcode(pickle.FRAME, pickled) - self.assertGreaterEqual(n_frames, len(obj)) - self.check_frame_opcodes(pickled) + for fast in [True, False]: + with self.subTest(proto=proto, fast=fast): + if hasattr(self, 'pickler'): + buf = io.BytesIO() + pickler = self.pickler(buf, protocol=proto) + pickler.fast = fast + pickler.dump(obj) + pickled = buf.getvalue() + elif fast: + continue + else: + # Fallback to self.dumps when fast=False and + # self.pickler is not available. + pickled = self.dumps(obj, proto) + unpickled = self.loads(pickled) + # More informative error message in case of failure. + self.assertEqual([len(x) for x in obj], + [len(x) for x in unpickled]) + # Perform full equality check if the lengths match. + self.assertEqual(obj, unpickled) + n_frames = count_opcode(pickle.FRAME, pickled) + if not fast: + # One frame per memoize for each large object. + self.assertGreaterEqual(n_frames, len(obj)) + else: + # One frame at the beginning and one at the end. + self.assertGreaterEqual(n_frames, 2) + self.check_frame_opcodes(pickled) def test_optional_frames(self): if pickle.HIGHEST_PROTOCOL < 4: @@ -2125,6 +2165,71 @@ def remove_frames(pickled, keep_frame=None): count_opcode(pickle.FRAME, pickled)) self.assertEqual(obj, self.loads(some_frames_pickle)) + def test_framed_write_sizes_with_delayed_writer(self): + class ChunkAccumulator: + """Accumulate pickler output in a list of raw chunks.""" + + def __init__(self): + self.chunks = [] + + def write(self, chunk): + self.chunks.append(chunk) + + def concatenate_chunks(self): + # Some chunks can be memoryview instances, we need to convert + # them to bytes to be able to call join + return b"".join([c.tobytes() if hasattr(c, 'tobytes') else c + for c in self.chunks]) + + small_objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)}) + for i in range(int(1e4))] + + for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): + # Protocol 4 packs groups of small objects into frames and issues + # calls to write only once or twice per frame: + # The C pickler issues one call to write per-frame (header and + # contents) while Python pickler issues two calls to write: one for + # the frame header and one for the frame binary contents. + writer = ChunkAccumulator() + self.pickler(writer, proto).dump(small_objects) + + # Actually read the binary content of the chunks after the end + # of the call to dump: ant memoryview passed to write should not + # be released otherwise this delayed access would not be possible. + pickled = writer.concatenate_chunks() + reconstructed = self.loads(pickled) + self.assertEqual(reconstructed, small_objects) + self.assertGreater(len(writer.chunks), 1) + + n_frames, remainder = divmod(len(pickled), self.FRAME_SIZE_TARGET) + if remainder > 0: + n_frames += 1 + + # There should be at least one call to write per frame + self.assertGreaterEqual(len(writer.chunks), n_frames) + + # but not too many either: there can be one for the proto, + # one per-frame header and one per frame for the actual contents. + self.assertGreaterEqual(2 * n_frames + 1, len(writer.chunks)) + + chunk_sizes = [len(c) for c in writer.chunks[:-1]] + large_sizes = [s for s in chunk_sizes + if s >= self.FRAME_SIZE_TARGET] + small_sizes = [s for s in chunk_sizes + if s < self.FRAME_SIZE_TARGET] + + # Large chunks should not be too large: + for chunk_size in large_sizes: + self.assertGreater(2 * self.FRAME_SIZE_TARGET, chunk_size) + + last_chunk_size = len(writer.chunks[-1]) + self.assertGreater(2 * self.FRAME_SIZE_TARGET, last_chunk_size) + + # Small chunks (if any) should be very small + # (only proto and frame headers) + for chunk_size in small_sizes: + self.assertGreaterEqual(9, chunk_size) + def test_nested_names(self): global Nested class Nested: diff --git a/Lib/test/test_pickletools.py b/Lib/test/test_pickletools.py index b3cab0e4fb3..e40a958f7eb 100644 --- a/Lib/test/test_pickletools.py +++ b/Lib/test/test_pickletools.py @@ -15,6 +15,9 @@ def loads(self, buf, **kwds): # Test relies on precise output of dumps() test_pickle_to_2x = None + # Test relies on writing by chunks into a file object. + test_framed_write_sizes_with_delayed_writer = None + def test_optimize_long_binget(self): data = [str(i) for i in range(257)] data.append(data[-1]) diff --git a/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst b/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst new file mode 100644 index 00000000000..b453e21c80c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst @@ -0,0 +1,14 @@ +The picklers do no longer allocate temporary memory when dumping large +``bytes`` and ``str`` objects into a file object. Instead the data is +directly streamed into the underlying file object. + +Previously the C implementation would buffer all content and issue a +single call to ``file.write`` at the end of the dump. With protocol 4 +this behavior has changed to issue one call to ``file.write`` per frame. + +The Python pickler with protocol 4 now dumps each frame content as a +memoryview to an IOBytes instance that is never reused and the +memoryview is no longer released after the call to write. This makes it +possible for the file object to delay access to the memoryview of +previous frames without forcing any additional memory copy as was +already possible with the C pickler. diff --git a/Modules/_pickle.c b/Modules/_pickle.c index da915efd831..5cb1fba6cc2 100644 --- a/Modules/_pickle.c +++ b/Modules/_pickle.c @@ -971,20 +971,6 @@ _Pickler_CommitFrame(PicklerObject *self) return 0; } -static int -_Pickler_OpcodeBoundary(PicklerObject *self) -{ - Py_ssize_t frame_len; - - if (!self->framing || self->frame_start == -1) - return 0; - frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; - if (frame_len >= FRAME_SIZE_TARGET) - return _Pickler_CommitFrame(self); - else - return 0; -} - static PyObject * _Pickler_GetString(PicklerObject *self) { @@ -1019,6 +1005,38 @@ _Pickler_FlushToFile(PicklerObject *self) return (result == NULL) ? -1 : 0; } +static int +_Pickler_OpcodeBoundary(PicklerObject *self) +{ + Py_ssize_t frame_len; + + if (!self->framing || self->frame_start == -1) { + return 0; + } + frame_len = self->output_len - self->frame_start - FRAME_HEADER_SIZE; + if (frame_len >= FRAME_SIZE_TARGET) { + if(_Pickler_CommitFrame(self)) { + return -1; + } + /* Flush the content of the commited frame to the underlying + * file and reuse the pickler buffer for the next frame so as + * to limit memory usage when dumping large complex objects to + * a file. + * + * self->write is NULL when called via dumps. + */ + if (self->write != NULL) { + if (_Pickler_FlushToFile(self) < 0) { + return -1; + } + if (_Pickler_ClearBuffer(self) < 0) { + return -1; + } + } + } + return 0; +} + static Py_ssize_t _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) { @@ -2124,6 +2142,51 @@ save_float(PicklerObject *self, PyObject *obj) return 0; } +/* No-copy code-path to write large contiguous data directly into the + underlying file object, bypassing the output_buffer of the Pickler. */ +static int +_Pickler_write_large_bytes( + PicklerObject *self, const char *header, Py_ssize_t header_size, + PyObject *payload) +{ + assert(self->output_buffer != NULL); + assert(self->write != NULL); + PyObject *result; + + /* Commit the previous frame. */ + if (_Pickler_CommitFrame(self)) { + return -1; + } + /* Disable frameing temporarily */ + self->framing = 0; + + if (_Pickler_Write(self, header, header_size) < 0) { + return -1; + } + /* Dump the output buffer to the file. */ + if (_Pickler_FlushToFile(self) < 0) { + return -1; + } + + /* Stream write the payload into the file without going through the + output buffer. */ + result = PyObject_CallFunctionObjArgs(self->write, payload, NULL); + if (result == NULL) { + return -1; + } + Py_DECREF(result); + + /* Reinitialize the buffer for subsequent calls to _Pickler_Write. */ + if (_Pickler_ClearBuffer(self) < 0) { + return -1; + } + + /* Re-enable framing for subsequent calls to _Pickler_Write. */ + self->framing = 1; + + return 0; +} + static int save_bytes(PicklerObject *self, PyObject *obj) { @@ -2202,11 +2265,21 @@ save_bytes(PicklerObject *self, PyObject *obj) return -1; /* string too large */ } - if (_Pickler_Write(self, header, len) < 0) - return -1; - - if (_Pickler_Write(self, PyBytes_AS_STRING(obj), size) < 0) - return -1; + if (size < FRAME_SIZE_TARGET || self->write == NULL) { + if (_Pickler_Write(self, header, len) < 0) { + return -1; + } + if (_Pickler_Write(self, PyBytes_AS_STRING(obj), size) < 0) { + return -1; + } + } + else { + /* Bypass the in-memory buffer to directly stream large data + into the underlying file object. */ + if (_Pickler_write_large_bytes(self, header, len, obj) < 0) { + return -1; + } + } if (memo_put(self, obj) < 0) return -1; @@ -2291,6 +2364,7 @@ write_utf8(PicklerObject *self, const char *data, Py_ssize_t size) { char header[9]; Py_ssize_t len; + PyObject *mem; assert(size >= 0); if (size <= 0xff && self->proto >= 4) { @@ -2317,11 +2391,27 @@ write_utf8(PicklerObject *self, const char *data, Py_ssize_t size) return -1; } - if (_Pickler_Write(self, header, len) < 0) - return -1; - if (_Pickler_Write(self, data, size) < 0) - return -1; - + if (size < FRAME_SIZE_TARGET || self->write == NULL) { + if (_Pickler_Write(self, header, len) < 0) { + return -1; + } + if (_Pickler_Write(self, data, size) < 0) { + return -1; + } + } + else { + /* Bypass the in-memory buffer to directly stream large data + into the underlying file object. */ + mem = PyMemoryView_FromMemory((char *) data, size, PyBUF_READ); + if (mem == NULL) { + return -1; + } + if (_Pickler_write_large_bytes(self, header, len, mem) < 0) { + Py_DECREF(mem); + return -1; + } + Py_DECREF(mem); + } return 0; } From webhook-mailer at python.org Sat Jan 6 12:41:55 2018 From: webhook-mailer at python.org (Eric V. Smith) Date: Sat, 06 Jan 2018 17:41:55 -0000 Subject: [Python-checkins] bpo-32499: Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass or an instance of one. (#5113) Message-ID: https://github.com/python/cpython/commit/e7ba013d870012157f695ead7e3645c2828a7fc5 commit: e7ba013d870012157f695ead7e3645c2828a7fc5 branch: master author: Eric V. Smith committer: GitHub date: 2018-01-06T12:41:53-05:00 summary: bpo-32499: Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass or an instance of one. (#5113) files: A Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst M Lib/dataclasses.py M Lib/test/test_dataclasses.py diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index eaaed63ef28..b4786bf502e 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -16,6 +16,7 @@ 'astuple', 'make_dataclass', 'replace', + 'is_dataclass', ] # Raised when an attempt is made to modify a frozen class. @@ -615,11 +616,17 @@ def fields(class_or_instance): return tuple(f for f in fields.values() if f._field_type is _FIELD) -def _isdataclass(obj): +def _is_dataclass_instance(obj): """Returns True if obj is an instance of a dataclass.""" return not isinstance(obj, type) and hasattr(obj, _MARKER) +def is_dataclass(obj): + """Returns True if obj is a dataclass or an instance of a + dataclass.""" + return hasattr(obj, _MARKER) + + def asdict(obj, *, dict_factory=dict): """Return the fields of a dataclass instance as a new dictionary mapping field names to field values. @@ -639,12 +646,12 @@ class C: dataclass instances. This will also look into built-in containers: tuples, lists, and dicts. """ - if not _isdataclass(obj): + if not _is_dataclass_instance(obj): raise TypeError("asdict() should be called on dataclass instances") return _asdict_inner(obj, dict_factory) def _asdict_inner(obj, dict_factory): - if _isdataclass(obj): + if _is_dataclass_instance(obj): result = [] for f in fields(obj): value = _asdict_inner(getattr(obj, f.name), dict_factory) @@ -678,12 +685,12 @@ class C: tuples, lists, and dicts. """ - if not _isdataclass(obj): + if not _is_dataclass_instance(obj): raise TypeError("astuple() should be called on dataclass instances") return _astuple_inner(obj, tuple_factory) def _astuple_inner(obj, tuple_factory): - if _isdataclass(obj): + if _is_dataclass_instance(obj): result = [] for f in fields(obj): value = _astuple_inner(getattr(obj, f.name), tuple_factory) @@ -751,7 +758,7 @@ class C: # We're going to mutate 'changes', but that's okay because it's a new # dict, even if called with 'replace(obj, **my_changes)'. - if not _isdataclass(obj): + if not _is_dataclass_instance(obj): raise TypeError("replace() should be called on dataclass instances") # It's an error to have init=False fields in 'changes'. diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index ed695639882..fca384d8c3c 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -1,6 +1,6 @@ from dataclasses import ( dataclass, field, FrozenInstanceError, fields, asdict, astuple, - make_dataclass, replace, InitVar, Field, MISSING + make_dataclass, replace, InitVar, Field, MISSING, is_dataclass, ) import pickle @@ -1365,27 +1365,32 @@ class C: self.assertIs(C().x, int) - def test_isdataclass(self): - # There is no isdataclass() helper any more, but the PEP - # describes how to write it, so make sure that works. Note - # that this version returns True for both classes and - # instances. - def isdataclass(obj): - try: - fields(obj) - return True - except TypeError: - return False + def test_is_dataclass(self): + class NotDataClass: + pass - self.assertFalse(isdataclass(0)) - self.assertFalse(isdataclass(int)) + self.assertFalse(is_dataclass(0)) + self.assertFalse(is_dataclass(int)) + self.assertFalse(is_dataclass(NotDataClass)) + self.assertFalse(is_dataclass(NotDataClass())) @dataclass class C: x: int - self.assertTrue(isdataclass(C)) - self.assertTrue(isdataclass(C(0))) + @dataclass + class D: + d: C + e: int + + c = C(10) + d = D(c, 4) + + self.assertTrue(is_dataclass(C)) + self.assertTrue(is_dataclass(c)) + self.assertFalse(is_dataclass(c.x)) + self.assertTrue(is_dataclass(d.d)) + self.assertFalse(is_dataclass(d.e)) def test_helper_fields_with_class_instance(self): # Check that we can call fields() on either a class or instance, diff --git a/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst b/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst new file mode 100644 index 00000000000..bf3e99c8d86 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst @@ -0,0 +1,2 @@ +Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass +or an instance of one. From webhook-mailer at python.org Sat Jan 6 16:14:06 2018 From: webhook-mailer at python.org (Eric V. Smith) Date: Sat, 06 Jan 2018 21:14:06 -0000 Subject: [Python-checkins] bpo-32278: Allow dataclasses.make_dataclass() to omit type information. (gh-5115) Message-ID: https://github.com/python/cpython/commit/ed7d429ebb591f65cef558760fb4ebdc4fc8f8b0 commit: ed7d429ebb591f65cef558760fb4ebdc4fc8f8b0 branch: master author: Eric V. Smith committer: GitHub date: 2018-01-06T16:14:03-05:00 summary: bpo-32278: Allow dataclasses.make_dataclass() to omit type information. (gh-5115) files: A Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst M Lib/dataclasses.py M Lib/test/test_dataclasses.py diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index b4786bf502e..c4e94b8f667 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -708,9 +708,10 @@ def _astuple_inner(obj, tuple_factory): def make_dataclass(cls_name, fields, *, bases=(), namespace=None): """Return a new dynamically created dataclass. - The dataclass name will be 'cls_name'. 'fields' is an interable - of either (name, type) or (name, type, Field) objects. Field - objects are created by calling 'field(name, type [, Field])'. + The dataclass name will be 'cls_name'. 'fields' is an iterable + of either (name), (name, type) or (name, type, Field) objects. If type is + omitted, use the string 'typing.Any'. Field objects are created by + calling 'field(name, type [, Field])'. C = make_class('C', [('a', int', ('b', int, Field(init=False))], bases=Base) @@ -730,12 +731,19 @@ class C(Base): # Copy namespace since we're going to mutate it. namespace = namespace.copy() - anns = collections.OrderedDict((name, tp) for name, tp, *_ in fields) - namespace['__annotations__'] = anns + anns = collections.OrderedDict() for item in fields: - if len(item) == 3: + if isinstance(item, str): + name = item + tp = 'typing.Any' + elif len(item) == 2: + name, tp, = item + elif len(item) == 3: name, tp, spec = item namespace[name] = spec + anns[name] = tp + + namespace['__annotations__'] = anns cls = type(cls_name, bases, namespace) return dataclass(cls) diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index fca384d8c3c..c44c53d039d 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2033,6 +2033,20 @@ def test_helper_make_dataclass_class_var(self): self.assertEqual(C.y, 10) self.assertEqual(C.z, 20) + def test_helper_make_dataclass_no_types(self): + C = make_dataclass('Point', ['x', 'y', 'z']) + c = C(1, 2, 3) + self.assertEqual(vars(c), {'x': 1, 'y': 2, 'z': 3}) + self.assertEqual(C.__annotations__, {'x': 'typing.Any', + 'y': 'typing.Any', + 'z': 'typing.Any'}) + + C = make_dataclass('Point', ['x', ('y', int), 'z']) + c = C(1, 2, 3) + self.assertEqual(vars(c), {'x': 1, 'y': 2, 'z': 3}) + self.assertEqual(C.__annotations__, {'x': 'typing.Any', + 'y': int, + 'z': 'typing.Any'}) class TestDocString(unittest.TestCase): def assertDocStrEqual(self, a, b): diff --git a/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst b/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst new file mode 100644 index 00000000000..c627468072e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst @@ -0,0 +1,2 @@ +Make type information optional on dataclasses.make_dataclass(). If omitted, +the string 'typing.Any' is used. From webhook-mailer at python.org Sat Jan 6 17:10:01 2018 From: webhook-mailer at python.org (Eric V. Smith) Date: Sat, 06 Jan 2018 22:10:01 -0000 Subject: [Python-checkins] bpo-32279: Add additional params to make_dataclass(), pass through to dataclass(). (gh-5117) Message-ID: https://github.com/python/cpython/commit/d80b443f02e087dd289ffefd04179c675304d76d commit: d80b443f02e087dd289ffefd04179c675304d76d branch: master author: Eric V. Smith committer: GitHub date: 2018-01-06T17:09:58-05:00 summary: bpo-32279: Add additional params to make_dataclass(), pass through to dataclass(). (gh-5117) files: A Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst M Lib/dataclasses.py M Lib/test/test_dataclasses.py diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index c4e94b8f667..62b7c5ed70a 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -705,7 +705,8 @@ def _astuple_inner(obj, tuple_factory): return deepcopy(obj) -def make_dataclass(cls_name, fields, *, bases=(), namespace=None): +def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, + repr=True, eq=True, order=False, hash=None, frozen=False): """Return a new dynamically created dataclass. The dataclass name will be 'cls_name'. 'fields' is an iterable @@ -723,6 +724,9 @@ class C(Base): b: int = field(init=False) For the bases and namespace paremeters, see the builtin type() function. + + The parameters init, repr, eq, order, hash, and frozen are passed to + dataclass(). """ if namespace is None: @@ -745,8 +749,8 @@ class C(Base): namespace['__annotations__'] = anns cls = type(cls_name, bases, namespace) - return dataclass(cls) - + return dataclass(cls, init=init, repr=repr, eq=eq, order=order, + hash=hash, frozen=frozen) def replace(obj, **changes): """Return a new object replacing specified fields with new values. diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index c44c53d039d..69819ea4507 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -2033,6 +2033,23 @@ def test_helper_make_dataclass_class_var(self): self.assertEqual(C.y, 10) self.assertEqual(C.z, 20) + def test_helper_make_dataclass_other_params(self): + C = make_dataclass('C', + [('x', int), + ('y', ClassVar[int], 10), + ('z', ClassVar[int], field(default=20)), + ], + init=False) + # Make sure we have a repr, but no init. + self.assertNotIn('__init__', vars(C)) + self.assertIn('__repr__', vars(C)) + + # Make sure random other params don't work. + with self.assertRaisesRegex(TypeError, 'unexpected keyword argument'): + C = make_dataclass('C', + [], + xxinit=False) + def test_helper_make_dataclass_no_types(self): C = make_dataclass('Point', ['x', 'y', 'z']) c = C(1, 2, 3) diff --git a/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst b/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst new file mode 100644 index 00000000000..b7ef8c80f5a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst @@ -0,0 +1,2 @@ +Add params to dataclasses.make_dataclasses(): init, repr, eq, order, hash, +and frozen. Pass them through to dataclass(). From webhook-mailer at python.org Sat Jan 6 21:05:21 2018 From: webhook-mailer at python.org (Steve Dower) Date: Sun, 07 Jan 2018 02:05:21 -0000 Subject: [Python-checkins] bpo-32282: Remove unnecessary check for `VersionHelpers.h` in `socketmodule.c` on Windows Message-ID: https://github.com/python/cpython/commit/af11a15c586e980a157c04ee60b6e33dc7228f3f commit: af11a15c586e980a157c04ee60b6e33dc7228f3f branch: master author: Max B?langer committer: Steve Dower date: 2018-01-07T13:05:18+11:00 summary: bpo-32282: Remove unnecessary check for `VersionHelpers.h` in `socketmodule.c` on Windows files: A Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst M Modules/socketmodule.c diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst new file mode 100644 index 00000000000..1c833c5439b --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst @@ -0,0 +1,2 @@ +Fix an unnecessary ifdef in the include of VersionHelpers.h in socketmodule +on Windows. diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index d52d9db743a..d75a51af9a6 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -297,10 +297,8 @@ if_indextoname(index) -- return the corresponding interface name\n\ # include # endif -#if defined(_MSC_VER) && _MSC_VER >= 1800 /* Provides the IsWindows7SP1OrGreater() function */ #include -#endif #endif @@ -6552,15 +6550,7 @@ PyInit__socket(void) #ifdef MS_WINDOWS if (support_wsa_no_inherit == -1) { -#if defined(_MSC_VER) && _MSC_VER >= 1800 support_wsa_no_inherit = IsWindows7SP1OrGreater(); -#else - DWORD version = GetVersion(); - DWORD major = (DWORD)LOBYTE(LOWORD(version)); - DWORD minor = (DWORD)HIBYTE(LOWORD(version)); - /* need Windows 7 SP1, 2008 R2 SP1 or later */ - support_wsa_no_inherit = major > 6 || (major == 6 && minor >= 1); -#endif } #endif From webhook-mailer at python.org Sat Jan 6 21:41:20 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 02:41:20 -0000 Subject: [Python-checkins] Kill the AppVeyor file whitelist (GH-5121) Message-ID: https://github.com/python/cpython/commit/7f7de371f947dc38e67505601927e9bc58fa268a commit: 7f7de371f947dc38e67505601927e9bc58fa268a branch: master author: Zachary Ware committer: GitHub date: 2018-01-06T20:41:17-06:00 summary: Kill the AppVeyor file whitelist (GH-5121) It's more trouble than it's worth, since AppVeyor only checks the HEAD commit of a PR rather than the full diff against the base branch to decide which files changed. files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index b052b28f8aa..b7a01335d61 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -16,20 +16,3 @@ environment: HOST_PYTHON: C:\Python36\python.exe image: - Visual Studio 2017 - -# Only trigger AppVeyor if actual code or its configuration changes -only_commits: - files: - - .github/appveyor.yml - - .gitattributes - - Grammar/ - - Include/ - - Lib/ - - Modules/ - - Objects/ - - PC/ - - PCbuild/ - - Parser/ - - Programs/ - - Python/ - - Tools/ From webhook-mailer at python.org Sat Jan 6 22:16:37 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 03:16:37 -0000 Subject: [Python-checkins] [3.6] Kill the AppVeyor file whitelist (GH-5122) Message-ID: https://github.com/python/cpython/commit/157be7ca1de0d046a092e2d44d6d7200de6add8b commit: 157be7ca1de0d046a092e2d44d6d7200de6add8b branch: 3.6 author: Zachary Ware committer: GitHub date: 2018-01-06T21:16:33-06:00 summary: [3.6] Kill the AppVeyor file whitelist (GH-5122) It's more trouble than it's worth, since AppVeyor only checks the HEAD commit of a PR rather than the full diff against the base branch to decide which files changed. (cherry picked from commit 7f7de371f947dc38e67505601927e9bc58fa268a) files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 96674ce84d8..b8a01c313f6 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -17,20 +17,3 @@ environment: image: - Visual Studio 2015 - Visual Studio 2017 - -# Only trigger AppVeyor if actual code or its configuration changes -only_commits: - files: - - .github/appveyor.yml - - .gitattributes - - Grammar/ - - Include/ - - Lib/ - - Modules/ - - Objects/ - - PC/ - - PCBuild/ - - Parser/ - - Programs/ - - Python/ - - Tools/ From webhook-mailer at python.org Sat Jan 6 22:16:59 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 03:16:59 -0000 Subject: [Python-checkins] [2.7] Kill the AppVeyor file whitelist (GH-5123) Message-ID: https://github.com/python/cpython/commit/cd02003b9e1479ac250d6dec4ce75a2ec3d12a71 commit: cd02003b9e1479ac250d6dec4ce75a2ec3d12a71 branch: 2.7 author: Zachary Ware committer: GitHub date: 2018-01-06T21:16:56-06:00 summary: [2.7] Kill the AppVeyor file whitelist (GH-5123) It's more trouble than it's worth, since AppVeyor only checks the HEAD commit of a PR rather than the full diff against the base branch to decide which files changed. (cherry picked from commit 7f7de371f947dc38e67505601927e9bc58fa268a) files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 2cd9a42feb8..43bd7ed9665 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -14,20 +14,3 @@ test_script: - cmd: PCbuild\rt.bat -q -uall -u-cpu -rwW --slowest -j2 environment: HOST_PYTHON: C:\Python36\python.exe - -# Only trigger AppVeyor if actual code or its configuration changes -only_commits: - files: - - .github/appveyor.yml - - .gitattributes - - Grammar/ - - Include/ - - Lib/ - - Modules/ - - Objects/ - - PC/ - - PCBuild/ - - Parser/ - - Programs/ - - Python/ - - Tools/ From solipsis at pitrou.net Sun Jan 7 04:17:04 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Sun, 07 Jan 2018 09:17:04 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=79 Message-ID: <20180107091704.1.C9DC0181CE360C68@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 0, 7] memory blocks, sum=7 test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [0, 0, 44] references, sum=44 test_multiprocessing_fork leaked [0, 0, 22] memory blocks, sum=22 test_multiprocessing_fork leaked [0, 0, 2] file descriptors, sum=2 test_multiprocessing_forkserver leaked [2, -1, -1] memory blocks, sum=0 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogskyxRz', '--timeout', '7200'] From webhook-mailer at python.org Sun Jan 7 08:19:53 2018 From: webhook-mailer at python.org (Eric V. Smith) Date: Sun, 07 Jan 2018 13:19:53 -0000 Subject: [Python-checkins] Fix dataclasses docstring typo. (gh-5118) Message-ID: https://github.com/python/cpython/commit/d327ae6ba157fb5118df28a86975c5ca523f05e2 commit: d327ae6ba157fb5118df28a86975c5ca523f05e2 branch: master author: Eric V. Smith committer: GitHub date: 2018-01-07T08:19:45-05:00 summary: Fix dataclasses docstring typo. (gh-5118) files: M Lib/dataclasses.py diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 62b7c5ed70a..9e186c3c7b7 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -712,9 +712,9 @@ def make_dataclass(cls_name, fields, *, bases=(), namespace=None, init=True, The dataclass name will be 'cls_name'. 'fields' is an iterable of either (name), (name, type) or (name, type, Field) objects. If type is omitted, use the string 'typing.Any'. Field objects are created by - calling 'field(name, type [, Field])'. + the equivalent of calling 'field(name, type [, Field-info])'. - C = make_class('C', [('a', int', ('b', int, Field(init=False))], bases=Base) + C = make_class('C', ['x', ('y', int'), ('z', int, Field(init=False))], bases=[Base]) is equivalent to: From webhook-mailer at python.org Sun Jan 7 08:30:21 2018 From: webhook-mailer at python.org (Nick Coghlan) Date: Sun, 07 Jan 2018 13:30:21 -0000 Subject: [Python-checkins] bpo-30579: Allow TracebackType creation and tb_next mutation from Python (GH-4793) Message-ID: https://github.com/python/cpython/commit/e46a8af450210ee5c7f0459ad6beddbc626ae60f commit: e46a8af450210ee5c7f0459ad6beddbc626ae60f branch: master author: Nathaniel J. Smith committer: Nick Coghlan date: 2018-01-07T23:30:18+10:00 summary: bpo-30579: Allow TracebackType creation and tb_next mutation from Python (GH-4793) Third party projects may wish to hide their own internal machinery in order to present more comprehensible tracebacks to end users (e.g. Jinja2 and Trio both do this). Previously such projects have had to rely on ctypes to do so: https://github.com/pallets/jinja/blob/fe3dadacdf4cf411d0a5b6bbd4d5234697a28af2/jinja2/debug.py#L345 https://github.com/python-trio/trio/blob/1e86b1aee8c0c759f6f239ae53a05d0d3963c629/trio/_core/_multierror.py#L296 This provides a Python level API for creating and modifying real Traceback objects, allowing tracebacks to be edited at runtime. Patch by Nathaniel Smith. files: A Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst A Python/clinic/traceback.c.h M Lib/test/test_raise.py M Python/traceback.c diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index 103f6086d20..c1ef154a9a9 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -228,6 +228,72 @@ def test_accepts_traceback(self): self.fail("No exception raised") +class TestTracebackType(unittest.TestCase): + + def raiser(self): + raise ValueError + + def test_attrs(self): + try: + self.raiser() + except Exception as exc: + tb = exc.__traceback__ + + self.assertIsInstance(tb.tb_next, types.TracebackType) + self.assertIs(tb.tb_frame, sys._getframe()) + self.assertIsInstance(tb.tb_lasti, int) + self.assertIsInstance(tb.tb_lineno, int) + + self.assertIs(tb.tb_next.tb_next, None) + + # Invalid assignments + with self.assertRaises(TypeError): + del tb.tb_next + + with self.assertRaises(TypeError): + tb.tb_next = "asdf" + + # Loops + with self.assertRaises(ValueError): + tb.tb_next = tb + + with self.assertRaises(ValueError): + tb.tb_next.tb_next = tb + + # Valid assignments + tb.tb_next = None + self.assertIs(tb.tb_next, None) + + new_tb = get_tb() + tb.tb_next = new_tb + self.assertIs(tb.tb_next, new_tb) + + def test_constructor(self): + other_tb = get_tb() + frame = sys._getframe() + + tb = types.TracebackType(other_tb, frame, 1, 2) + self.assertEqual(tb.tb_next, other_tb) + self.assertEqual(tb.tb_frame, frame) + self.assertEqual(tb.tb_lasti, 1) + self.assertEqual(tb.tb_lineno, 2) + + tb = types.TracebackType(None, frame, 1, 2) + self.assertEqual(tb.tb_next, None) + + with self.assertRaises(TypeError): + types.TracebackType("no", frame, 1, 2) + + with self.assertRaises(TypeError): + types.TracebackType(other_tb, "no", 1, 2) + + with self.assertRaises(TypeError): + types.TracebackType(other_tb, frame, "no", 2) + + with self.assertRaises(TypeError): + types.TracebackType(other_tb, frame, 1, "nuh-uh") + + class TestContext(unittest.TestCase): def test_instance_context_instance_raise(self): context = IndexError() diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst new file mode 100644 index 00000000000..392ebf6a79e --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst @@ -0,0 +1,2 @@ +Implement TracebackType.__new__ to allow Python-level creation of +traceback objects, and make TracebackType.tb_next mutable. diff --git a/Python/clinic/traceback.c.h b/Python/clinic/traceback.c.h new file mode 100644 index 00000000000..d9daccbbb74 --- /dev/null +++ b/Python/clinic/traceback.c.h @@ -0,0 +1,35 @@ +/*[clinic input] +preserve +[clinic start generated code]*/ + +PyDoc_STRVAR(tb_new__doc__, +"TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno)\n" +"--\n" +"\n" +"Create a new traceback object."); + +static PyObject * +tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, + int tb_lasti, int tb_lineno); + +static PyObject * +tb_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + PyObject *return_value = NULL; + static const char * const _keywords[] = {"tb_next", "tb_frame", "tb_lasti", "tb_lineno", NULL}; + static _PyArg_Parser _parser = {"OO!ii:TracebackType", _keywords, 0}; + PyObject *tb_next; + PyFrameObject *tb_frame; + int tb_lasti; + int tb_lineno; + + if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser, + &tb_next, &PyFrame_Type, &tb_frame, &tb_lasti, &tb_lineno)) { + goto exit; + } + return_value = tb_new_impl(type, tb_next, tb_frame, tb_lasti, tb_lineno); + +exit: + return return_value; +} +/*[clinic end generated code: output=0133130d7d19556f input=a9049054013a1b77]*/ diff --git a/Python/traceback.c b/Python/traceback.c index 831b4f26249..b00864b06e4 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -27,6 +27,65 @@ _Py_IDENTIFIER(close); _Py_IDENTIFIER(open); _Py_IDENTIFIER(path); +/*[clinic input] +class TracebackType "PyTracebackObject *" "&PyTraceback_Type" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=928fa06c10151120]*/ + +#include "clinic/traceback.c.h" + +static PyObject * +tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti, + int lineno) +{ + PyTracebackObject *tb; + if ((next != NULL && !PyTraceBack_Check(next)) || + frame == NULL || !PyFrame_Check(frame)) { + PyErr_BadInternalCall(); + return NULL; + } + tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); + if (tb != NULL) { + Py_XINCREF(next); + tb->tb_next = next; + Py_XINCREF(frame); + tb->tb_frame = frame; + tb->tb_lasti = lasti; + tb->tb_lineno = lineno; + PyObject_GC_Track(tb); + } + return (PyObject *)tb; +} + +/*[clinic input] + at classmethod +TracebackType.__new__ as tb_new + + tb_next: object + tb_frame: object(type='PyFrameObject *', subclass_of='&PyFrame_Type') + tb_lasti: int + tb_lineno: int + +Create a new traceback object. +[clinic start generated code]*/ + +static PyObject * +tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame, + int tb_lasti, int tb_lineno) +/*[clinic end generated code: output=fa077debd72d861a input=01cbe8ec8783fca7]*/ +{ + if (tb_next == Py_None) { + tb_next = NULL; + } else if (!PyTraceBack_Check(tb_next)) { + return PyErr_Format(PyExc_TypeError, + "expected traceback object or None, got '%s'", + Py_TYPE(tb_next)->tp_name); + } + + return tb_create_raw((PyTracebackObject *)tb_next, tb_frame, tb_lasti, + tb_lineno); +} + static PyObject * tb_dir(PyTracebackObject *self) { @@ -34,19 +93,72 @@ tb_dir(PyTracebackObject *self) "tb_lasti", "tb_lineno"); } +static PyObject * +tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_)) +{ + PyObject* ret = (PyObject*)self->tb_next; + if (!ret) { + ret = Py_None; + } + Py_INCREF(ret); + return ret; +} + +static int +tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_)) +{ + if (!new_next) { + PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute"); + return -1; + } + + /* We accept None or a traceback object, and map None -> NULL (inverse of + tb_next_get) */ + if (new_next == Py_None) { + new_next = NULL; + } else if (!PyTraceBack_Check(new_next)) { + PyErr_Format(PyExc_TypeError, + "expected traceback object, got '%s'", + Py_TYPE(new_next)->tp_name); + return -1; + } + + /* Check for loops */ + PyTracebackObject *cursor = (PyTracebackObject *)new_next; + while (cursor) { + if (cursor == self) { + PyErr_Format(PyExc_ValueError, "traceback loop detected"); + return -1; + } + cursor = cursor->tb_next; + } + + PyObject *old_next = (PyObject*)self->tb_next; + Py_XINCREF(new_next); + self->tb_next = (PyTracebackObject *)new_next; + Py_XDECREF(old_next); + + return 0; +} + + static PyMethodDef tb_methods[] = { {"__dir__", (PyCFunction)tb_dir, METH_NOARGS}, {NULL, NULL, 0, NULL}, }; static PyMemberDef tb_memberlist[] = { - {"tb_next", T_OBJECT, OFF(tb_next), READONLY}, {"tb_frame", T_OBJECT, OFF(tb_frame), READONLY}, {"tb_lasti", T_INT, OFF(tb_lasti), READONLY}, {"tb_lineno", T_INT, OFF(tb_lineno), READONLY}, {NULL} /* Sentinel */ }; +static PyGetSetDef tb_getsetters[] = { + {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL}, + {NULL} /* Sentinel */ +}; + static void tb_dealloc(PyTracebackObject *tb) { @@ -94,7 +206,7 @@ PyTypeObject PyTraceBack_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ - 0, /* tp_doc */ + tb_new__doc__, /* tp_doc */ (traverseproc)tb_traverse, /* tp_traverse */ (inquiry)tb_clear, /* tp_clear */ 0, /* tp_richcompare */ @@ -103,39 +215,24 @@ PyTypeObject PyTraceBack_Type = { 0, /* tp_iternext */ tb_methods, /* tp_methods */ tb_memberlist, /* tp_members */ - 0, /* tp_getset */ + tb_getsetters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + tb_new, /* tp_new */ }; -static PyTracebackObject * -newtracebackobject(PyTracebackObject *next, PyFrameObject *frame) -{ - PyTracebackObject *tb; - if ((next != NULL && !PyTraceBack_Check(next)) || - frame == NULL || !PyFrame_Check(frame)) { - PyErr_BadInternalCall(); - return NULL; - } - tb = PyObject_GC_New(PyTracebackObject, &PyTraceBack_Type); - if (tb != NULL) { - Py_XINCREF(next); - tb->tb_next = next; - Py_XINCREF(frame); - tb->tb_frame = frame; - tb->tb_lasti = frame->f_lasti; - tb->tb_lineno = PyFrame_GetLineNumber(frame); - PyObject_GC_Track(tb); - } - return tb; -} - int PyTraceBack_Here(PyFrameObject *frame) { PyObject *exc, *val, *tb, *newtb; PyErr_Fetch(&exc, &val, &tb); - newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame); + newtb = tb_create_raw((PyTracebackObject *)tb, frame, frame->f_lasti, + PyFrame_GetLineNumber(frame)); if (newtb == NULL) { _PyErr_ChainExceptions(exc, val, tb); return -1; From webhook-mailer at python.org Sun Jan 7 10:54:37 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 07 Jan 2018 15:54:37 -0000 Subject: [Python-checkins] bpo-31802: Fix importing native path module before importing os. (#4017) Message-ID: https://github.com/python/cpython/commit/3460198f6ba40a839f105c381f07179aba1e8c61 commit: 3460198f6ba40a839f105c381f07179aba1e8c61 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-07T17:54:31+02:00 summary: bpo-31802: Fix importing native path module before importing os. (#4017) files: A Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst M Lib/macpath.py M Lib/ntpath.py M Lib/posixpath.py M Lib/test/test_genericpath.py diff --git a/Lib/macpath.py b/Lib/macpath.py index f85a91435b9..aacf7235b01 100644 --- a/Lib/macpath.py +++ b/Lib/macpath.py @@ -1,5 +1,17 @@ """Pathname and path-related operations for the Macintosh.""" +# strings representing various path-related bits and pieces +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = ':' +pardir = '::' +extsep = '.' +sep = ':' +pathsep = '\n' +defpath = ':' +altsep = None +devnull = 'Dev:Null' + import os from stat import * import genericpath @@ -16,17 +28,6 @@ "curdir","pardir","sep","pathsep","defpath","altsep","extsep", "devnull","realpath","supports_unicode_filenames"] -# strings representing various path-related bits and pieces -# These are primarily for export; internally, they are hardcoded. -curdir = ':' -pardir = '::' -extsep = '.' -sep = ':' -pathsep = '\n' -defpath = ':' -altsep = None -devnull = 'Dev:Null' - def _get_colon(path): if isinstance(path, bytes): return b':' diff --git a/Lib/ntpath.py b/Lib/ntpath.py index 10d3f2dc35b..2182ec776cc 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -5,6 +5,18 @@ module as os.path. """ +# strings representing various path-related bits and pieces +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '\\' +pathsep = ';' +altsep = '/' +defpath = '.;C:\\bin' +devnull = 'nul' + import os import sys import stat @@ -19,17 +31,6 @@ "extsep","devnull","realpath","supports_unicode_filenames","relpath", "samefile", "sameopenfile", "samestat", "commonpath"] -# strings representing various path-related bits and pieces -# These are primarily for export; internally, they are hardcoded. -curdir = '.' -pardir = '..' -extsep = '.' -sep = '\\' -pathsep = ';' -altsep = '/' -defpath = '.;C:\\bin' -devnull = 'nul' - def _get_bothseps(path): if isinstance(path, bytes): return b'\\/' diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 6dbdab27497..e92186c64e0 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -10,6 +10,18 @@ for manipulation of the pathname component of URLs. """ +# Strings representing various path-related bits and pieces. +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '/' +pathsep = ':' +defpath = ':/bin:/usr/bin' +altsep = None +devnull = '/dev/null' + import os import sys import stat @@ -25,16 +37,6 @@ "devnull","realpath","supports_unicode_filenames","relpath", "commonpath"] -# Strings representing various path-related bits and pieces. -# These are primarily for export; internally, they are hardcoded. -curdir = '.' -pardir = '..' -extsep = '.' -sep = '/' -pathsep = ':' -defpath = ':/bin:/usr/bin' -altsep = None -devnull = '/dev/null' def _get_sep(path): if isinstance(path, bytes): diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 01e11da0980..ad5a59c44ed 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -8,6 +8,7 @@ import unittest import warnings from test import support +from test.support.script_helper import assert_python_ok def create_file(filename, data=b'foo'): @@ -486,6 +487,9 @@ def test_relpath_errors(self): with self.assertRaisesRegex(TypeError, 'bytearray'): self.pathmodule.relpath(bytearray(b'foo'), bytearray(b'bar')) + def test_import(self): + assert_python_ok('-S', '-c', 'import ' + self.pathmodule.__name__) + class PathLikeTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst b/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst new file mode 100644 index 00000000000..77df6bbe695 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst @@ -0,0 +1,2 @@ +Importing native path module (``posixpath``, ``ntpath``) now works even if +the ``os`` module still is not imported. From webhook-mailer at python.org Sun Jan 7 11:35:30 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Sun, 07 Jan 2018 16:35:30 -0000 Subject: [Python-checkins] bpo-31802: Fix importing native path module before importing os. (GH-4017) (#5129) Message-ID: https://github.com/python/cpython/commit/94a3facc0e5ce02ef34d9fa595703cd96cb95984 commit: 94a3facc0e5ce02ef34d9fa595703cd96cb95984 branch: 3.6 author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com> committer: Serhiy Storchaka date: 2018-01-07T18:35:28+02:00 summary: bpo-31802: Fix importing native path module before importing os. (GH-4017) (#5129) (cherry picked from commit 3460198f6ba40a839f105c381f07179aba1e8c61) files: A Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst M Lib/macpath.py M Lib/ntpath.py M Lib/posixpath.py M Lib/test/test_genericpath.py diff --git a/Lib/macpath.py b/Lib/macpath.py index a90d1053bc8..d15b7e1e9e2 100644 --- a/Lib/macpath.py +++ b/Lib/macpath.py @@ -1,5 +1,17 @@ """Pathname and path-related operations for the Macintosh.""" +# strings representing various path-related bits and pieces +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = ':' +pardir = '::' +extsep = '.' +sep = ':' +pathsep = '\n' +defpath = ':' +altsep = None +devnull = 'Dev:Null' + import os from stat import * import genericpath @@ -12,17 +24,6 @@ "curdir","pardir","sep","pathsep","defpath","altsep","extsep", "devnull","realpath","supports_unicode_filenames"] -# strings representing various path-related bits and pieces -# These are primarily for export; internally, they are hardcoded. -curdir = ':' -pardir = '::' -extsep = '.' -sep = ':' -pathsep = '\n' -defpath = ':' -altsep = None -devnull = 'Dev:Null' - def _get_colon(path): if isinstance(path, bytes): return b':' diff --git a/Lib/ntpath.py b/Lib/ntpath.py index a8f4b37f648..a5e79ba6637 100644 --- a/Lib/ntpath.py +++ b/Lib/ntpath.py @@ -5,6 +5,18 @@ module as os.path. """ +# strings representing various path-related bits and pieces +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '\\' +pathsep = ';' +altsep = '/' +defpath = '.;C:\\bin' +devnull = 'nul' + import os import sys import stat @@ -19,17 +31,6 @@ "extsep","devnull","realpath","supports_unicode_filenames","relpath", "samefile", "sameopenfile", "samestat", "commonpath"] -# strings representing various path-related bits and pieces -# These are primarily for export; internally, they are hardcoded. -curdir = '.' -pardir = '..' -extsep = '.' -sep = '\\' -pathsep = ';' -altsep = '/' -defpath = '.;C:\\bin' -devnull = 'nul' - def _get_bothseps(path): if isinstance(path, bytes): return b'\\/' diff --git a/Lib/posixpath.py b/Lib/posixpath.py index 6dbdab27497..e92186c64e0 100644 --- a/Lib/posixpath.py +++ b/Lib/posixpath.py @@ -10,6 +10,18 @@ for manipulation of the pathname component of URLs. """ +# Strings representing various path-related bits and pieces. +# These are primarily for export; internally, they are hardcoded. +# Should be set before imports for resolving cyclic dependency. +curdir = '.' +pardir = '..' +extsep = '.' +sep = '/' +pathsep = ':' +defpath = ':/bin:/usr/bin' +altsep = None +devnull = '/dev/null' + import os import sys import stat @@ -25,16 +37,6 @@ "devnull","realpath","supports_unicode_filenames","relpath", "commonpath"] -# Strings representing various path-related bits and pieces. -# These are primarily for export; internally, they are hardcoded. -curdir = '.' -pardir = '..' -extsep = '.' -sep = '/' -pathsep = ':' -defpath = ':/bin:/usr/bin' -altsep = None -devnull = '/dev/null' def _get_sep(path): if isinstance(path, bytes): diff --git a/Lib/test/test_genericpath.py b/Lib/test/test_genericpath.py index 01e11da0980..ad5a59c44ed 100644 --- a/Lib/test/test_genericpath.py +++ b/Lib/test/test_genericpath.py @@ -8,6 +8,7 @@ import unittest import warnings from test import support +from test.support.script_helper import assert_python_ok def create_file(filename, data=b'foo'): @@ -486,6 +487,9 @@ def test_relpath_errors(self): with self.assertRaisesRegex(TypeError, 'bytearray'): self.pathmodule.relpath(bytearray(b'foo'), bytearray(b'bar')) + def test_import(self): + assert_python_ok('-S', '-c', 'import ' + self.pathmodule.__name__) + class PathLikeTests(unittest.TestCase): diff --git a/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst b/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst new file mode 100644 index 00000000000..77df6bbe695 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst @@ -0,0 +1,2 @@ +Importing native path module (``posixpath``, ``ntpath``) now works even if +the ``os`` module still is not imported. From webhook-mailer at python.org Sun Jan 7 13:59:51 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 18:59:51 -0000 Subject: [Python-checkins] Fix version in AppVeyor config (GH-5124) Message-ID: https://github.com/python/cpython/commit/b216a253129b41d7792417bcd7737b2ebdb26c9a commit: b216a253129b41d7792417bcd7737b2ebdb26c9a branch: master author: Zachary Ware committer: GitHub date: 2018-01-07T12:59:48-06:00 summary: Fix version in AppVeyor config (GH-5124) files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index b7a01335d61..b7d40787318 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.7.0a0.{build} +version: 3.7build{build} clone_depth: 5 branches: only: From webhook-mailer at python.org Sun Jan 7 14:00:36 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 19:00:36 -0000 Subject: [Python-checkins] Fix version in AppVeyor config (GH-5125) Message-ID: https://github.com/python/cpython/commit/9c99fd163d5ca9bcc0b7ddd0d1e3b8717a63237c commit: 9c99fd163d5ca9bcc0b7ddd0d1e3b8717a63237c branch: 3.6 author: Zachary Ware committer: GitHub date: 2018-01-07T13:00:33-06:00 summary: Fix version in AppVeyor config (GH-5125) files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index b8a01c313f6..162a7d8a701 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,4 +1,4 @@ -version: 3.6.1+.{build} +version: 3.6build{build} clone_depth: 5 branches: only: From webhook-mailer at python.org Sun Jan 7 14:00:59 2018 From: webhook-mailer at python.org (Zachary Ware) Date: Sun, 07 Jan 2018 19:00:59 -0000 Subject: [Python-checkins] Fix version in AppVeyor config (GH-5126) Message-ID: https://github.com/python/cpython/commit/0ebf0ae6a2b055f6a2373d9d1976f6b243ed8b00 commit: 0ebf0ae6a2b055f6a2373d9d1976f6b243ed8b00 branch: 2.7 author: Zachary Ware committer: GitHub date: 2018-01-07T13:00:56-06:00 summary: Fix version in AppVeyor config (GH-5126) files: M .github/appveyor.yml diff --git a/.github/appveyor.yml b/.github/appveyor.yml index 43bd7ed9665..ddd5b15c5aa 100644 --- a/.github/appveyor.yml +++ b/.github/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.7.13+.{build} +version: 2.7build{build} clone_depth: 5 branches: only: From webhook-mailer at python.org Sun Jan 7 14:30:19 2018 From: webhook-mailer at python.org (Eric V. Smith) Date: Sun, 07 Jan 2018 19:30:19 -0000 Subject: [Python-checkins] bpo-32506: Change dataclasses from OrderedDict to plain dict. (gh-5131) Message-ID: https://github.com/python/cpython/commit/d13889214a4c81b78fa8683d35bdbd17ff22f4fe commit: d13889214a4c81b78fa8683d35bdbd17ff22f4fe branch: master author: Eric V. Smith committer: GitHub date: 2018-01-07T14:30:17-05:00 summary: bpo-32506: Change dataclasses from OrderedDict to plain dict. (gh-5131) files: A Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst M Lib/dataclasses.py diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 9e186c3c7b7..d80054920ce 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -1,7 +1,6 @@ import sys import types from copy import deepcopy -import collections import inspect __all__ = ['dataclass', @@ -448,11 +447,11 @@ def _set_attribute(cls, name, value): def _process_class(cls, repr, eq, order, hash, init, frozen): - # Use an OrderedDict because: - # - Order matters! - # - Derived class fields overwrite base class fields, but the - # order is defined by the base class, which is found first. - fields = collections.OrderedDict() + # Now that dicts retain insertion order, there's no reason to use + # an ordered dict. I am leveraging that ordering here, because + # derived class fields overwrite base class fields, but the order + # is defined by the base class, which is found first. + fields = {} # Find our base classes in reverse MRO order, and exclude # ourselves. In reversed order so that more derived classes @@ -612,7 +611,8 @@ def fields(class_or_instance): except AttributeError: raise TypeError('must be called with a dataclass type or instance') - # Exclude pseudo-fields. + # Exclude pseudo-fields. Note that fields is sorted by insertion + # order, so the order of the tuple is as the fields were defined. return tuple(f for f in fields.values() if f._field_type is _FIELD) @@ -735,7 +735,7 @@ class C(Base): # Copy namespace since we're going to mutate it. namespace = namespace.copy() - anns = collections.OrderedDict() + anns = {} for item in fields: if isinstance(item, str): name = item diff --git a/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst b/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst new file mode 100644 index 00000000000..e524769c6df --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst @@ -0,0 +1,2 @@ +Now that dict is defined as keeping insertion order, drop OrderedDict and +just use plain dict. From webhook-mailer at python.org Sun Jan 7 21:45:05 2018 From: webhook-mailer at python.org (Nick Coghlan) Date: Mon, 08 Jan 2018 02:45:05 -0000 Subject: [Python-checkins] bpo-31975 (PEP 565): Show DeprecationWarning in __main__ (GH-4458) Message-ID: https://github.com/python/cpython/commit/9b99747386b690007027c3be2a5d7cfe3d3634f5 commit: 9b99747386b690007027c3be2a5d7cfe3d3634f5 branch: master author: Nick Coghlan committer: GitHub date: 2018-01-08T12:45:02+10:00 summary: bpo-31975 (PEP 565): Show DeprecationWarning in __main__ (GH-4458) - primary change is to add a new default filter entry for 'default::DeprecationWarning:__main__' - secondary change is an internal one to cope with plain strings in the warning module's internal filter list (this avoids the need to create a compiled regex object early on during interpreter startup) - assorted documentation updates, including many more examples of configuring the warnings settings - additional tests to ensure that both the pure Python and the C accelerated warnings modules have the expected default configuration files: A Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst M Doc/library/exceptions.rst M Doc/library/warnings.rst M Doc/tools/susp-ignored.csv M Doc/using/cmdline.rst M Doc/whatsnew/3.7.rst M Lib/test/test_cmd_line.py M Lib/test/test_warnings/__init__.py M Lib/warnings.py M Python/_warnings.c diff --git a/Doc/library/exceptions.rst b/Doc/library/exceptions.rst index c8d32cff4e0..aa3141053b3 100644 --- a/Doc/library/exceptions.rst +++ b/Doc/library/exceptions.rst @@ -661,11 +661,13 @@ depending on the system error code. :pep:`3151` - Reworking the OS and IO exception hierarchy +.. _warning-categories-as-exceptions: + Warnings -------- -The following exceptions are used as warning categories; see the :mod:`warnings` -module for more information. +The following exceptions are used as warning categories; see the +:ref:`warning-categories` documentation for more details. .. exception:: Warning @@ -679,12 +681,14 @@ module for more information. .. exception:: DeprecationWarning - Base class for warnings about deprecated features. + Base class for warnings about deprecated features when those warnings are + intended for other Python developers. .. exception:: PendingDeprecationWarning - Base class for warnings about features which will be deprecated in the future. + Base class for warnings about features which will be deprecated in the + future. .. exception:: SyntaxWarning @@ -699,8 +703,8 @@ module for more information. .. exception:: FutureWarning - Base class for warnings about constructs that will change semantically in the - future. + Base class for warnings about deprecated features when those warnings are + intended for end users of applications that are written in Python. .. exception:: ImportWarning @@ -720,7 +724,8 @@ module for more information. .. exception:: ResourceWarning - Base class for warnings related to resource usage. + Base class for warnings related to resource usage. Ignored by the default + warning filters. .. versionadded:: 3.2 diff --git a/Doc/library/warnings.rst b/Doc/library/warnings.rst index f67f4bc24c4..b04bd79e4bb 100644 --- a/Doc/library/warnings.rst +++ b/Doc/library/warnings.rst @@ -51,8 +51,17 @@ Warning Categories ------------------ There are a number of built-in exceptions that represent warning categories. -This categorization is useful to be able to filter out groups of warnings. The -following warnings category classes are currently defined: +This categorization is useful to be able to filter out groups of warnings. + +While these are technically +:ref:`built-in exceptions `, they are +documented here, because conceptually they belong to the warnings mechanism. + +User code can define additional warning categories by subclassing one of the +standard warning categories. A warning category must always be a subclass of +the :exc:`Warning` class. + +The following warnings category classes are currently defined: .. tabularcolumns:: |l|p{0.6\linewidth}| @@ -66,7 +75,9 @@ following warnings category classes are currently defined: | :exc:`UserWarning` | The default category for :func:`warn`. | +----------------------------------+-----------------------------------------------+ | :exc:`DeprecationWarning` | Base category for warnings about deprecated | -| | features (ignored by default). | +| | features when those warnings are intended for | +| | other Python developers (ignored by default, | +| | unless triggered by code in ``__main__``). | +----------------------------------+-----------------------------------------------+ | :exc:`SyntaxWarning` | Base category for warnings about dubious | | | syntactic features. | @@ -74,8 +85,10 @@ following warnings category classes are currently defined: | :exc:`RuntimeWarning` | Base category for warnings about dubious | | | runtime features. | +----------------------------------+-----------------------------------------------+ -| :exc:`FutureWarning` | Base category for warnings about constructs | -| | that will change semantically in the future. | +| :exc:`FutureWarning` | Base category for warnings about deprecated | +| | features when those warnings are intended for | +| | end users of applications that are written in | +| | Python. | +----------------------------------+-----------------------------------------------+ | :exc:`PendingDeprecationWarning` | Base category for warnings about features | | | that will be deprecated in the future | @@ -95,13 +108,12 @@ following warnings category classes are currently defined: | | resource usage. | +----------------------------------+-----------------------------------------------+ - -While these are technically built-in exceptions, they are documented here, -because conceptually they belong to the warnings mechanism. - -User code can define additional warning categories by subclassing one of the -standard warning categories. A warning category must always be a subclass of -the :exc:`Warning` class. +.. versionchanged:: 3.7 + Previously :exc:`DeprecationWarning` and :exc:`FutureWarning` were + distinguished based on whether a feature was being removed entirely or + changing its behaviour. They are now distinguished based on their + intended audience and the way they're handled by the default warnings + filters. .. _warning-filter: @@ -114,7 +126,7 @@ into errors (raising an exception). Conceptually, the warnings filter maintains an ordered list of filter specifications; any specific warning is matched against each filter -specification in the list in turn until a match is found; the match determines +specification in the list in turn until a match is found; the filter determines the disposition of the match. Each entry is a tuple of the form (*action*, *message*, *category*, *module*, *lineno*), where: @@ -123,19 +135,19 @@ the disposition of the match. Each entry is a tuple of the form (*action*, +---------------+----------------------------------------------+ | Value | Disposition | +===============+==============================================+ + | ``"default"`` | print the first occurrence of matching | + | | warnings for each location (module + | + | | line number) where the warning is issued | + +---------------+----------------------------------------------+ | ``"error"`` | turn matching warnings into exceptions | +---------------+----------------------------------------------+ | ``"ignore"`` | never print matching warnings | +---------------+----------------------------------------------+ | ``"always"`` | always print matching warnings | +---------------+----------------------------------------------+ - | ``"default"`` | print the first occurrence of matching | - | | warnings for each location where the warning | - | | is issued | - +---------------+----------------------------------------------+ | ``"module"`` | print the first occurrence of matching | | | warnings for each module where the warning | - | | is issued | + | | is issued (regardless of line number) | +---------------+----------------------------------------------+ | ``"once"`` | print only the first occurrence of matching | | | warnings, regardless of location | @@ -157,33 +169,119 @@ the disposition of the match. Each entry is a tuple of the form (*action*, Since the :exc:`Warning` class is derived from the built-in :exc:`Exception` class, to turn a warning into an error we simply raise ``category(message)``. +If a warning is reported and doesn't match any registered filter then the +"default" action is applied (hence its name). + + +.. _describing-warning-filters: + +Describing Warning Filters +~~~~~~~~~~~~~~~~~~~~~~~~~~ + The warnings filter is initialized by :option:`-W` options passed to the Python -interpreter command line. The interpreter saves the arguments for all -:option:`-W` options without interpretation in ``sys.warnoptions``; the -:mod:`warnings` module parses these when it is first imported (invalid options -are ignored, after printing a message to ``sys.stderr``). +interpreter command line and the :envvar:`PYTHONWARNINGS` environment variable. +The interpreter saves the arguments for all supplied entries without +interpretation in ``sys.warnoptions``; the :mod:`warnings` module parses these +when it is first imported (invalid options are ignored, after printing a +message to ``sys.stderr``). + +Individual warnings filters are specified as a sequence of fields separated by +colons:: + action:message:category:module:line -Default Warning Filters -~~~~~~~~~~~~~~~~~~~~~~~ +The meaning of each of these fields is as described in :ref:`warning-filter`. +When listing multiple filters on a single line (as for +:envvar:`PYTHONWARNINGS`), the individual filters are separated by commas,and +the filters listed later take precedence over those listed before them (as +they're applied left-to-right, and the most recently applied filters take +precedence over earlier ones). + +Commonly used warning filters apply to either all warnings, warnings in a +particular category, or warnings raised by particular modules or packages. +Some examples:: + + default # Show all warnings (even those ignored by default) + ignore # Ignore all warnings + error # Convert all warnings to errors + error::ResourceWarning # Treat ResourceWarning messages as errors + default::DeprecationWarning # Show DeprecationWarning messages + ignore,default:::mymodule # Only report warnings triggered by "mymodule" + error:::mymodule[.*] # Convert warnings to errors in "mymodule" + # and any subpackages of "mymodule" + + +.. _default-warning-filter: + +Default Warning Filter +~~~~~~~~~~~~~~~~~~~~~~ By default, Python installs several warning filters, which can be overridden by -the command-line options passed to :option:`-W` and calls to -:func:`filterwarnings`. +the :option:`-W` command-line option, the :envvar:`PYTHONWARNINGS` environment +variable and calls to :func:`filterwarnings`. -* :exc:`DeprecationWarning` and :exc:`PendingDeprecationWarning`, and - :exc:`ImportWarning` are ignored. +In regular release builds, the default warning filter has the following entries +(in order of precedence):: -* :exc:`BytesWarning` is ignored unless the :option:`-b` option is given once or - twice; in this case this warning is either printed (``-b``) or turned into an - exception (``-bb``). + default::DeprecationWarning:__main__ + ignore::DeprecationWarning + ignore::PendingDeprecationWarning + ignore::ImportWarning + ignore::ResourceWarning -* :exc:`ResourceWarning` is ignored unless Python was built in debug mode. +In debug builds, the list of default warning filters is empty. .. versionchanged:: 3.2 :exc:`DeprecationWarning` is now ignored by default in addition to :exc:`PendingDeprecationWarning`. +.. versionchanged:: 3.7 + :exc:`DeprecationWarning` is once again shown by default when triggered + directly by code in ``__main__``. + +.. versionchanged:: 3.7 + :exc:`BytesWarning` no longer appears in the default filter list and is + instead configured via :data:`sys.warnoptions` when :option:`-b` is specified + twice. + + +.. _warning-disable: + +Overriding the default filter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Developers of applications written in Python may wish to hide *all* Python level +warnings from their users by default, and only display them when running tests +or otherwise working on the application. The :data:`sys.warnoptions` attribute +used to pass filter configurations to the interpreter can be used as a marker to +indicate whether or not warnings should be disabled:: + + import sys + + if not sys.warnoptions: + import warnings + warnings.simplefilter("ignore") + +Developers of test runners for Python code are advised to instead ensure that +*all* warnings are displayed by default for the code under test, using code +like:: + + import sys + + if not sys.warnoptions: + import os, warnings + warnings.simplefilter("default") # Change the filter in this process + os.environ["PYTHONWARNINGS"] = "default" # Also affect subprocesses + +Finally, developers of interactive shells that run user code in a namespace +other than ``__main__`` are advised to ensure that :exc:`DeprecationWarning` +messages are made visible by default, using code like the following (where +``user_ns`` is the module used to execute code entered interactively):: + + import warnings + warnings.filterwarnings("default", category=DeprecationWarning, + module=user_ns.get("__name__")) + .. _warning-suppress: @@ -191,7 +289,8 @@ Temporarily Suppressing Warnings -------------------------------- If you are using code that you know will raise a warning, such as a deprecated -function, but do not want to see the warning, then it is possible to suppress +function, but do not want to see the warning (even when warnings have been +explicitly configured via the command line), then it is possible to suppress the warning using the :class:`catch_warnings` context manager:: import warnings @@ -261,38 +360,30 @@ entries from the warnings list before each new operation). .. _warning-ignored: -Updating Code For New Versions of Python ----------------------------------------- - -Warnings that are only of interest to the developer are ignored by default. As -such you should make sure to test your code with typically ignored warnings -made visible. You can do this from the command-line by passing :option:`-Wd <-W>` -to the interpreter (this is shorthand for :option:`!-W default`). This enables -default handling for all warnings, including those that are ignored by default. -To change what action is taken for encountered warnings you simply change what -argument is passed to :option:`-W`, e.g. :option:`!-W error`. See the -:option:`-W` flag for more details on what is possible. - -To programmatically do the same as :option:`!-Wd`, use:: - - warnings.simplefilter('default') - -Make sure to execute this code as soon as possible. This prevents the -registering of what warnings have been raised from unexpectedly influencing how -future warnings are treated. - -Having certain warnings ignored by default is done to prevent a user from -seeing warnings that are only of interest to the developer. As you do not -necessarily have control over what interpreter a user uses to run their code, -it is possible that a new version of Python will be released between your -release cycles. The new interpreter release could trigger new warnings in your -code that were not there in an older interpreter, e.g. -:exc:`DeprecationWarning` for a module that you are using. While you as a -developer want to be notified that your code is using a deprecated module, to a -user this information is essentially noise and provides no benefit to them. - -The :mod:`unittest` module has been also updated to use the ``'default'`` -filter while running tests. +Updating Code For New Versions of Dependencies +---------------------------------------------- + +Warning categories that are primarily of interest to Python developers (rather +than end users of applications written in Python) are ignored by default. + +Notably, this "ignored by default" list includes :exc:`DeprecationWarning` +(for every module except ``__main__``), which means developers should make sure +to test their code with typically ignored warnings made visible in order to +receive timely notifications of future breaking API changes (whether in the +standard library or third party packages). + +In the ideal case, the code will have a suitable test suite, and the test runner +will take care of implicitly enabling all warnings when running tests +(the test runner provided by the :mod:`unittest` module does this). + +In less ideal cases, applications can be checked for use of deprecated +interfaces by passing :option:`-Wd <-W>` to the Python interpreter (this is +shorthand for :option:`!-W default`) or setting ``PYTHONWARNINGS=default`` in +the environment. This enables default handling for all warnings, including those +that are ignored by default. To change what action is taken for encountered +warnings you can change what argument is passed to :option:`-W` (e.g. +:option:`!-W error`). See the :option:`-W` flag for more details on what is +possible. .. _warning-functions: diff --git a/Doc/tools/susp-ignored.csv b/Doc/tools/susp-ignored.csv index 48dd53f85d2..cfdd5266c51 100644 --- a/Doc/tools/susp-ignored.csv +++ b/Doc/tools/susp-ignored.csv @@ -259,12 +259,8 @@ tutorial/stdlib2,,:start,extra = data[start:start+extra_size] tutorial/stdlib2,,:start,"fields = struct.unpack('Lancelot @@ -330,3 +340,4 @@ whatsnew/3.7,,`,'`' whatsnew/3.7,,::,error::BytesWarning whatsnew/changelog,,::,error::BytesWarning whatsnew/changelog,,::,default::BytesWarning +whatsnew/changelog,,::,default::DeprecationWarning diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index b1bd47fa6b9..1e9ed6e645a 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -356,49 +356,27 @@ Miscellaneous options :option:`-W` options are ignored (though, a warning message is printed about invalid options when the first warning is issued). - Warnings can also be controlled from within a Python program using the + Warnings can also be controlled using the :envvar:`PYTHONWARNINGS` + environment variable and from within a Python program using the :mod:`warnings` module. - The simplest form of argument is one of the following action strings (or a - unique abbreviation): - - ``ignore`` - Ignore all warnings. - ``default`` - Explicitly request the default behavior (printing each warning once per - source line). - ``all`` - Print a warning each time it occurs (this may generate many messages if a - warning is triggered repeatedly for the same source line, such as inside a - loop). - ``module`` - Print each warning only the first time it occurs in each module. - ``once`` - Print each warning only the first time it occurs in the program. - ``error`` - Raise an exception instead of printing a warning message. - - The full form of argument is:: - - action:message:category:module:line - - Here, *action* is as explained above but only applies to messages that match - the remaining fields. Empty fields match all values; trailing empty fields - may be omitted. The *message* field matches the start of the warning message - printed; this match is case-insensitive. The *category* field matches the - warning category. This must be a class name; the match tests whether the - actual warning category of the message is a subclass of the specified warning - category. The full class name must be given. The *module* field matches the - (fully-qualified) module name; this match is case-sensitive. The *line* - field matches the line number, where zero matches all line numbers and is - thus equivalent to an omitted line number. + The simplest settings apply a particular action unconditionally to all + warnings emitted by a process (even those that are otherwise ignored by + default):: - .. seealso:: - :mod:`warnings` -- the warnings module + -Wdefault # Warn once per call location + -Werror # Convert to exceptions + -Walways # Warn every time + -Wmodule # Warn once per calling module + -Wonce # Warn once per Python process + -Wignore # Never warn - :pep:`230` -- Warning framework + The action names can be abbreviated as desired (e.g. ``-Wi``, ``-Wd``, + ``-Wa``, ``-We``) and the interpreter will resolve them to the appropriate + action name. - :envvar:`PYTHONWARNINGS` + See :ref:`warning-filter` and :ref:`describing-warning-filters` for more + details. .. cmdoption:: -x @@ -659,7 +637,23 @@ conflict. This is equivalent to the :option:`-W` option. If set to a comma separated string, it is equivalent to specifying :option:`-W` multiple - times. + times, with filters later in the list taking precedence over those earlier + in the list. + + The simplest settings apply a particular action unconditionally to all + warnings emitted by a process (even those that are otherwise ignored by + default):: + + PYTHONWARNINGS=default # Warn once per call location + PYTHONWARNINGS=error # Convert to exceptions + PYTHONWARNINGS=always # Warn every time + PYTHONWARNINGS=module # Warn once per calling module + PYTHONWARNINGS=once # Warn once per Python process + PYTHONWARNINGS=ignore # Never warn + + See :ref:`warning-filter` and :ref:`describing-warning-filters` for more + details. + .. envvar:: PYTHONFAULTHANDLER diff --git a/Doc/whatsnew/3.7.rst b/Doc/whatsnew/3.7.rst index 9785d599dd3..992d9ba6e58 100644 --- a/Doc/whatsnew/3.7.rst +++ b/Doc/whatsnew/3.7.rst @@ -70,6 +70,7 @@ Summary -- Release highlights New Features ============ + .. _whatsnew37-pep538: PEP 538: Legacy C Locale Coercion @@ -107,6 +108,7 @@ locale remains active when the core interpreter is initialized. :pep:`538` -- Coercing the legacy C locale to a UTF-8 based locale PEP written and implemented by Nick Coghlan. + .. _whatsnew37-pep553: PEP 553: Built-in breakpoint() @@ -203,6 +205,44 @@ resolution on Linux and Windows. PEP written and implemented by Victor Stinner +.. _whatsnew37-pep565: + +PEP 565: Show DeprecationWarning in ``__main__`` +------------------------------------------------ + +The default handling of :exc:`DeprecationWarning` has been changed such that +these warnings are once more shown by default, but only when the code +triggering them is running directly in the ``__main__`` module. As a result, +developers of single file scripts and those using Python interactively should +once again start seeing deprecation warnings for the APIs they use, but +deprecation warnings triggered by imported application, library and framework +modules will continue to be hidden by default. + +As a result of this change, the standard library now allows developers to choose +between three different deprecation warning behaviours: + +* :exc:`FutureWarning`: always displayed by default, recommended for warnings + intended to be seen by application end users (e.g. for deprecated application + configuration settings). +* :exc:`DeprecationWarning`: displayed by default only in ``__main__`` and when + running tests, recommended for warnings intended to be seen by other Python + developers where a version upgrade may result in changed behaviour or an + error. +* :exc:`PendingDeprecationWarning`: displayed by default only when running + tests, intended for cases where a future version upgrade will change the + warning category to :exc:`DeprecationWarning` or :exc:`FutureWarning`. + +Previously both :exc:`DeprecationWarning` and :exc:`PendingDeprecationWarning` +were only visible when running tests, which meant that developers primarily +writing single file scripts or using Python interactively could be surprised +by breaking changes in the APIs they used. + +.. seealso:: + + :pep:`565` -- Show DeprecationWarning in ``__main__`` + PEP written and implemented by Nick Coghlan + + PEP 540: Add a new UTF-8 mode ----------------------------- diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index 54ea3773a06..a6b663403f4 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -558,6 +558,7 @@ def test_xdev(self): expected_filters = "default::Warning" else: expected_filters = ("default::Warning " + "default::DeprecationWarning " "ignore::DeprecationWarning " "ignore::PendingDeprecationWarning " "ignore::ImportWarning " @@ -626,6 +627,7 @@ def test_warnings_filter_precedence(self): "always::UserWarning") if not Py_DEBUG: expected_filters += (" " + "default::DeprecationWarning " "ignore::DeprecationWarning " "ignore::PendingDeprecationWarning " "ignore::ImportWarning " diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 039c96e02c9..31ab94b7471 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -16,6 +16,8 @@ py_warnings = support.import_fresh_module('warnings', blocked=['_warnings']) c_warnings = support.import_fresh_module('warnings', fresh=['_warnings']) +Py_DEBUG = hasattr(sys, 'gettotalrefcount') + @contextmanager def warnings_state(module): """Use a specific warnings implementation in warning_tests.""" @@ -320,6 +322,7 @@ def test_simplefilter_duplicate_filters(self): self.module.filters[0][0], "error", "simplefilter did not promote filter to the beginning of list" ) + def test_append_duplicate(self): with original_warnings.catch_warnings(module=self.module, record=True) as w: @@ -1143,6 +1146,37 @@ def test_conflicting_envvar_and_command_line(self): b" File \"\", line 1, in ", b"DeprecationWarning: Message"]) + def test_default_filter_configuration(self): + pure_python_api = self.module is py_warnings + if Py_DEBUG: + expected_default_filters = [] + else: + if pure_python_api: + main_module_filter = re.compile("__main__") + else: + main_module_filter = "__main__" + expected_default_filters = [ + ('default', None, DeprecationWarning, main_module_filter, 0), + ('ignore', None, DeprecationWarning, None, 0), + ('ignore', None, PendingDeprecationWarning, None, 0), + ('ignore', None, ImportWarning, None, 0), + ('ignore', None, ResourceWarning, None, 0), + ] + expected_output = [str(f).encode() for f in expected_default_filters] + + if pure_python_api: + # Disable the warnings acceleration module in the subprocess + code = "import sys; sys.modules.pop('warnings', None); sys.modules['_warnings'] = None; " + else: + code = "" + code += "import warnings; [print(f) for f in warnings.filters]" + + rc, stdout, stderr = assert_python_ok("-c", code, __isolated=True) + stdout_lines = [line.strip() for line in stdout.splitlines()] + self.maxDiff = None + self.assertEqual(stdout_lines, expected_output) + + @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii', 'requires non-ascii filesystemencoding') def test_nonascii(self): @@ -1192,7 +1226,7 @@ def __del__(self): rc, out, err = assert_python_ok("-c", code) # note: "__main__" filename is not correct, it should be the name # of the script - self.assertEqual(err, b'__main__:7: UserWarning: test') + self.assertEqual(err.decode(), '__main__:7: UserWarning: test') def test_late_resource_warning(self): # Issue #21925: Emitting a ResourceWarning late during the Python diff --git a/Lib/warnings.py b/Lib/warnings.py index f4331c8ac38..76ad4dac018 100644 --- a/Lib/warnings.py +++ b/Lib/warnings.py @@ -519,8 +519,10 @@ def _filters_mutated(): # Module initialization _processoptions(sys.warnoptions) if not _warnings_defaults: - # Several warning categories are ignored by default in Py_DEBUG builds + # Several warning categories are ignored by default in regular builds if not hasattr(sys, 'gettotalrefcount'): + filterwarnings("default", category=DeprecationWarning, + module="__main__", append=1) simplefilter("ignore", category=DeprecationWarning, append=1) simplefilter("ignore", category=PendingDeprecationWarning, append=1) simplefilter("ignore", category=ImportWarning, append=1) diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst new file mode 100644 index 00000000000..98cfae0dd8c --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst @@ -0,0 +1,4 @@ +The default warning filter list now starts with a +"default::DeprecationWarning:__main__" entry, so deprecation warnings are +once again shown by default in single-file scripts and at the interactive +prompt. diff --git a/Python/_warnings.c b/Python/_warnings.c index be8370da06d..c286364dda0 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -12,6 +12,7 @@ MODULE_NAME " provides basic warning filtering support.\n" _Py_IDENTIFIER(argv); _Py_IDENTIFIER(stderr); #ifndef Py_DEBUG +_Py_IDENTIFIER(default); _Py_IDENTIFIER(ignore); #endif @@ -22,8 +23,20 @@ check_matched(PyObject *obj, PyObject *arg) _Py_IDENTIFIER(match); int rc; + /* A 'None' filter always matches */ if (obj == Py_None) return 1; + + /* An internal plain text default filter must match exactly */ + if (PyUnicode_CheckExact(obj)) { + int cmp_result = PyUnicode_Compare(obj, arg); + if (cmp_result == -1 && PyErr_Occurred()) { + return -1; + } + return !cmp_result; + } + + /* Otherwise assume a regex filter and call its match() method */ result = _PyObject_CallMethodIdObjArgs(obj, &PyId_match, arg, NULL); if (result == NULL) return -1; @@ -1158,16 +1171,27 @@ static PyMethodDef warnings_functions[] = { #ifndef Py_DEBUG static PyObject * -create_filter(PyObject *category, _Py_Identifier *id) +create_filter(PyObject *category, _Py_Identifier *id, const char *modname) { + PyObject *modname_obj = NULL; PyObject *action_str = _PyUnicode_FromId(id); if (action_str == NULL) { return NULL; } + /* Default to "no module name" for initial filter set */ + if (modname != NULL) { + modname_obj = PyUnicode_InternFromString(modname); + if (modname_obj == NULL) { + return NULL; + } + } else { + modname_obj = Py_None; + } + /* This assumes the line number is zero for now. */ return PyTuple_Pack(5, action_str, Py_None, - category, Py_None, _PyLong_Zero); + category, modname_obj, _PyLong_Zero); } #endif @@ -1180,20 +1204,22 @@ init_filters(void) return PyList_New(0); #else /* Other builds ignore a number of warning categories by default */ - PyObject *filters = PyList_New(4); + PyObject *filters = PyList_New(5); if (filters == NULL) { return NULL; } size_t pos = 0; /* Post-incremented in each use. */ PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_DeprecationWarning, &PyId_ignore)); + create_filter(PyExc_DeprecationWarning, &PyId_default, "__main__")); + PyList_SET_ITEM(filters, pos++, + create_filter(PyExc_DeprecationWarning, &PyId_ignore, NULL)); PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore)); + create_filter(PyExc_PendingDeprecationWarning, &PyId_ignore, NULL)); PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ImportWarning, &PyId_ignore)); + create_filter(PyExc_ImportWarning, &PyId_ignore, NULL)); PyList_SET_ITEM(filters, pos++, - create_filter(PyExc_ResourceWarning, &PyId_ignore)); + create_filter(PyExc_ResourceWarning, &PyId_ignore, NULL)); for (size_t x = 0; x < pos; x++) { if (PyList_GET_ITEM(filters, x) == NULL) { From solipsis at pitrou.net Mon Jan 8 04:13:38 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Mon, 08 Jan 2018 09:13:38 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=4 Message-ID: <20180108091338.1.02FF286F2B4319F8@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_collections leaked [0, 7, -7] memory blocks, sum=0 test_functools leaked [0, 3, 1] memory blocks, sum=4 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogUb3VGl', '--timeout', '7200'] From lp_benchmark_robot at intel.com Mon Jan 8 19:12:10 2018 From: lp_benchmark_robot at intel.com (lp_benchmark_robot at intel.com) Date: Mon, 8 Jan 2018 16:12:10 -0800 Subject: [Python-checkins] [1 down, 1 up, 63 flat] Results for Python (master branch) 2018-01-08 Message-ID: <3abfad68-7c49-4267-ba45-24c9ff258047@orsmsx102.amr.corp.intel.com> Results for project python/master, build date: 2018-01-08 03:04:20-08:00. - commit: 9b99747 - previous commit: 94459fd - revision date: 2018-01-08 12:45:02+10:00 - environment: Broadwell-EP - cpu: Intel(R) Xeon(R) CPU E5-2699 v4 @ 2.20GHz 2x22 cores, stepping 1, LLC 55 MB - mem: 128 GB - os: Ubuntu 16.04.2 LTS - kernel: 4.4.0-62-generic x86_64 GNU/Linux Baseline results were generated using release v3.6.0, with hash 5c4568a from 2016-12-22 23:38:47+00:00. +-----+------------------------+--------+------------+------------+------------+ | | |relative|change since|change since|current rev | | | benchmark|std_dev*| last run | baseline |run with PGO| +-----+------------------------+--------+------------+------------+------------+ | :-| | 2to3| 0.877% | -0.468% | +6.634% | +7.355% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method| 0.902% | +0.593% | +22.126% | +10.038% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_slots| 1.801% | +0.481% | +24.188% | +9.773% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_method_unknown| 1.106% | +0.687% | +21.943% | +8.379% | +-----+------------------------+--------+------------+------------+------------+ | :-| | call_simple| 3.284% | +0.922% | +8.557% | +12.401% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chameleon| 1.392% | +0.148% | +9.448% | +13.009% | +-----+------------------------+--------+------------+------------+------------+ | :-| | chaos| 1.010% | +0.638% | +5.428% | +11.480% | +-----+------------------------+--------+------------+------------+------------+ | :-| | crypto_pyaes| 0.633% | -0.203% | -0.922% | +7.934% | +-----+------------------------+--------+------------+------------+------------+ | :-| | deltablue| 3.357% | +0.092% | +9.715% | +17.606% | +-----+------------------------+--------+------------+------------+------------+ | :-| | django_template| 4.004% | +0.391% | +12.568% | +13.919% | +-----+------------------------+--------+------------+------------+------------+ | :-| | dulwich_log| 1.010% | +0.505% | +3.827% | +6.857% | +-----+------------------------+--------+------------+------------+------------+ | :-| | fannkuch| 0.661% | -0.325% | +4.345% | +5.370% | +-----+------------------------+--------+------------+------------+------------+ | :-| | float| 0.544% | -0.081% | +2.524% | +6.957% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_text| 1.276% | +0.050% | +12.087% | +10.860% | +-----+------------------------+--------+------------+------------+------------+ | :-| | genshi_xml| 1.701% | -1.640% | +7.486% | +11.358% | +-----+------------------------+--------+------------+------------+------------+ | :-| | go| 0.966% | +0.267% | +6.629% | +11.498% | +-----+------------------------+--------+------------+------------+------------+ | :-| | hexiom| 0.546% | +0.437% | +10.366% | +10.286% | +-----+------------------------+--------+------------+------------+------------+ | :-| | html5lib| 3.189% | +1.888% | +8.009% | +10.683% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_dumps| 1.315% | +0.366% | +3.227% | +9.403% | +-----+------------------------+--------+------------+------------+------------+ | :-| | json_loads| 4.750% | -0.051% | -0.618% | +12.792% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_format| 1.483% | -0.336% | +8.196% | +12.579% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_silent| 2.899% | -0.893% | +46.368% | +12.253% | +-----+------------------------+--------+------------+------------+------------+ | :-| | logging_simple| 1.525% | -0.604% | +8.868% | +14.074% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mako| 0.950% | -0.485% | +17.029% | +13.877% | +-----+------------------------+--------+------------+------------+------------+ | :-| | mdp| 4.237% | -0.641% | +11.164% | +7.549% | +-----+------------------------+--------+------------+------------+------------+ | :-| | meteor_contest| 2.967% | +1.376% | +3.759% | +6.018% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nbody| 0.760% | +0.160% | -4.900% | +1.717% | +-----+------------------------+--------+------------+------------+------------+ | :-| | nqueens| 1.875% | -0.129% | +4.204% | +7.350% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pathlib| 1.638% | +2.027% | +3.040% | +10.370% | +-----+------------------------+--------+------------+------------+------------+ | :-( | pickle| 0.805% | -2.969% | -2.012% | +23.179% | +-----+------------------------+--------+------------+------------+------------+ | :-) | pickle_dict| 0.147% | +1.726% | +3.424% | +17.158% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_list| 1.840% | +1.285% | +4.727% | +17.140% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pickle_pure_python| 2.336% | -0.031% | +12.019% | +8.932% | +-----+------------------------+--------+------------+------------+------------+ | :-| | pidigits| 0.090% | -0.068% | -0.107% | +10.187% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup| 0.159% | -0.153% | +10.593% | +5.432% | +-----+------------------------+--------+------------+------------+------------+ | :-| | python_startup_no_site| 0.129% | -0.158% | +1.909% | +5.496% | +-----+------------------------+--------+------------+------------+------------+ | :-| | raytrace| 0.866% | +0.074% | +10.372% | +13.845% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_compile| 6.122% | -0.466% | +0.959% | +11.910% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_dna| 0.251% | +0.407% | -0.574% | +10.239% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_effbot| 1.926% | -0.750% | -4.838% | +7.192% | +-----+------------------------+--------+------------+------------+------------+ | :-| | regex_v8| 2.440% | +0.630% | +5.731% | +4.391% | +-----+------------------------+--------+------------+------------+------------+ | :-| | richards| 1.562% | -0.055% | +8.677% | +15.131% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_fft| 0.800% | +0.221% | -2.854% | +5.201% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_lu| 3.310% | +0.467% | +26.317% | +8.063% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_monte_carlo| 2.134% | -0.125% | +4.755% | +5.065% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sor| 0.914% | +0.360% | +14.682% | +8.204% | +-----+------------------------+--------+------------+------------+------------+ | :-| | scimark_sparse_mat_mult| 0.690% | -1.118% | -6.649% | +1.040% | +-----+------------------------+--------+------------+------------+------------+ | :-| | spectral_norm| 0.430% | -0.994% | +5.043% | +4.038% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_declarative| 1.310% | -0.197% | +5.958% | +6.834% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlalchemy_imperative| 3.252% | +0.621% | +5.812% | +5.297% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sqlite_synth| 3.597% | +0.772% | +19.072% | +7.331% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_expand| 2.092% | +0.554% | +11.622% | +7.130% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_integrate| 2.515% | -0.281% | +8.068% | +8.008% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_str| 3.648% | +0.165% | +11.621% | +8.536% | +-----+------------------------+--------+------------+------------+------------+ | :-| | sympy_sum| 6.177% | -0.862% | +10.313% | +9.834% | +-----+------------------------+--------+------------+------------+------------+ | :-| | telco| 5.259% | -2.292% | +17.677% | +13.728% | +-----+------------------------+--------+------------+------------+------------+ | :-| | tornado_http| 0.903% | -0.190% | +5.890% | +6.610% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpack_sequence| 2.419% | +0.604% | +2.127% | -1.123% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle| 7.309% | -2.272% | +4.388% | +24.216% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_list| 1.615% | +2.433% | -2.367% | +17.246% | +-----+------------------------+--------+------------+------------+------------+ | :-| | unpickle_pure_python| 1.495% | -0.781% | +7.857% | +6.644% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_generate| 1.099% | -0.983% | +0.501% | +13.741% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_iterparse| 2.306% | -1.053% | +1.928% | +9.173% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_parse| 4.331% | -1.302% | -9.694% | +14.885% | +-----+------------------------+--------+------------+------------+------------+ | :-| | xml_etree_process| 1.306% | -1.169% | +2.832% | +12.798% | +-----+------------------------+--------+------------+------------+------------+ * Relative Standard Deviation (Standard Deviation/Average) If this is not displayed properly please visit our results page here: http://languagesperformance.intel.com/1-down-1-up-63-flat-results-for-python-master-branch-2018-01-08 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 webhook-mailer at python.org Mon Jan 8 21:08:02 2018 From: webhook-mailer at python.org (Ned Deily) Date: Tue, 09 Jan 2018 02:08:02 -0000 Subject: [Python-checkins] bpo-32248: install new test_importlib directories (#5138) Message-ID: https://github.com/python/cpython/commit/ca0c5f26563349ed761af13590acef80e1064eab commit: ca0c5f26563349ed761af13590acef80e1064eab branch: master author: Ned Deily committer: GitHub date: 2018-01-08T21:07:59-05:00 summary: bpo-32248: install new test_importlib directories (#5138) files: M Makefile.pre.in diff --git a/Makefile.pre.in b/Makefile.pre.in index 4fe9affe0d2..59ba9d4c1f1 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1250,9 +1250,26 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/test_import/data/circular_imports/subpkg \ test/test_import/data/package \ test/test_import/data/package2 \ + importlib \ + test/test_importlib \ + test/test_importlib/builtin \ + test/test_importlib/data01 \ + test/test_importlib/data01/subdirectory \ + test/test_importlib/data02 \ + test/test_importlib/data02/one \ + test/test_importlib/data02/two \ + test/test_importlib/data03 \ + test/test_importlib/data03/namespace \ + test/test_importlib/data03/namespace/portion1 \ + test/test_importlib/data03/namespace/portion2 \ + test/test_importlib/extension \ + test/test_importlib/frozen \ + test/test_importlib/import_ \ test/test_importlib/namespace_pkgs \ test/test_importlib/namespace_pkgs/both_portions \ test/test_importlib/namespace_pkgs/both_portions/foo \ + test/test_importlib/namespace_pkgs/module_and_namespace_package \ + test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test \ test/test_importlib/namespace_pkgs/not_a_namespace_pkg \ test/test_importlib/namespace_pkgs/not_a_namespace_pkg/foo \ test/test_importlib/namespace_pkgs/portion1 \ @@ -1268,8 +1285,9 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ test/test_importlib/namespace_pkgs/project3 \ test/test_importlib/namespace_pkgs/project3/parent \ test/test_importlib/namespace_pkgs/project3/parent/child \ - test/test_importlib/namespace_pkgs/module_and_namespace_package \ - test/test_importlib/namespace_pkgs/module_and_namespace_package/a_test \ + test/test_importlib/source \ + test/test_importlib/zipdata01 \ + test/test_importlib/zipdata02 \ asyncio \ test/test_asyncio \ collections concurrent concurrent/futures encodings \ @@ -1284,9 +1302,6 @@ LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \ ctypes ctypes/test ctypes/macholib \ idlelib idlelib/Icons idlelib/idle_test \ distutils distutils/command distutils/tests $(XMLLIBSUBDIRS) \ - importlib test/test_importlib test/test_importlib/builtin \ - test/test_importlib/extension test/test_importlib/frozen \ - test/test_importlib/import_ test/test_importlib/source \ test/test_tools test/test_warnings test/test_warnings/data \ turtledemo \ multiprocessing multiprocessing/dummy \ From webhook-mailer at python.org Tue Jan 9 03:14:51 2018 From: webhook-mailer at python.org (Steve Dower) Date: Tue, 09 Jan 2018 08:14:51 -0000 Subject: [Python-checkins] bpo-32507: Change Windows install to include app-local UCRT (#5119) Message-ID: https://github.com/python/cpython/commit/d135f20ae8887acc7716561bc8f4c7eb6d58d24c commit: d135f20ae8887acc7716561bc8f4c7eb6d58d24c branch: master author: Steve Dower committer: GitHub date: 2018-01-09T19:14:46+11:00 summary: bpo-32507: Change Windows install to include app-local UCRT (#5119) files: A Misc/NEWS.d/next/Windows/2018-01-07-12-32-49.bpo-32507.vB4gxk.rst A Misc/NEWS.d/next/Windows/2018-01-07-12-33-21.bpo-29911.ewSJKb.rst A Tools/msi/ucrt/ucrt.wixproj A Tools/msi/ucrt/ucrt.wxs A Tools/msi/ucrt/ucrt_en-US.wxl D PC/dllbase_nt.txt M PCbuild/_bz2.vcxproj M PCbuild/_ctypes.vcxproj M PCbuild/_decimal.vcxproj M PCbuild/_elementtree.vcxproj M PCbuild/_msi.vcxproj M PCbuild/_multiprocessing.vcxproj M PCbuild/_overlapped.vcxproj M PCbuild/_socket.vcxproj M PCbuild/_sqlite3.vcxproj M PCbuild/_testbuffer.vcxproj M PCbuild/_testcapi.vcxproj M PCbuild/_testimportmultiple.vcxproj M PCbuild/python.vcxproj M PCbuild/pythoncore.vcxproj M PCbuild/pythonw.vcxproj M PCbuild/select.vcxproj M PCbuild/unicodedata.vcxproj M PCbuild/xxlimited.vcxproj M Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp M Tools/msi/bundle/bundle.targets M Tools/msi/bundle/packagegroups/crt.wxs M Tools/msi/exe/exe.wxs M Tools/msi/get_externals.bat M Tools/msi/msi.props M Tools/msi/uploadrelease.proj diff --git a/Misc/NEWS.d/next/Windows/2018-01-07-12-32-49.bpo-32507.vB4gxk.rst b/Misc/NEWS.d/next/Windows/2018-01-07-12-32-49.bpo-32507.vB4gxk.rst new file mode 100644 index 00000000000..010271ca24e --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-01-07-12-32-49.bpo-32507.vB4gxk.rst @@ -0,0 +1,2 @@ +Use app-local UCRT install rather than the proper update for old versions of +Windows. diff --git a/Misc/NEWS.d/next/Windows/2018-01-07-12-33-21.bpo-29911.ewSJKb.rst b/Misc/NEWS.d/next/Windows/2018-01-07-12-33-21.bpo-29911.ewSJKb.rst new file mode 100644 index 00000000000..7f311efef46 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2018-01-07-12-33-21.bpo-29911.ewSJKb.rst @@ -0,0 +1 @@ +Ensure separate Modify and Uninstall buttons are displayed. diff --git a/PC/dllbase_nt.txt b/PC/dllbase_nt.txt deleted file mode 100644 index 93a15d12bf8..00000000000 --- a/PC/dllbase_nt.txt +++ /dev/null @@ -1,77 +0,0 @@ -In Win32, DLL's are "pre-linked" using a specified base address. -When the DLL is loaded, an attempt is made to place it at -that address. If that address is already in use, a new base address -is selected, and the DLL subject to fixups. Apparently, these -fixups are very slow, and significant performance gains can be -made by selecting a good base address. - -This document is to allocate base addresses to core Python -and Python .PYD files, to give a better change of optimal performance. -This base address is passed to the linker using the /BASE -command line switch. - - -Python.exe/Pythonw.exe - 1d000000 - 1e000000 (-1) -Python.dll - 1e000000 - 1e100000 (-1) - -Standard Extension Modules 1e100000 - 1e200000 "" - - _symtable 1e100000 - 1e110000 pyd removed in 2.4 - - bsddb 1e180000 - 1e188000 pyd removed in 3.0 - - _tkinter 1e190000 - 1e1A0000 - - parser 1e1A0000 - 1e1B0000 pyd removed in 2.4 - - zlib 1e1B0000 - 1e1C0000 - - winreg 1e1C0000 - 1e1D0000 pyd removed in 2.4 - - _socket 1e1D0000 - 1e1E0000 - - _sre 1e1E0000 - 1e1F0000 pyd removed in 2.4 - - mmap 1e1F0000 - 1e1FFFFF pyd removed in 2.4 - -More standard extensions 1D100000 - 1e000000 - - pyexpat 1D100000 - 1D110000 - - select 1D110000 - 1D120000 - - unicodedata 1D120000 - 1D160000 - - winsound 1D160000 - 1D170000 - - bZ2 1D170000 - 1D180000 - - datetime 1D180000 - 1D190000 pyd removed in 2.4 - - _csv 1D190000 - 1D1A0000 pyd removed in 2.4 - - _ctypes 1D1A0000 - 1D1B0000 - -Other extension modules - - win32api 1e200000 - 1e220000 - - win32ras 1e220000 - 1e230000 - - win32lz 1e230000 - 1e240000 - - timer 1e240000 - 1e250000 - - mmapfile 1e250000 - 1e260000 - - win32pipe 1e260000 - 1e270000 - - avl 1e270000 - 1e270000 - - dbhash 1e280000 - 1e290000 - - win32net 1e290000 - 1e2A0000 - - win32security 1e2A0000 - 1e2B0000 - - win32print 1e2B0000 - 1e2c0000 - - 1e2d0000 - 1e2e0000 - - win32gui 1e2e0000 - 1e2f0000 - - _imaging 1e2f0000 - 1e300000 - - multiarray 1e300000 - 1e310000 - - win32help 1e310000 - 1e320000 - - win32clipboard 1e320000 - 1e330000 - - win2kras 1e330000 - 1e340000 - - pythoncom 1e340000 - 1e400000 - - win32ui 1e400000 - 1e500000 - - win32uiole 1e500000 - 1e600000 - - pywintypes 1e600000 - 1e700000 - - win32process 1e700000 - 1e800000 - - odbc 1e710000 - 1e720000 - - dbi 1e720000 - 1e730000 - - win32file 1e730000 - 1e740000 - - win32wnet 1e740000 - 1e750000 - - win32com.shell 1e750000 - 1e760000 - - win32com.internet 1e760000 - 1e770000 - - win32com.exchange 1e770000 - 1e780000 - - win32com.exchdapi 1e780000 - 1e790000 - - win32com.axscript 1e790000 - 1e7a0000 - - win32com.axdebug 1e7b0000 - 1e7c0000 - - win32com.adsi 1e7f0000 - 1e800000 - - win32event 1e810000 - 1e820000 - - win32evtlog 1e820000 - 1e830000 - - win32com.axcontrol 1e830000 - 1e840000 - - diff --git a/PCbuild/_bz2.vcxproj b/PCbuild/_bz2.vcxproj index b3ab378c6ed..3c21848ae28 100644 --- a/PCbuild/_bz2.vcxproj +++ b/PCbuild/_bz2.vcxproj @@ -66,9 +66,6 @@ WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;%(PreprocessorDefinitions) 4244;4267;%(DisableSpecificWarnings) - - 0x1D170000 - diff --git a/PCbuild/_ctypes.vcxproj b/PCbuild/_ctypes.vcxproj index 43d51f82965..81670a75bd6 100644 --- a/PCbuild/_ctypes.vcxproj +++ b/PCbuild/_ctypes.vcxproj @@ -64,7 +64,6 @@ ..\Modules\_ctypes\libffi_msvc;%(AdditionalIncludeDirectories) - 0x1D1A0000 /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) diff --git a/PCbuild/_decimal.vcxproj b/PCbuild/_decimal.vcxproj index 9c9c19abbe3..b14f31093ff 100644 --- a/PCbuild/_decimal.vcxproj +++ b/PCbuild/_decimal.vcxproj @@ -66,9 +66,6 @@ CONFIG_64;%(PreprocessorDefinitions) ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) - - 0x1D1A0000 - diff --git a/PCbuild/_elementtree.vcxproj b/PCbuild/_elementtree.vcxproj index 0db61f20818..2338af4505b 100644 --- a/PCbuild/_elementtree.vcxproj +++ b/PCbuild/_elementtree.vcxproj @@ -64,9 +64,6 @@ ..\Modules\expat;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) - - 0x1D100000 - diff --git a/PCbuild/_msi.vcxproj b/PCbuild/_msi.vcxproj index 3895d450f35..6be83ca6860 100644 --- a/PCbuild/_msi.vcxproj +++ b/PCbuild/_msi.vcxproj @@ -62,7 +62,6 @@ cabinet.lib;msi.lib;rpcrt4.lib;%(AdditionalDependencies) - 0x1D160000 diff --git a/PCbuild/_multiprocessing.vcxproj b/PCbuild/_multiprocessing.vcxproj index bb2bb4114c9..0e3f376eaf9 100644 --- a/PCbuild/_multiprocessing.vcxproj +++ b/PCbuild/_multiprocessing.vcxproj @@ -62,7 +62,6 @@ ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 diff --git a/PCbuild/_overlapped.vcxproj b/PCbuild/_overlapped.vcxproj index 26b2d214c35..829cc81b623 100644 --- a/PCbuild/_overlapped.vcxproj +++ b/PCbuild/_overlapped.vcxproj @@ -62,7 +62,6 @@ ws2_32.lib;%(AdditionalDependencies) - 0x1D110000 diff --git a/PCbuild/_socket.vcxproj b/PCbuild/_socket.vcxproj index d5c4d1b5b6f..9e27891081e 100644 --- a/PCbuild/_socket.vcxproj +++ b/PCbuild/_socket.vcxproj @@ -62,7 +62,6 @@ ws2_32.lib;%(AdditionalDependencies) - 0x1e1D0000 diff --git a/PCbuild/_sqlite3.vcxproj b/PCbuild/_sqlite3.vcxproj index 5456bb5b238..1f1a1c8cada 100644 --- a/PCbuild/_sqlite3.vcxproj +++ b/PCbuild/_sqlite3.vcxproj @@ -64,9 +64,6 @@ $(sqlite3Dir);%(AdditionalIncludeDirectories) MODULE_NAME="sqlite3";%(PreprocessorDefinitions) - - 0x1e180000 - diff --git a/PCbuild/_testbuffer.vcxproj b/PCbuild/_testbuffer.vcxproj index 1f45b298102..fd2f320d797 100644 --- a/PCbuild/_testbuffer.vcxproj +++ b/PCbuild/_testbuffer.vcxproj @@ -60,11 +60,6 @@ <_ProjectFileVersion>10.0.40219.1 - - - 0x1e1F0000 - - diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj index 365b07c5c5c..e668000bf2b 100644 --- a/PCbuild/_testcapi.vcxproj +++ b/PCbuild/_testcapi.vcxproj @@ -60,11 +60,6 @@ <_ProjectFileVersion>10.0.30319.1 - - - 0x1e1F0000 - - diff --git a/PCbuild/_testimportmultiple.vcxproj b/PCbuild/_testimportmultiple.vcxproj index 37c1a64ac8c..56da66cf327 100644 --- a/PCbuild/_testimportmultiple.vcxproj +++ b/PCbuild/_testimportmultiple.vcxproj @@ -60,11 +60,6 @@ <_ProjectFileVersion>10.0.30319.1 - - - 0x1e1F0000 - - diff --git a/PCbuild/python.vcxproj b/PCbuild/python.vcxproj index 423e68c57b2..8b64e364f18 100644 --- a/PCbuild/python.vcxproj +++ b/PCbuild/python.vcxproj @@ -62,7 +62,6 @@ Console 2000000 - 0x1d000000 diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 25651d00049..c8a5d7d01b4 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -76,7 +76,6 @@ version.lib;shlwapi.lib;ws2_32.lib;%(AdditionalDependencies) %(AdditionalLibraryDirectories);$(PySourcePath)PC\external\$(PlatformToolset)\$(ArchName) - 0x1e000000 diff --git a/PCbuild/pythonw.vcxproj b/PCbuild/pythonw.vcxproj index e40f66c856b..19d64a332b2 100644 --- a/PCbuild/pythonw.vcxproj +++ b/PCbuild/pythonw.vcxproj @@ -58,7 +58,6 @@ 2000000 - 0x1d000000 diff --git a/PCbuild/select.vcxproj b/PCbuild/select.vcxproj index d6112ab6fe3..ea75705ae49 100644 --- a/PCbuild/select.vcxproj +++ b/PCbuild/select.vcxproj @@ -61,7 +61,6 @@ ws2_32.lib;%(AdditionalDependencies) - 0x1D110000 diff --git a/PCbuild/unicodedata.vcxproj b/PCbuild/unicodedata.vcxproj index 317c1a8a56d..b80da53af33 100644 --- a/PCbuild/unicodedata.vcxproj +++ b/PCbuild/unicodedata.vcxproj @@ -59,11 +59,6 @@ <_ProjectFileVersion>10.0.30319.1 - - - 0x1D120000 - - diff --git a/PCbuild/xxlimited.vcxproj b/PCbuild/xxlimited.vcxproj index 9dbdc77335d..a796255c820 100644 --- a/PCbuild/xxlimited.vcxproj +++ b/PCbuild/xxlimited.vcxproj @@ -66,7 +66,6 @@ wsock32.lib;%(AdditionalDependencies) - 0x1D110000 diff --git a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp index e88981fc3ab..2e468b7e57b 100644 --- a/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp +++ b/Tools/msi/bundle/bootstrap/PythonBootstrapperApplication.cpp @@ -281,10 +281,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { case ID_INSTALL_BUTTON: SavePageSettings(); - if (!WillElevate() && !QueryElevateForCrtInstall()) { - break; - } - hr = BalGetNumericVariable(L"InstallAllUsers", &installAllUsers); ExitOnFailure(hr, L"Failed to get install scope"); @@ -332,10 +328,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { ReleaseStr(targetDir); } - if (!WillElevate() && !QueryElevateForCrtInstall()) { - break; - } - OnPlan(_command.action); break; @@ -2642,30 +2634,6 @@ class PythonBootstrapperApplication : public CBalBaseBootstrapperApplication { return result; } - BOOL QueryElevateForCrtInstall() { - // Called to prompt the user that even though they think they won't need - // to elevate, they actually will because of the CRT install. - if (IsCrtInstalled()) { - // CRT is already installed - no need to prompt - return TRUE; - } - - LONGLONG elevated; - HRESULT hr = BalGetNumericVariable(L"WixBundleElevated", &elevated); - if (SUCCEEDED(hr) && elevated) { - // Already elevated - no need to prompt - return TRUE; - } - - LOC_STRING *locStr; - hr = LocGetString(_wixLoc, L"#(loc.ElevateForCRTInstall)", &locStr); - if (FAILED(hr)) { - BalLogError(hr, "Failed to get ElevateForCRTInstall string"); - return FALSE; - } - return ::MessageBoxW(_hWnd, locStr->wzText, _theme->sczCaption, MB_YESNO) != IDNO; - } - HRESULT EvaluateConditions() { HRESULT hr = S_OK; BOOL result = FALSE; diff --git a/Tools/msi/bundle/bundle.targets b/Tools/msi/bundle/bundle.targets index e0dae21202e..f882d2ee1f0 100644 --- a/Tools/msi/bundle/bundle.targets +++ b/Tools/msi/bundle/bundle.targets @@ -71,6 +71,7 @@ + diff --git a/Tools/msi/bundle/packagegroups/crt.wxs b/Tools/msi/bundle/packagegroups/crt.wxs index dc4047590e8..61b756fc255 100644 --- a/Tools/msi/bundle/packagegroups/crt.wxs +++ b/Tools/msi/bundle/packagegroups/crt.wxs @@ -2,48 +2,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + ForcePerMachine="no" + InstallCondition="not InstallAllUsers and not CRTInstalled and (Include_core or Include_exe or Include_pip) and not LauncherOnly"> + + - - - \ No newline at end of file diff --git a/Tools/msi/exe/exe.wxs b/Tools/msi/exe/exe.wxs index 03d43c60324..98d31b3a77b 100644 --- a/Tools/msi/exe/exe.wxs +++ b/Tools/msi/exe/exe.wxs @@ -3,10 +3,10 @@ - + - + @@ -14,7 +14,7 @@ - + diff --git a/Tools/msi/get_externals.bat b/Tools/msi/get_externals.bat index 913512a778f..d66781d7c42 100644 --- a/Tools/msi/get_externals.bat +++ b/Tools/msi/get_externals.bat @@ -55,7 +55,7 @@ set binaries=%binaries% binutils set binaries=%binaries% gpg set binaries=%binaries% htmlhelp set binaries=%binaries% nuget -set binaries=%binaries% redist +set binaries=%binaries% redist-1 set binaries=%binaries% wix for %%b in (%binaries%) do ( diff --git a/Tools/msi/msi.props b/Tools/msi/msi.props index 0318f7aa8eb..0fe822af931 100644 --- a/Tools/msi/msi.props +++ b/Tools/msi/msi.props @@ -54,8 +54,8 @@ $(OutputPath)\ $(OutputPath) true - $(ExternalsDir)\windows-installer\redist - + $(ExternalsDir)\windows-installer\redist-1\$(Platform) + $([System.IO.Path]::GetFullPath($(CRTRedist))) python$(MajorVersionNumber)$(MinorVersionNumber)$(MicroVersionNumber)$(ReleaseLevelName).chm $(MajorVersionNumber).$(MinorVersionNumber).$(Field3Value).0 @@ -123,10 +123,7 @@ tcltk - - redist - - + redist diff --git a/Tools/msi/ucrt/ucrt.wixproj b/Tools/msi/ucrt/ucrt.wixproj new file mode 100644 index 00000000000..52a7e0e672b --- /dev/null +++ b/Tools/msi/ucrt/ucrt.wixproj @@ -0,0 +1,28 @@ + + + + {E233091D-2EE3-49D8-A7F1-6E266CE1B6B1} + 2.0 + ucrt + Package + + + + + + + + + + + $(CRTRedist) + !(bindpath.redist)\ + $(CRTRedist)\ucrt + InstallDirectory\ + ucrt_dll + false + + + + + \ No newline at end of file diff --git a/Tools/msi/ucrt/ucrt.wxs b/Tools/msi/ucrt/ucrt.wxs new file mode 100644 index 00000000000..76e56820c53 --- /dev/null +++ b/Tools/msi/ucrt/ucrt.wxs @@ -0,0 +1,14 @@ +? + + + + + + + + + + + + + diff --git a/Tools/msi/ucrt/ucrt_en-US.wxl b/Tools/msi/ucrt/ucrt_en-US.wxl new file mode 100644 index 00000000000..f42dd5fe44c --- /dev/null +++ b/Tools/msi/ucrt/ucrt_en-US.wxl @@ -0,0 +1,5 @@ +? + + C Runtime Library + ucrt + diff --git a/Tools/msi/uploadrelease.proj b/Tools/msi/uploadrelease.proj index 96b99a4ff63..e70ae1de22f 100644 --- a/Tools/msi/uploadrelease.proj +++ b/Tools/msi/uploadrelease.proj @@ -21,7 +21,7 @@ - + $(MSITarget) From solipsis at pitrou.net Tue Jan 9 04:13:30 2018 From: solipsis at pitrou.net (solipsis at pitrou.net) Date: Tue, 09 Jan 2018 09:13:30 +0000 Subject: [Python-checkins] Daily reference leaks (4243df51fe43): sum=3 Message-ID: <20180109091330.1.9FCFEB1C37E63A1E@psf.io> results for 4243df51fe43 on branch "default" -------------------------------------------- test_functools leaked [0, 3, 1] memory blocks, sum=4 test_multiprocessing_fork leaked [-1, -1, 2] memory blocks, sum=0 test_multiprocessing_spawn leaked [1, 0, -2] memory blocks, sum=-1 Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/psf-users/antoine/refleaks/reflogMSSfrq', '--timeout', '7200'] From webhook-mailer at python.org Tue Jan 9 10:22:40 2018 From: webhook-mailer at python.org (Ned Deily) Date: Tue, 09 Jan 2018 15:22:40 -0000 Subject: [Python-checkins] Update docs for 3.7.0a4 Message-ID: https://github.com/python/cpython/commit/3b43bfaae665ab784ef67cefc3a3f95a75aafdc4 commit: 3b43bfaae665ab784ef67cefc3a3f95a75aafdc4 branch: master author: Ned Deily committer: Ned Deily date: 2018-01-08T21:57:13-05:00 summary: Update docs for 3.7.0a4 files: A Misc/NEWS.d/3.7.0a4.rst D Misc/NEWS.d/next/C API/2017-12-07-15-58-15.bpo-32241.LbyQt6.rst D Misc/NEWS.d/next/C API/2017-12-12-23-09-46.bpo-32264.ahRlOI.rst D Misc/NEWS.d/next/C API/2017-12-16-09-59-35.bpo-29084.ZGJ-LJ.rst D Misc/NEWS.d/next/C API/2017-12-20-23-22-32.bpo-32030.d1dcwh.rst D Misc/NEWS.d/next/Core and Builtins/2017-07-26-00-20-15.bpo-29469.potmyI.rst D Misc/NEWS.d/next/Core and Builtins/2017-11-26-14-38-44.bpo-31650.JWf_Im.rst D Misc/NEWS.d/next/Core and Builtins/2017-11-28-15-04-14.bpo-31901.mDeCLK.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-33-47.bpo-32225.ucKjvw.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-42-58.bpo-32226.G8fqb6.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-05-23-10-58.bpo-29240.qpJP5l.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-06-20-18-34.bpo-32230.PgGQaB.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-07-17-22-30.bpo-20361.zQUmbi.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-07-23-44-29.bpo-31506.j1U2fU.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-09-11-03-51.bpo-32260.1DAO-p.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-14-11-48-19.bpo-30416.hlHo_9.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-15-00-13-04.bpo-32329.q47IN2.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-15-11-50-06.bpo-27169.VO84fQ.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-16-14-30-21.bpo-32259.GoOJiX.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-19-21-14-41.bpo-32379.B7mOmI.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst D Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-38-17.bpo-32399.wlH12z.rst D Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst D Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst D Misc/NEWS.d/next/Documentation/2017-12-24-17-29-37.bpo-32418.eZe-ID.rst D Misc/NEWS.d/next/Library/2017-09-16-02-56-33.bpo-15216.lqXCTT.rst D Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst D Misc/NEWS.d/next/Library/2017-10-10-18-56-46.bpo-30241.F_go20.rst D Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst D Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst D Misc/NEWS.d/next/Library/2017-11-02-11-57-41.bpo-27456.snzyTC.rst D Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst D Misc/NEWS.d/next/Library/2017-11-24-08-35-43.bpo-26439.IC45_f.rst D Misc/NEWS.d/next/Library/2017-11-26-17-28-26.bpo-32143.o7YdXL.rst D Misc/NEWS.d/next/Library/2017-12-04-12-23-26.bpo-32199.nGof4v.rst D Misc/NEWS.d/next/Library/2017-12-04-17-41-40.bpo-15873.-T4TRK.rst D Misc/NEWS.d/next/Library/2017-12-05-13-25-15.bpo-32227.3vnWFS.rst D Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst D Misc/NEWS.d/next/Library/2017-12-08-11-02-26.bpo-32193.NJe_TQ.rst D Misc/NEWS.d/next/Library/2017-12-08-15-09-41.bpo-22589.8ouqI6.rst D Misc/NEWS.d/next/Library/2017-12-09-11-30-35.bpo-32253.TQHSYF.rst D Misc/NEWS.d/next/Library/2017-12-10-00-57-51.bpo-32265.kELtTE.rst D Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst D Misc/NEWS.d/next/Library/2017-12-10-18-59-13.bpo-32272.Mu84Am.rst D Misc/NEWS.d/next/Library/2017-12-10-19-14-55.bpo-32273.5KKlCv.rst D Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst D Misc/NEWS.d/next/Library/2017-12-10-23-44-56.bpo-30050.4SZ3lY.rst D Misc/NEWS.d/next/Library/2017-12-11-09-53-14.bpo-32277.jkKiVC.rst D Misc/NEWS.d/next/Library/2017-12-12-07-29-06.bpo-32255.2bfNmM.rst D Misc/NEWS.d/next/Library/2017-12-12-16-58-20.bpo-32250.UljTa0.rst D Misc/NEWS.d/next/Library/2017-12-12-18-01-01.bpo-32296.bwscHz.rst D Misc/NEWS.d/next/Library/2017-12-13-00-00-37.bpo-17852.Q8BP8N.rst D Misc/NEWS.d/next/Library/2017-12-13-16-47-38.bpo-32314.W4_U2j.rst D Misc/NEWS.d/next/Library/2017-12-13-19-02-38.bpo-29970.uxVOpk.rst D Misc/NEWS.d/next/Library/2017-12-13-20-31-30.bpo-32308.CUbsb2.rst D Misc/NEWS.d/next/Library/2017-12-13-22-10-36.bpo-29711.hJjghA.rst D Misc/NEWS.d/next/Library/2017-12-13-22-38-08.bpo-32302.othtTr.rst D Misc/NEWS.d/next/Library/2017-12-14-10-10-10.bpo-32323.ideco.rst D Misc/NEWS.d/next/Library/2017-12-14-16-00-25.bpo-32327.bbkSxA.rst D Misc/NEWS.d/next/Library/2017-12-14-17-28-54.bpo-32311.DL5Ytn.rst D Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst D Misc/NEWS.d/next/Library/2017-12-15-23-48-43.bpo-32331.fIg1Uc.rst D Misc/NEWS.d/next/Library/2017-12-16-18-50-57.bpo-32348.5j__he.rst D Misc/NEWS.d/next/Library/2017-12-17-14-23-23.bpo-32351.95fh2K.rst D Misc/NEWS.d/next/Library/2017-12-17-21-42-24.bpo-32355.tbaTWA.rst D Misc/NEWS.d/next/Library/2017-12-17-22-50-51.bpo-32356.roZJpA.rst D Misc/NEWS.d/next/Library/2017-12-18-00-36-41.bpo-32357.t1F3sn.rst D Misc/NEWS.d/next/Library/2017-12-19-00-37-28.bpo-32363.YTeGU0.rst D Misc/NEWS.d/next/Library/2017-12-21-11-08-42.bpo-26133.mt81QV.rst D Misc/NEWS.d/next/Library/2017-12-23-12-45-00.bpo-32415.YufXTU.rst D Misc/NEWS.d/next/Library/2017-12-25-11-09-46.bpo-31721.5gM972.rst D Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst D Misc/NEWS.d/next/Library/2017-12-28-21-30-40.bpo-32441.LqlboJ.rst D Misc/NEWS.d/next/Library/2017-12-29-00-44-42.bpo-23749.QL1Cxd.rst D Misc/NEWS.d/next/Library/2017-12-31-20-32-58.bpo-32468.YBs__0.rst D Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst D Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst D Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst D Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst D Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst D Misc/NEWS.d/next/Tests/2017-12-11-13-31-33.bpo-32252.YnFw7J.rst D Misc/NEWS.d/next/Tools-Demos/2017-12-22-09-25-51.bpo-24960.TGdAgO.rst D Misc/NEWS.d/next/Windows/2017-08-18-18-00-24.bpo-19764.ODpc9y.rst M Lib/pydoc_data/topics.py diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index bb9c1efbd0d..dc9591adc78 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Dec 5 03:14:53 2017 +# Autogenerated by Sphinx on Mon Jan 8 21:23:03 2018 topics = {'assert': 'The "assert" statement\n' '**********************\n' '\n' @@ -571,6 +571,65 @@ ' sorts it.\n' '\n' '\n' + 'Customizing module attribute access\n' + '===================================\n' + '\n' + 'Special names "__getattr__" and "__dir__" can be also ' + 'used to\n' + 'customize access to module attributes. The "__getattr__" ' + 'function at\n' + 'the module level should accept one argument which is the ' + 'name of an\n' + 'attribute and return the computed value or raise an ' + '"AttributeError".\n' + 'If an attribute is not found on a module object through ' + 'the normal\n' + 'lookup, i.e. "object.__getattribute__()", then ' + '"__getattr__" is\n' + 'searched in the module "__dict__" before raising an ' + '"AttributeError".\n' + 'If found, it is called with the attribute name and the ' + 'result is\n' + 'returned.\n' + '\n' + 'The "__dir__" function should accept no arguments, and ' + 'return a list\n' + 'of strings that represents the names accessible on ' + 'module. If present,\n' + 'this function overrides the standard "dir()" search on a ' + 'module.\n' + '\n' + 'For a more fine grained customization of the module ' + 'behavior (setting\n' + 'attributes, properties, etc.), one can set the ' + '"__class__" attribute\n' + 'of a module object to a subclass of "types.ModuleType". ' + 'For example:\n' + '\n' + ' import sys\n' + ' from types import ModuleType\n' + '\n' + ' class VerboseModule(ModuleType):\n' + ' def __repr__(self):\n' + " return f'Verbose {self.__name__}'\n" + '\n' + ' def __setattr__(self, attr, value):\n' + " print(f'Setting {attr}...')\n" + ' setattr(self, attr, value)\n' + '\n' + ' sys.modules[__name__].__class__ = VerboseModule\n' + '\n' + 'Note: Defining module "__getattr__" and setting module ' + '"__class__"\n' + ' only affect lookups made using the attribute access ' + 'syntax --\n' + ' directly accessing the module globals (whether by code ' + 'within the\n' + " module, or via a reference to the module's globals " + 'dictionary) is\n' + ' unaffected.\n' + '\n' + '\n' 'Implementing Descriptors\n' '========================\n' '\n' @@ -2905,63 +2964,52 @@ '\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 ' + ' called a finalizer or (improperly) a destructor. If a ' + 'base class\n' + ' has a "__del__()" method, the derived class\'s ' + '"__del__()" method,\n' + ' if any, must explicitly call it to ensure proper ' + 'deletion of the\n' + ' base class part of the instance.\n' + '\n' + ' It is possible (though not recommended!) for the ' + '"__del__()" method\n' + ' to postpone destruction of the instance by creating a ' + 'new reference\n' + ' to it. This is called object *resurrection*. It is\n' + ' implementation-dependent whether "__del__()" is called a ' + 'second\n' + ' time when a resurrected object is about to be destroyed; ' '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' + ' current *CPython* implementation only calls it once.\n' + '\n' + ' It is not guaranteed that "__del__()" methods are called ' + 'for\n' + ' objects that still exist when 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 ' + ' only called when "x"\'s reference count reaches zero.\n' + '\n' + ' **CPython implementation detail:** It is possible for 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' + ' cycle to prevent the reference count of an object from ' + 'going to\n' + ' zero. In this case, the cycle will be later detected ' + 'and deleted\n' + ' by the *cyclic garbage collector*. A common cause of ' + 'reference\n' + ' cycles is when an exception has been caught in a local ' + 'variable.\n' + " The frame's locals then reference the exception, which " + 'references\n' + ' its own traceback, which references the locals of all ' + 'frames caught\n' + ' in the traceback.\n' + '\n' + ' See also: Documentation for the "gc" module.\n' '\n' ' Warning: Due to the precarious circumstances under ' 'which\n' @@ -2969,29 +3017,35 @@ '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 ' + ' "sys.stderr" instead. In particular:\n' + '\n' + ' * "__del__()" can be invoked when arbitrary code is ' + 'being\n' + ' executed, including from any arbitrary thread. If ' '"__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' + ' needs to take a lock or invoke any other blocking ' + 'resource, it\n' + ' may deadlock as the resource may already be taken by ' + 'the code\n' + ' that gets interrupted to execute "__del__()".\n' + '\n' + ' * "__del__()" can be executed during interpreter ' + 'shutdown. As\n' + ' a consequence, the global variables it needs to ' + 'access\n' + ' (including other modules) may already have been ' + 'deleted or set\n' + ' to "None". Python guarantees that globals whose name ' + 'begins\n' + ' with a single underscore are deleted from their ' + 'module before\n' + ' other globals are deleted; if no other references to ' + 'such\n' + ' globals exist, this may help in assuring that ' + 'imported modules\n' + ' are still available at the time when the "__del__()" ' + 'method is\n' + ' called.\n' '\n' 'object.__repr__(self)\n' '\n' @@ -3346,6 +3400,13 @@ 'executes\n' 'commands as if given in a ".pdbrc" file, see Debugger Commands.\n' '\n' + 'New in version 3.7: "pdb.py" now accepts a "-m" option that ' + 'execute\n' + 'modules similar to the way "python3 -m" does. As with a script, ' + 'the\n' + 'debugger will pause execution just before the first line of the\n' + 'module.\n' + '\n' 'The typical usage to break into the debugger from a running ' 'program is\n' 'to insert\n' @@ -7563,91 +7624,87 @@ '\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 ' + ' called a finalizer or (improperly) a destructor. If a ' + 'base class\n' + ' has a "__del__()" method, the derived class\'s ' + '"__del__()" method,\n' + ' if any, must explicitly call it to ensure proper deletion ' + 'of the\n' + ' base class part of the instance.\n' + '\n' + ' It is possible (though not recommended!) for the ' + '"__del__()" method\n' + ' to postpone destruction of the instance by creating a new ' + 'reference\n' + ' to it. This is called object *resurrection*. It is\n' + ' implementation-dependent whether "__del__()" is called a ' + 'second\n' + ' time when a resurrected object is about to be destroyed; ' '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' + ' current *CPython* implementation only calls it once.\n' + '\n' + ' It is not guaranteed that "__del__()" methods are called ' + 'for\n' + ' objects that still exist when 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 ' + ' only called when "x"\'s reference count reaches zero.\n' + '\n' + ' **CPython implementation detail:** It is possible for 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' + ' cycle to prevent the reference count of an object from ' + 'going to\n' + ' zero. In this case, the cycle will be later detected and ' + 'deleted\n' + ' by the *cyclic garbage collector*. A common cause of ' + 'reference\n' + ' cycles is when an exception has been caught in a local ' + 'variable.\n' + " The frame's locals then reference the exception, which " + 'references\n' + ' its own traceback, which references the locals of all ' + 'frames caught\n' + ' in the traceback.\n' + '\n' + ' See also: Documentation for the "gc" module.\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 ' + ' "sys.stderr" instead. In particular:\n' + '\n' + ' * "__del__()" can be invoked when arbitrary code is ' + 'being\n' + ' executed, including from any arbitrary thread. If ' '"__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' + ' needs to take a lock or invoke any other blocking ' + 'resource, it\n' + ' may deadlock as the resource may already be taken by ' + 'the code\n' + ' that gets interrupted to execute "__del__()".\n' + '\n' + ' * "__del__()" can be executed during interpreter ' + 'shutdown. As\n' + ' a consequence, the global variables it needs to ' + 'access\n' + ' (including other modules) may already have been ' + 'deleted or set\n' + ' to "None". Python guarantees that globals whose name ' + 'begins\n' + ' with a single underscore are deleted from their ' + 'module before\n' + ' other globals are deleted; if no other references to ' + 'such\n' + ' globals exist, this may help in assuring that ' + 'imported modules\n' + ' are still available at the time when the "__del__()" ' + 'method is\n' + ' called.\n' '\n' 'object.__repr__(self)\n' '\n' @@ -8031,6 +8088,65 @@ ' sorts it.\n' '\n' '\n' + 'Customizing module attribute access\n' + '-----------------------------------\n' + '\n' + 'Special names "__getattr__" and "__dir__" can be also used ' + 'to\n' + 'customize access to module attributes. The "__getattr__" ' + 'function at\n' + 'the module level should accept one argument which is the ' + 'name of an\n' + 'attribute and return the computed value or raise an ' + '"AttributeError".\n' + 'If an attribute is not found on a module object through the ' + 'normal\n' + 'lookup, i.e. "object.__getattribute__()", then "__getattr__" ' + 'is\n' + 'searched in the module "__dict__" before raising an ' + '"AttributeError".\n' + 'If found, it is called with the attribute name and the ' + 'result is\n' + 'returned.\n' + '\n' + 'The "__dir__" function should accept no arguments, and ' + 'return a list\n' + 'of strings that represents the names accessible on module. ' + 'If present,\n' + 'this function overrides the standard "dir()" search on a ' + 'module.\n' + '\n' + 'For a more fine grained customization of the module behavior ' + '(setting\n' + 'attributes, properties, etc.), one can set the "__class__" ' + 'attribute\n' + 'of a module object to a subclass of "types.ModuleType". For ' + 'example:\n' + '\n' + ' import sys\n' + ' from types import ModuleType\n' + '\n' + ' class VerboseModule(ModuleType):\n' + ' def __repr__(self):\n' + " return f'Verbose {self.__name__}'\n" + '\n' + ' def __setattr__(self, attr, value):\n' + " print(f'Setting {attr}...')\n" + ' setattr(self, attr, value)\n' + '\n' + ' sys.modules[__name__].__class__ = VerboseModule\n' + '\n' + 'Note: Defining module "__getattr__" and setting module ' + '"__class__"\n' + ' only affect lookups made using the attribute access syntax ' + '--\n' + ' directly accessing the module globals (whether by code ' + 'within the\n' + " module, or via a reference to the module's globals " + 'dictionary) is\n' + ' unaffected.\n' + '\n' + '\n' 'Implementing Descriptors\n' '------------------------\n' '\n' @@ -12211,18 +12327,18 @@ ' 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' + 'Not\n' + ' all implementations support passing the additional arguments ' + '*i*\n' + ' and *j*. These arguments allow efficient searching of ' + 'subsections\n' + ' of the sequence. Passing the extra arguments is roughly ' + 'equivalent\n' + ' to using "s[i:j].index(x)", only without copying any data and ' + 'with\n' + ' the returned index being relative to the start of the ' + 'sequence\n' + ' rather than the start of the slice.\n' '\n' '\n' 'Immutable Sequence Types\n' diff --git a/Misc/NEWS.d/3.7.0a4.rst b/Misc/NEWS.d/3.7.0a4.rst new file mode 100644 index 00000000000..cc90bd68de0 --- /dev/null +++ b/Misc/NEWS.d/3.7.0a4.rst @@ -0,0 +1,847 @@ +.. bpo: 31975 +.. date: 2018-01-05-20-54-27 +.. nonce: AmftlU +.. release date: 2018-01-08 +.. section: Core and Builtins + +The default warning filter list now starts with a +"default::DeprecationWarning:__main__" entry, so deprecation warnings are +once again shown by default in single-file scripts and at the interactive +prompt. + +.. + +.. bpo: 32226 +.. date: 2018-01-04-15-06-15 +.. nonce: 7cAvRG +.. section: Core and Builtins + +``__class_getitem__`` is now an automatic class method. + +.. + +.. bpo: 32399 +.. date: 2017-12-22-13-38-17 +.. nonce: wlH12z +.. section: Core and Builtins + +Add AIX uuid library support for RFC4122 using uuid_create() in libc.a + +.. + +.. bpo: 32390 +.. date: 2017-12-22-13-28-07 +.. nonce: QPj083 +.. section: Core and Builtins + +Fix the compilation failure on AIX after the f_fsid field has been added to +the object returned by os.statvfs() (issue #32143). Original patch by +Michael Felt. + +.. + +.. bpo: 32379 +.. date: 2017-12-19-21-14-41 +.. nonce: B7mOmI +.. section: Core and Builtins + +Make MRO computation faster when a class inherits from a single base. + +.. + +.. bpo: 32259 +.. date: 2017-12-16-14-30-21 +.. nonce: GoOJiX +.. section: Core and Builtins + +The error message of a TypeError raised when unpack non-iterable is now more +specific. + +.. + +.. bpo: 27169 +.. date: 2017-12-15-11-50-06 +.. nonce: VO84fQ +.. section: Core and Builtins + +The ``__debug__`` constant is now optimized out at compile time. This fixes +also bpo-22091. + +.. + +.. bpo: 32329 +.. date: 2017-12-15-00-13-04 +.. nonce: q47IN2 +.. section: Core and Builtins + +The :option:`-R` option now turns on hash randomization when the +:envvar:`PYTHONHASHSEED` environment variable is set to ``0``. Previously, +the option was ignored. Moreover, ``sys.flags.hash_randomization`` is now +properly set to 0 when hash randomization is turned off by +``PYTHONHASHSEED=0``. + +.. + +.. bpo: 30416 +.. date: 2017-12-14-11-48-19 +.. nonce: hlHo_9 +.. section: Core and Builtins + +The optimizer is now protected from spending much time doing complex +calculations and consuming much memory for creating large constants in +constant folding. Increased limits for constants that can be produced in +constant folding. + +.. + +.. bpo: 32282 +.. date: 2017-12-12-14-02-28 +.. nonce: xFVMTn +.. section: Core and Builtins + +Fix an unnecessary ifdef in the include of VersionHelpers.h in socketmodule +on Windows. + +.. + +.. bpo: 30579 +.. date: 2017-12-11-01-52-42 +.. nonce: X6cEzf +.. section: Core and Builtins + +Implement TracebackType.__new__ to allow Python-level creation of traceback +objects, and make TracebackType.tb_next mutable. + +.. + +.. bpo: 32260 +.. date: 2017-12-09-11-03-51 +.. nonce: 1DAO-p +.. section: Core and Builtins + +Don't byte swap the input keys to the SipHash algorithm on big-endian +platforms. This should ensure siphash gives consistent results across +platforms. + +.. + +.. bpo: 31506 +.. date: 2017-12-07-23-44-29 +.. nonce: j1U2fU +.. section: Core and Builtins + +Improve the error message logic for object.__new__ and object.__init__. +Patch by Sanyam Khurana. + +.. + +.. bpo: 20361 +.. date: 2017-12-07-17-22-30 +.. nonce: zQUmbi +.. section: Core and Builtins + +``-b`` and ``-bb`` now inject ``'default::BytesWarning'`` and +``error::BytesWarning`` entries into ``sys.warnoptions``, ensuring that they +take precedence over any other warning filters configured via the ``-W`` +option or the ``PYTHONWARNINGS`` environment variable. + +.. + +.. bpo: 32230 +.. date: 2017-12-06-20-18-34 +.. nonce: PgGQaB +.. section: Core and Builtins + +`-X dev` now injects a ``'default'`` entry into sys.warnoptions, ensuring +that it behaves identically to actually passing ``-Wdefault`` at the command +line. + +.. + +.. bpo: 29240 +.. date: 2017-12-05-23-10-58 +.. nonce: qpJP5l +.. section: Core and Builtins + +Add a new UTF-8 mode: implementation of the :pep:`540`. + +.. + +.. bpo: 32226 +.. date: 2017-12-05-21-42-58 +.. nonce: G8fqb6 +.. section: Core and Builtins + +PEP 560: Add support for __mro_entries__ and __class_getitem__. Implemented +by Ivan Levkivskyi. + +.. + +.. bpo: 32225 +.. date: 2017-12-05-21-33-47 +.. nonce: ucKjvw +.. section: Core and Builtins + +PEP 562: Add support for module ``__getattr__`` and ``__dir__``. Implemented +by Ivan Levkivskyi. + +.. + +.. bpo: 31901 +.. date: 2017-11-28-15-04-14 +.. nonce: mDeCLK +.. section: Core and Builtins + +The `atexit` module now has its callback stored per interpreter. + +.. + +.. bpo: 31650 +.. date: 2017-11-26-14-38-44 +.. nonce: JWf_Im +.. section: Core and Builtins + +Implement PEP 552 (Deterministic pycs). Python now supports invalidating +bytecode cache files bashed on a source content hash rather than source +last-modified time. + +.. + +.. bpo: 29469 +.. date: 2017-07-26-00-20-15 +.. nonce: potmyI +.. section: Core and Builtins + +Move constant folding from bytecode layer to AST layer. Original patch by +Eugene Toder. + +.. + +.. bpo: 32506 +.. date: 2018-01-07-11-32-42 +.. nonce: MaT-zU +.. section: Library + +Now that dict is defined as keeping insertion order, drop OrderedDict and +just use plain dict. + +.. + +.. bpo: 32279 +.. date: 2018-01-06-16-50-11 +.. nonce: 1xOpU8 +.. section: Library + +Add params to dataclasses.make_dataclasses(): init, repr, eq, order, hash, +and frozen. Pass them through to dataclass(). + +.. + +.. bpo: 32278 +.. date: 2018-01-06-15-15-34 +.. nonce: bGnGc0 +.. section: Library + +Make type information optional on dataclasses.make_dataclass(). If omitted, +the string 'typing.Any' is used. + +.. + +.. bpo: 32499 +.. date: 2018-01-06-10-54-16 +.. nonce: koyY-4 +.. section: Library + +Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass +or an instance of one. + +.. + +.. bpo: 32468 +.. date: 2017-12-31-20-32-58 +.. nonce: YBs__0 +.. section: Library + +Improve frame repr() to mention filename, code name and current line number. + +.. + +.. bpo: 23749 +.. date: 2017-12-29-00-44-42 +.. nonce: QL1Cxd +.. section: Library + +asyncio: Implement loop.start_tls() + +.. + +.. bpo: 32441 +.. date: 2017-12-28-21-30-40 +.. nonce: LqlboJ +.. section: Library + +Return the new file descriptor (i.e., the second argument) from ``os.dup2``. +Previously, ``None`` was always returned. + +.. + +.. bpo: 32422 +.. date: 2017-12-25-20-22-47 +.. nonce: 5H3Wq2 +.. section: Library + +``functools.lru_cache`` uses less memory (3 words for each cached key) and +takes about 1/3 time for cyclic GC. + +.. + +.. bpo: 31721 +.. date: 2017-12-25-11-09-46 +.. nonce: 5gM972 +.. section: Library + +Prevent Python crash from happening when Future._log_traceback is set to +True manually. Now it can only be set to False, or a ValueError is raised. + +.. + +.. bpo: 32415 +.. date: 2017-12-23-12-45-00 +.. nonce: YufXTU +.. section: Library + +asyncio: Add Task.get_loop() and Future.get_loop() + +.. + +.. bpo: 26133 +.. date: 2017-12-21-11-08-42 +.. nonce: mt81QV +.. section: Library + +Don't unsubscribe signals in asyncio UNIX event loop on interpreter +shutdown. + +.. + +.. bpo: 32363 +.. date: 2017-12-19-00-37-28 +.. nonce: YTeGU0 +.. section: Library + +Make asyncio.Task.set_exception() and set_result() raise +NotImplementedError. Task._step() and Future.__await__() raise proper +exceptions when they are in an invalid state, instead of raising an +AssertionError. + +.. + +.. bpo: 32357 +.. date: 2017-12-18-00-36-41 +.. nonce: t1F3sn +.. section: Library + +Optimize asyncio.iscoroutine() and loop.create_task() for non-native +coroutines (e.g. async/await compiled with Cython). + +'loop.create_task(python_coroutine)' used to be 20% faster than +'loop.create_task(cython_coroutine)'. Now, the latter is as fast. + +.. + +.. bpo: 32356 +.. date: 2017-12-17-22-50-51 +.. nonce: roZJpA +.. section: Library + +asyncio.transport.resume_reading() and pause_reading() are now idempotent. +New transport.is_reading() method is added. + +.. + +.. bpo: 32355 +.. date: 2017-12-17-21-42-24 +.. nonce: tbaTWA +.. section: Library + +Optimize asyncio.gather(); now up to 15% faster. + +.. + +.. bpo: 32351 +.. date: 2017-12-17-14-23-23 +.. nonce: 95fh2K +.. section: Library + +Use fastpath in asyncio.sleep if delay<0 (2x boost) + +.. + +.. bpo: 32348 +.. date: 2017-12-16-18-50-57 +.. nonce: 5j__he +.. section: Library + +Optimize asyncio.Future schedule/add/remove callback. The optimization +shows 3-6% performance improvements of async/await code. + +.. + +.. bpo: 32331 +.. date: 2017-12-15-23-48-43 +.. nonce: fIg1Uc +.. section: Library + +Fix socket.settimeout() and socket.setblocking() to keep socket.type as is. +Fix socket.socket() constructor to reset any bit flags applied to socket's +type. This change only affects OSes that have SOCK_NONBLOCK and/or +SOCK_CLOEXEC. + +.. + +.. bpo: 32248 +.. date: 2017-12-15-15-34-12 +.. nonce: zmO8G2 +.. section: Library + +Add :class:`importlib.abc.ResourceReader` as an ABC for loaders to provide a +unified API for reading resources contained within packages. Also add +:mod:`importlib.resources` as the port of ``importlib_resources``. + +.. + +.. bpo: 32311 +.. date: 2017-12-14-17-28-54 +.. nonce: DL5Ytn +.. section: Library + +Implement asyncio.create_task(coro) shortcut + +.. + +.. bpo: 32327 +.. date: 2017-12-14-16-00-25 +.. nonce: bbkSxA +.. section: Library + +Convert asyncio functions that were documented as coroutines to coroutines. +Affected functions: loop.sock_sendall, loop.sock_recv, loop.sock_accept, +loop.run_in_executor, loop.getaddrinfo, loop.getnameinfo. + +.. + +.. bpo: 32323 +.. date: 2017-12-14-10-10-10 +.. nonce: ideco +.. section: Library + +:func:`urllib.parse.urlsplit()` does not convert zone-id (scope) to lower +case for scoped IPv6 addresses in hostnames now. + +.. + +.. bpo: 32302 +.. date: 2017-12-13-22-38-08 +.. nonce: othtTr +.. section: Library + +Fix bdist_wininst of distutils for CRT v142: it binary compatible with CRT +v140. + +.. + +.. bpo: 29711 +.. date: 2017-12-13-22-10-36 +.. nonce: hJjghA +.. section: Library + +Fix ``stop_serving`` in asyncio proactor loop kill all listening servers + +.. + +.. bpo: 32308 +.. date: 2017-12-13-20-31-30 +.. nonce: CUbsb2 +.. section: Library + +:func:`re.sub()` now replaces empty matches adjacent to a previous non-empty +match. + +.. + +.. bpo: 29970 +.. date: 2017-12-13-19-02-38 +.. nonce: uxVOpk +.. section: Library + +Abort asyncio SSLProtocol connection if handshake not complete within 10s + +.. + +.. bpo: 32314 +.. date: 2017-12-13-16-47-38 +.. nonce: W4_U2j +.. section: Library + +Implement asyncio.run(). + +.. + +.. bpo: 17852 +.. date: 2017-12-13-00-00-37 +.. nonce: Q8BP8N +.. section: Library + +Revert incorrect fix based on misunderstanding of _Py_PyAtExit() semantics. + +.. + +.. bpo: 32296 +.. date: 2017-12-12-18-01-01 +.. nonce: bwscHz +.. section: Library + +Implement asyncio._get_running_loop() and get_event_loop() in C. This makes +them 4x faster. + +.. + +.. bpo: 32250 +.. date: 2017-12-12-16-58-20 +.. nonce: UljTa0 +.. section: Library + +Implement ``asyncio.current_task()`` and ``asyncio.all_tasks()``. Add +helpers intended to be used by alternative task implementations: +``asyncio._register_task``, ``asyncio._enter_task``, ``asyncio._leave_task`` +and ``asyncio._unregister_task``. Deprecate ``asyncio.Task.current_task()`` +and ``asyncio.Task.all_tasks()``. + +.. + +.. bpo: 32255 +.. date: 2017-12-12-07-29-06 +.. nonce: 2bfNmM +.. section: Library + +A single empty field is now always quoted when written into a CSV file. This +allows to distinguish an empty row from a row consisting of a single empty +field. Patch by Licht Takeuchi. + +.. + +.. bpo: 32277 +.. date: 2017-12-11-09-53-14 +.. nonce: jkKiVC +.. section: Library + +Raise ``NotImplementedError`` instead of ``SystemError`` on platforms where +``chmod(..., follow_symlinks=False)`` is not supported. Patch by Anthony +Sottile. + +.. + +.. bpo: 30050 +.. date: 2017-12-10-23-44-56 +.. nonce: 4SZ3lY +.. section: Library + +New argument warn_on_full_buffer to signal.set_wakeup_fd lets you control +whether Python prints a warning on stderr when the wakeup fd buffer +overflows. + +.. + +.. bpo: 29137 +.. date: 2017-12-10-21-19-14 +.. nonce: CFcON1 +.. section: Library + +The ``fpectl`` library has been removed. It was never enabled by default, +never worked correctly on x86-64, and it changed the Python ABI in ways that +caused unexpected breakage of C extensions. + +.. + +.. bpo: 32273 +.. date: 2017-12-10-19-14-55 +.. nonce: 5KKlCv +.. section: Library + +Move asyncio.test_utils to test.test_asyncio. + +.. + +.. bpo: 32272 +.. date: 2017-12-10-18-59-13 +.. nonce: Mu84Am +.. section: Library + +Remove asyncio.async() function. + +.. + +.. bpo: 32269 +.. date: 2017-12-10-12-30-13 +.. nonce: Q85pKj +.. section: Library + +Add asyncio.get_running_loop() function. + +.. + +.. bpo: 32265 +.. date: 2017-12-10-00-57-51 +.. nonce: kELtTE +.. section: Library + +All class and static methods of builtin types now are correctly classified +by inspect.classify_class_attrs() and grouped in pydoc ouput. Added +types.ClassMethodDescriptorType for unbound class methods of builtin types. + +.. + +.. bpo: 32253 +.. date: 2017-12-09-11-30-35 +.. nonce: TQHSYF +.. section: Library + +Deprecate ``yield from lock``, ``await lock``, ``with (yield from lock)`` +and ``with await lock`` for asyncio synchronization primitives. + +.. + +.. bpo: 22589 +.. date: 2017-12-08-15-09-41 +.. nonce: 8ouqI6 +.. section: Library + +Changed MIME type of .bmp from 'image/x-ms-bmp' to 'image/bmp' + +.. + +.. bpo: 32193 +.. date: 2017-12-08-11-02-26 +.. nonce: NJe_TQ +.. section: Library + +Convert asyncio to use *async/await* syntax. Old styled ``yield from`` is +still supported too. + +.. + +.. bpo: 32206 +.. date: 2017-12-07-13-14-40 +.. nonce: obm4OM +.. section: Library + +Add support to run modules with pdb + +.. + +.. bpo: 32227 +.. date: 2017-12-05-13-25-15 +.. nonce: 3vnWFS +.. section: Library + +``functools.singledispatch`` now supports registering implementations using +type annotations. + +.. + +.. bpo: 15873 +.. date: 2017-12-04-17-41-40 +.. nonce: -T4TRK +.. section: Library + +Added new alternate constructors :meth:`datetime.datetime.fromisoformat`, +:meth:`datetime.time.fromisoformat` and :meth:`datetime.date.fromisoformat` +as the inverse operation of each classes's respective ``isoformat`` methods. + +.. + +.. bpo: 32199 +.. date: 2017-12-04-12-23-26 +.. nonce: nGof4v +.. section: Library + +The getnode() ip getter now uses 'ip link' instead of 'ip link list'. + +.. + +.. bpo: 32143 +.. date: 2017-11-26-17-28-26 +.. nonce: o7YdXL +.. section: Library + +os.statvfs() includes the f_fsid field from statvfs(2) + +.. + +.. bpo: 26439 +.. date: 2017-11-24-08-35-43 +.. nonce: IC45_f +.. section: Library + +Fix ctypes.util.find_library() for AIX by implementing +ctypes._aix.find_library() Patch by: Michael Felt + +.. + +.. bpo: 31993 +.. date: 2017-11-10-00-05-08 +.. nonce: -OMNg8 +.. section: Library + +The picklers no longer allocate temporary memory when dumping large +``bytes`` and ``str`` objects into a file object. Instead the data is +directly streamed into the underlying file object. + +.. + +.. bpo: 27456 +.. date: 2017-11-02-11-57-41 +.. nonce: snzyTC +.. section: Library + +Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. + +.. + +.. bpo: 31778 +.. date: 2017-10-18-17-29-30 +.. nonce: B6vAkP +.. section: Library + +ast.literal_eval() is now more strict. Addition and subtraction of arbitrary +numbers no longer allowed. + +.. + +.. bpo: 31802 +.. date: 2017-10-17-14-52-14 +.. nonce: sYj2Zv +.. section: Library + +Importing native path module (``posixpath``, ``ntpath``) now works even if +the ``os`` module still is not imported. + +.. + +.. bpo: 30241 +.. date: 2017-10-10-18-56-46 +.. nonce: F_go20 +.. section: Library + +Add contextlib.AbstractAsyncContextManager. Patch by Jelle Zijlstra. + +.. + +.. bpo: 31699 +.. date: 2017-10-05-11-06-32 +.. nonce: MF47Y6 +.. section: Library + +Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when task +arguments or results cause pickling or unpickling errors. This should make +sure that calls to the :class:`ProcessPoolExecutor` API always eventually +return. + +.. + +.. bpo: 15216 +.. date: 2017-09-16-02-56-33 +.. nonce: lqXCTT +.. section: Library + +``TextIOWrapper.reconfigure()`` supports changing *encoding*, *errors*, and +*newline*. + +.. + +.. bpo: 32418 +.. date: 2017-12-24-17-29-37 +.. nonce: eZe-ID +.. section: Documentation + +Add get_loop() method to Server and AbstractServer classes. + +.. + +.. bpo: 32252 +.. date: 2017-12-11-13-31-33 +.. nonce: YnFw7J +.. section: Tests + +Fix faulthandler_suppress_crash_report() used to prevent core dump files +when testing crashes. getrlimit() returns zero on success. + +.. + +.. bpo: 32002 +.. date: 2017-11-11-16-35-18 +.. nonce: itDxIo +.. section: Tests + +Adjust C locale coercion testing for the empty locale and POSIX locale cases +to more readily adjust to platform dependent behaviour. + +.. + +.. bpo: 19764 +.. date: 2017-08-18-18-00-24 +.. nonce: ODpc9y +.. section: Windows + +Implement support for `subprocess.Popen(close_fds=True)` on Windows. Patch +by Segev Finer. + +.. + +.. bpo: 24960 +.. date: 2017-12-22-09-25-51 +.. nonce: TGdAgO +.. section: Tools/Demos + +2to3 and lib2to3 can now read pickled grammar files using pkgutil.get_data() +rather than probing the filesystem. This lets 2to3 and lib2to3 work when run +from a zipfile. + +.. + +.. bpo: 32030 +.. date: 2017-12-20-23-22-32 +.. nonce: d1dcwh +.. section: C API + +Py_Initialize() doesn't reset the memory allocators to default if the +``PYTHONMALLOC`` environment variable is not set. + +.. + +.. bpo: 29084 +.. date: 2017-12-16-09-59-35 +.. nonce: ZGJ-LJ +.. section: C API + +Undocumented C API for OrderedDict has been excluded from the limited C API. +It was added by mistake and actually never worked in the limited C API. + +.. + +.. bpo: 32264 +.. date: 2017-12-12-23-09-46 +.. nonce: ahRlOI +.. section: C API + +Moved the pygetopt.h header into internal/, since it has no public APIs. + +.. + +.. bpo: 32241 +.. date: 2017-12-07-15-58-15 +.. nonce: LbyQt6 +.. section: C API + +:c:func:`Py_SetProgramName` and :c:func:`Py_SetPythonHome` now take the +``const wchar *`` arguments instead of ``wchar *``. diff --git a/Misc/NEWS.d/next/C API/2017-12-07-15-58-15.bpo-32241.LbyQt6.rst b/Misc/NEWS.d/next/C API/2017-12-07-15-58-15.bpo-32241.LbyQt6.rst deleted file mode 100644 index 71fa8baa807..00000000000 --- a/Misc/NEWS.d/next/C API/2017-12-07-15-58-15.bpo-32241.LbyQt6.rst +++ /dev/null @@ -1,2 +0,0 @@ -:c:func:`Py_SetProgramName` and :c:func:`Py_SetPythonHome` now take the -``const wchar *`` arguments instead of ``wchar *``. diff --git a/Misc/NEWS.d/next/C API/2017-12-12-23-09-46.bpo-32264.ahRlOI.rst b/Misc/NEWS.d/next/C API/2017-12-12-23-09-46.bpo-32264.ahRlOI.rst deleted file mode 100644 index 5033d61a676..00000000000 --- a/Misc/NEWS.d/next/C API/2017-12-12-23-09-46.bpo-32264.ahRlOI.rst +++ /dev/null @@ -1 +0,0 @@ -Moved the pygetopt.h header into internal/, since it has no public APIs. diff --git a/Misc/NEWS.d/next/C API/2017-12-16-09-59-35.bpo-29084.ZGJ-LJ.rst b/Misc/NEWS.d/next/C API/2017-12-16-09-59-35.bpo-29084.ZGJ-LJ.rst deleted file mode 100644 index 940f7160772..00000000000 --- a/Misc/NEWS.d/next/C API/2017-12-16-09-59-35.bpo-29084.ZGJ-LJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Undocumented C API for OrderedDict has been excluded from the limited C API. -It was added by mistake and actually never worked in the limited C API. diff --git a/Misc/NEWS.d/next/C API/2017-12-20-23-22-32.bpo-32030.d1dcwh.rst b/Misc/NEWS.d/next/C API/2017-12-20-23-22-32.bpo-32030.d1dcwh.rst deleted file mode 100644 index 8e8b430e247..00000000000 --- a/Misc/NEWS.d/next/C API/2017-12-20-23-22-32.bpo-32030.d1dcwh.rst +++ /dev/null @@ -1,2 +0,0 @@ -Py_Initialize() doesn't reset the memory allocators to default if the -``PYTHONMALLOC`` environment variable is not set. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-07-26-00-20-15.bpo-29469.potmyI.rst b/Misc/NEWS.d/next/Core and Builtins/2017-07-26-00-20-15.bpo-29469.potmyI.rst deleted file mode 100644 index 138a913a4f8..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-07-26-00-20-15.bpo-29469.potmyI.rst +++ /dev/null @@ -1,2 +0,0 @@ -Move constant folding from bytecode layer to AST layer. -Original patch by Eugene Toder. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-11-26-14-38-44.bpo-31650.JWf_Im.rst b/Misc/NEWS.d/next/Core and Builtins/2017-11-26-14-38-44.bpo-31650.JWf_Im.rst deleted file mode 100644 index b653f0b27d2..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-11-26-14-38-44.bpo-31650.JWf_Im.rst +++ /dev/null @@ -1,3 +0,0 @@ -Implement PEP 552 (Deterministic pycs). Python now supports invalidating -bytecode cache files bashed on a source content hash rather than source -last-modified time. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-11-28-15-04-14.bpo-31901.mDeCLK.rst b/Misc/NEWS.d/next/Core and Builtins/2017-11-28-15-04-14.bpo-31901.mDeCLK.rst deleted file mode 100644 index 613eee0bf58..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-11-28-15-04-14.bpo-31901.mDeCLK.rst +++ /dev/null @@ -1 +0,0 @@ -The `atexit` module now has its callback stored per interpreter. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-33-47.bpo-32225.ucKjvw.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-33-47.bpo-32225.ucKjvw.rst deleted file mode 100644 index 5cde073dd63..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-33-47.bpo-32225.ucKjvw.rst +++ /dev/null @@ -1,2 +0,0 @@ -PEP 562: Add support for module ``__getattr__`` and ``__dir__``. Implemented by Ivan -Levkivskyi. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-42-58.bpo-32226.G8fqb6.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-42-58.bpo-32226.G8fqb6.rst deleted file mode 100644 index 97954fd1bb0..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-21-42-58.bpo-32226.G8fqb6.rst +++ /dev/null @@ -1,2 +0,0 @@ -PEP 560: Add support for __mro_entries__ and __class_getitem__. Implemented -by Ivan Levkivskyi. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-23-10-58.bpo-29240.qpJP5l.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-05-23-10-58.bpo-29240.qpJP5l.rst deleted file mode 100644 index dbd9d619411..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-05-23-10-58.bpo-29240.qpJP5l.rst +++ /dev/null @@ -1 +0,0 @@ -Add a new UTF-8 mode: implementation of the :pep:`540`. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-06-20-18-34.bpo-32230.PgGQaB.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-06-20-18-34.bpo-32230.PgGQaB.rst deleted file mode 100644 index b8656e4f25a..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-06-20-18-34.bpo-32230.PgGQaB.rst +++ /dev/null @@ -1,3 +0,0 @@ -`-X dev` now injects a ``'default'`` entry into sys.warnoptions, ensuring -that it behaves identically to actually passing ``-Wdefault`` at the command -line. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-07-17-22-30.bpo-20361.zQUmbi.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-07-17-22-30.bpo-20361.zQUmbi.rst deleted file mode 100644 index df7aed7f07a..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-07-17-22-30.bpo-20361.zQUmbi.rst +++ /dev/null @@ -1,4 +0,0 @@ -``-b`` and ``-bb`` now inject ``'default::BytesWarning'`` and -``error::BytesWarning`` entries into ``sys.warnoptions``, ensuring that they -take precedence over any other warning filters configured via the ``-W`` -option or the ``PYTHONWARNINGS`` environment variable. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-07-23-44-29.bpo-31506.j1U2fU.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-07-23-44-29.bpo-31506.j1U2fU.rst deleted file mode 100644 index ceb9ee2ce8a..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-07-23-44-29.bpo-31506.j1U2fU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Improve the error message logic for object.__new__ and object.__init__. -Patch by Sanyam Khurana. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-09-11-03-51.bpo-32260.1DAO-p.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-09-11-03-51.bpo-32260.1DAO-p.rst deleted file mode 100644 index 523ffe0a611..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-09-11-03-51.bpo-32260.1DAO-p.rst +++ /dev/null @@ -1,3 +0,0 @@ -Don't byte swap the input keys to the SipHash algorithm on big-endian -platforms. This should ensure siphash gives consistent results across -platforms. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst deleted file mode 100644 index 392ebf6a79e..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-11-01-52-42.bpo-30579.X6cEzf.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement TracebackType.__new__ to allow Python-level creation of -traceback objects, and make TracebackType.tb_next mutable. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst deleted file mode 100644 index 1c833c5439b..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-12-14-02-28.bpo-32282.xFVMTn.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix an unnecessary ifdef in the include of VersionHelpers.h in socketmodule -on Windows. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-14-11-48-19.bpo-30416.hlHo_9.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-14-11-48-19.bpo-30416.hlHo_9.rst deleted file mode 100644 index 532700e2481..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-14-11-48-19.bpo-30416.hlHo_9.rst +++ /dev/null @@ -1,4 +0,0 @@ -The optimizer is now protected from spending much time doing complex -calculations and consuming much memory for creating large constants in -constant folding. Increased limits for constants that can be produced in -constant folding. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-15-00-13-04.bpo-32329.q47IN2.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-15-00-13-04.bpo-32329.q47IN2.rst deleted file mode 100644 index 86bcf234477..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-15-00-13-04.bpo-32329.q47IN2.rst +++ /dev/null @@ -1,5 +0,0 @@ -The :option:`-R` option now turns on hash randomization when the -:envvar:`PYTHONHASHSEED` environment variable is set to ``0``. Previously, -the option was ignored. Moreover, ``sys.flags.hash_randomization`` is now -properly set to 0 when hash randomization is turned off by -``PYTHONHASHSEED=0``. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-15-11-50-06.bpo-27169.VO84fQ.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-15-11-50-06.bpo-27169.VO84fQ.rst deleted file mode 100644 index 81d1d15cbbd..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-15-11-50-06.bpo-27169.VO84fQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -The ``__debug__`` constant is now optimized out at compile time. This fixes also -bpo-22091. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-16-14-30-21.bpo-32259.GoOJiX.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-16-14-30-21.bpo-32259.GoOJiX.rst deleted file mode 100644 index 1129c759f9f..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-16-14-30-21.bpo-32259.GoOJiX.rst +++ /dev/null @@ -1,2 +0,0 @@ -The error message of a TypeError raised when unpack non-iterable is now more -specific. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-19-21-14-41.bpo-32379.B7mOmI.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-19-21-14-41.bpo-32379.B7mOmI.rst deleted file mode 100644 index 1050c61b9ec..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-19-21-14-41.bpo-32379.B7mOmI.rst +++ /dev/null @@ -1 +0,0 @@ -Make MRO computation faster when a class inherits from a single base. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst deleted file mode 100644 index 0e9c1bff540..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-28-07.bpo-32390.QPj083.rst +++ /dev/null @@ -1 +0,0 @@ -Fix the compilation failure on AIX after the f_fsid field has been added to the object returned by os.statvfs() (issue #32143). Original patch by Michael Felt. diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-38-17.bpo-32399.wlH12z.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-38-17.bpo-32399.wlH12z.rst deleted file mode 100644 index ab18f268c81..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2017-12-22-13-38-17.bpo-32399.wlH12z.rst +++ /dev/null @@ -1 +0,0 @@ -Add AIX uuid library support for RFC4122 using uuid_create() in libc.a diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst deleted file mode 100644 index 842775f3b93..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-01-04-15-06-15.bpo-32226.7cAvRG.rst +++ /dev/null @@ -1 +0,0 @@ -``__class_getitem__`` is now an automatic class method. diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst b/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst deleted file mode 100644 index 98cfae0dd8c..00000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2018-01-05-20-54-27.bpo-31975.AmftlU.rst +++ /dev/null @@ -1,4 +0,0 @@ -The default warning filter list now starts with a -"default::DeprecationWarning:__main__" entry, so deprecation warnings are -once again shown by default in single-file scripts and at the interactive -prompt. diff --git a/Misc/NEWS.d/next/Documentation/2017-12-24-17-29-37.bpo-32418.eZe-ID.rst b/Misc/NEWS.d/next/Documentation/2017-12-24-17-29-37.bpo-32418.eZe-ID.rst deleted file mode 100644 index 9441b74ef84..00000000000 --- a/Misc/NEWS.d/next/Documentation/2017-12-24-17-29-37.bpo-32418.eZe-ID.rst +++ /dev/null @@ -1 +0,0 @@ -Add get_loop() method to Server and AbstractServer classes. diff --git a/Misc/NEWS.d/next/Library/2017-09-16-02-56-33.bpo-15216.lqXCTT.rst b/Misc/NEWS.d/next/Library/2017-09-16-02-56-33.bpo-15216.lqXCTT.rst deleted file mode 100644 index 0e9fd558ff0..00000000000 --- a/Misc/NEWS.d/next/Library/2017-09-16-02-56-33.bpo-15216.lqXCTT.rst +++ /dev/null @@ -1,2 +0,0 @@ -``TextIOWrapper.reconfigure()`` supports changing *encoding*, *errors*, and -*newline*. diff --git a/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst b/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst deleted file mode 100644 index 49cbbb3b920..00000000000 --- a/Misc/NEWS.d/next/Library/2017-10-05-11-06-32.bpo-31699.MF47Y6.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix deadlocks in :class:`concurrent.futures.ProcessPoolExecutor` when -task arguments or results cause pickling or unpickling errors. -This should make sure that calls to the :class:`ProcessPoolExecutor` API -always eventually return. diff --git a/Misc/NEWS.d/next/Library/2017-10-10-18-56-46.bpo-30241.F_go20.rst b/Misc/NEWS.d/next/Library/2017-10-10-18-56-46.bpo-30241.F_go20.rst deleted file mode 100644 index 9b6c6f6e422..00000000000 --- a/Misc/NEWS.d/next/Library/2017-10-10-18-56-46.bpo-30241.F_go20.rst +++ /dev/null @@ -1 +0,0 @@ -Add contextlib.AbstractAsyncContextManager. Patch by Jelle Zijlstra. diff --git a/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst b/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst deleted file mode 100644 index 77df6bbe695..00000000000 --- a/Misc/NEWS.d/next/Library/2017-10-17-14-52-14.bpo-31802.sYj2Zv.rst +++ /dev/null @@ -1,2 +0,0 @@ -Importing native path module (``posixpath``, ``ntpath``) now works even if -the ``os`` module still is not imported. diff --git a/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst b/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst deleted file mode 100644 index 452ad6e4bd2..00000000000 --- a/Misc/NEWS.d/next/Library/2017-10-18-17-29-30.bpo-31778.B6vAkP.rst +++ /dev/null @@ -1,2 +0,0 @@ -ast.literal_eval() is now more strict. Addition and subtraction of -arbitrary numbers no longer allowed. diff --git a/Misc/NEWS.d/next/Library/2017-11-02-11-57-41.bpo-27456.snzyTC.rst b/Misc/NEWS.d/next/Library/2017-11-02-11-57-41.bpo-27456.snzyTC.rst deleted file mode 100644 index fa7b5616bb3..00000000000 --- a/Misc/NEWS.d/next/Library/2017-11-02-11-57-41.bpo-27456.snzyTC.rst +++ /dev/null @@ -1 +0,0 @@ -Ensure TCP_NODELAY is set on Linux. Tests by Victor Stinner. diff --git a/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst b/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst deleted file mode 100644 index b453e21c80c..00000000000 --- a/Misc/NEWS.d/next/Library/2017-11-10-00-05-08.bpo-31993.-OMNg8.rst +++ /dev/null @@ -1,14 +0,0 @@ -The picklers do no longer allocate temporary memory when dumping large -``bytes`` and ``str`` objects into a file object. Instead the data is -directly streamed into the underlying file object. - -Previously the C implementation would buffer all content and issue a -single call to ``file.write`` at the end of the dump. With protocol 4 -this behavior has changed to issue one call to ``file.write`` per frame. - -The Python pickler with protocol 4 now dumps each frame content as a -memoryview to an IOBytes instance that is never reused and the -memoryview is no longer released after the call to write. This makes it -possible for the file object to delay access to the memoryview of -previous frames without forcing any additional memory copy as was -already possible with the C pickler. diff --git a/Misc/NEWS.d/next/Library/2017-11-24-08-35-43.bpo-26439.IC45_f.rst b/Misc/NEWS.d/next/Library/2017-11-24-08-35-43.bpo-26439.IC45_f.rst deleted file mode 100644 index 91c9a45b503..00000000000 --- a/Misc/NEWS.d/next/Library/2017-11-24-08-35-43.bpo-26439.IC45_f.rst +++ /dev/null @@ -1,12 +0,0 @@ -Fix ctypes.util.find_library() for AIX -by implementing ctypes._aix.find_library() -Patch by: Michael Felt aka aixtools - -ctypes.util.find_library has always returned None on a standard AIX. -With this patch there is support for both AIX and svr4 shared libraries. -None is returned only when there is nothinbg found. Normal behavior is now: -on AIX find_library("FOO") returns either libFOO.a(libFOO.so) or libFOO.so -while legacy names e.g., find_library("c") returns libc.a(shr.o) -or libc.a(shr_64.o) - depending on 32 or 64-bit operations. -Include RTLD_MEMBER to mode to support AIX legacy library(member) names -(Modules/_ctype/posixmodule.c), ctypes/__init__.py and configure.ac) diff --git a/Misc/NEWS.d/next/Library/2017-11-26-17-28-26.bpo-32143.o7YdXL.rst b/Misc/NEWS.d/next/Library/2017-11-26-17-28-26.bpo-32143.o7YdXL.rst deleted file mode 100644 index f416ec504ec..00000000000 --- a/Misc/NEWS.d/next/Library/2017-11-26-17-28-26.bpo-32143.o7YdXL.rst +++ /dev/null @@ -1 +0,0 @@ -os.statvfs() includes the f_fsid field from statvfs(2) diff --git a/Misc/NEWS.d/next/Library/2017-12-04-12-23-26.bpo-32199.nGof4v.rst b/Misc/NEWS.d/next/Library/2017-12-04-12-23-26.bpo-32199.nGof4v.rst deleted file mode 100644 index d5f88cef5c7..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-04-12-23-26.bpo-32199.nGof4v.rst +++ /dev/null @@ -1 +0,0 @@ -The getnode() ip getter now uses 'ip link' instead of 'ip link list'. diff --git a/Misc/NEWS.d/next/Library/2017-12-04-17-41-40.bpo-15873.-T4TRK.rst b/Misc/NEWS.d/next/Library/2017-12-04-17-41-40.bpo-15873.-T4TRK.rst deleted file mode 100644 index 98a841597af..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-04-17-41-40.bpo-15873.-T4TRK.rst +++ /dev/null @@ -1,3 +0,0 @@ -Added new alternate constructors :meth:`datetime.datetime.fromisoformat`, -:meth:`datetime.time.fromisoformat` and :meth:`datetime.date.fromisoformat` -as the inverse operation of each classes's respective ``isoformat`` methods. diff --git a/Misc/NEWS.d/next/Library/2017-12-05-13-25-15.bpo-32227.3vnWFS.rst b/Misc/NEWS.d/next/Library/2017-12-05-13-25-15.bpo-32227.3vnWFS.rst deleted file mode 100644 index 4dbc7ba907b..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-05-13-25-15.bpo-32227.3vnWFS.rst +++ /dev/null @@ -1,2 +0,0 @@ -``functools.singledispatch`` now supports registering implementations using -type annotations. diff --git a/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst b/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst deleted file mode 100644 index 20d7eeace87..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-07-13-14-40.bpo-32206.obm4OM.rst +++ /dev/null @@ -1 +0,0 @@ -Add support to run modules with pdb diff --git a/Misc/NEWS.d/next/Library/2017-12-08-11-02-26.bpo-32193.NJe_TQ.rst b/Misc/NEWS.d/next/Library/2017-12-08-11-02-26.bpo-32193.NJe_TQ.rst deleted file mode 100644 index 6982f1e1ac5..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-08-11-02-26.bpo-32193.NJe_TQ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Convert asyncio to use *async/await* syntax. Old styled ``yield from`` is -still supported too. diff --git a/Misc/NEWS.d/next/Library/2017-12-08-15-09-41.bpo-22589.8ouqI6.rst b/Misc/NEWS.d/next/Library/2017-12-08-15-09-41.bpo-22589.8ouqI6.rst deleted file mode 100644 index e8469cba610..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-08-15-09-41.bpo-22589.8ouqI6.rst +++ /dev/null @@ -1 +0,0 @@ -Changed MIME type of .bmp from 'image/x-ms-bmp' to 'image/bmp' diff --git a/Misc/NEWS.d/next/Library/2017-12-09-11-30-35.bpo-32253.TQHSYF.rst b/Misc/NEWS.d/next/Library/2017-12-09-11-30-35.bpo-32253.TQHSYF.rst deleted file mode 100644 index 2916410e457..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-09-11-30-35.bpo-32253.TQHSYF.rst +++ /dev/null @@ -1,2 +0,0 @@ -Deprecate ``yield from lock``, ``await lock``, ``with (yield from lock)`` -and ``with await lock`` for asyncio synchronization primitives. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-00-57-51.bpo-32265.kELtTE.rst b/Misc/NEWS.d/next/Library/2017-12-10-00-57-51.bpo-32265.kELtTE.rst deleted file mode 100644 index 16686c1b418..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-00-57-51.bpo-32265.kELtTE.rst +++ /dev/null @@ -1,3 +0,0 @@ -All class and static methods of builtin types now are correctly classified -by inspect.classify_class_attrs() and grouped in pydoc ouput. Added -types.ClassMethodDescriptorType for unbound class methods of builtin types. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst b/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst deleted file mode 100644 index 9fa12446de2..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-12-30-13.bpo-32269.Q85pKj.rst +++ /dev/null @@ -1 +0,0 @@ -Add asyncio.get_running_loop() function. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-18-59-13.bpo-32272.Mu84Am.rst b/Misc/NEWS.d/next/Library/2017-12-10-18-59-13.bpo-32272.Mu84Am.rst deleted file mode 100644 index 500e3c8c2a5..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-18-59-13.bpo-32272.Mu84Am.rst +++ /dev/null @@ -1 +0,0 @@ -Remove asyncio.async() function. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-19-14-55.bpo-32273.5KKlCv.rst b/Misc/NEWS.d/next/Library/2017-12-10-19-14-55.bpo-32273.5KKlCv.rst deleted file mode 100644 index 3bbec8f6e34..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-19-14-55.bpo-32273.5KKlCv.rst +++ /dev/null @@ -1 +0,0 @@ -Move asyncio.test_utils to test.test_asyncio. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst b/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst deleted file mode 100644 index 85f3df5c8f5..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-21-19-14.bpo-29137.CFcON1.rst +++ /dev/null @@ -1,3 +0,0 @@ -The ``fpectl`` library has been removed. It was never enabled by default, -never worked correctly on x86-64, and it changed the Python ABI in ways that -caused unexpected breakage of C extensions. diff --git a/Misc/NEWS.d/next/Library/2017-12-10-23-44-56.bpo-30050.4SZ3lY.rst b/Misc/NEWS.d/next/Library/2017-12-10-23-44-56.bpo-30050.4SZ3lY.rst deleted file mode 100644 index 76de12bbe80..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-10-23-44-56.bpo-30050.4SZ3lY.rst +++ /dev/null @@ -1,3 +0,0 @@ -New argument warn_on_full_buffer to signal.set_wakeup_fd lets you control -whether Python prints a warning on stderr when the wakeup fd buffer -overflows. diff --git a/Misc/NEWS.d/next/Library/2017-12-11-09-53-14.bpo-32277.jkKiVC.rst b/Misc/NEWS.d/next/Library/2017-12-11-09-53-14.bpo-32277.jkKiVC.rst deleted file mode 100644 index 765527a6553..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-11-09-53-14.bpo-32277.jkKiVC.rst +++ /dev/null @@ -1,3 +0,0 @@ -Raise ``NotImplementedError`` instead of ``SystemError`` on platforms where -``chmod(..., follow_symlinks=False)`` is not supported. Patch by Anthony -Sottile. diff --git a/Misc/NEWS.d/next/Library/2017-12-12-07-29-06.bpo-32255.2bfNmM.rst b/Misc/NEWS.d/next/Library/2017-12-12-07-29-06.bpo-32255.2bfNmM.rst deleted file mode 100644 index dafee67bdd0..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-12-07-29-06.bpo-32255.2bfNmM.rst +++ /dev/null @@ -1,3 +0,0 @@ -A single empty field is now always quoted when written into a CSV file. -This allows to distinguish an empty row from a row consisting of a single empty field. -Patch by Licht Takeuchi. diff --git a/Misc/NEWS.d/next/Library/2017-12-12-16-58-20.bpo-32250.UljTa0.rst b/Misc/NEWS.d/next/Library/2017-12-12-16-58-20.bpo-32250.UljTa0.rst deleted file mode 100644 index f2d016df39a..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-12-16-58-20.bpo-32250.UljTa0.rst +++ /dev/null @@ -1,5 +0,0 @@ -Implement ``asyncio.current_task()`` and ``asyncio.all_tasks()``. Add -helpers intended to be used by alternative task implementations: -``asyncio._register_task``, ``asyncio._enter_task``, ``asyncio._leave_task`` -and ``asyncio._unregister_task``. Deprecate ``asyncio.Task.current_task()`` -and ``asyncio.Task.all_tasks()``. diff --git a/Misc/NEWS.d/next/Library/2017-12-12-18-01-01.bpo-32296.bwscHz.rst b/Misc/NEWS.d/next/Library/2017-12-12-18-01-01.bpo-32296.bwscHz.rst deleted file mode 100644 index 4100d48518e..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-12-18-01-01.bpo-32296.bwscHz.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement asyncio._get_running_loop() and get_event_loop() in C. This makes -them 4x faster. diff --git a/Misc/NEWS.d/next/Library/2017-12-13-00-00-37.bpo-17852.Q8BP8N.rst b/Misc/NEWS.d/next/Library/2017-12-13-00-00-37.bpo-17852.Q8BP8N.rst deleted file mode 100644 index 768108d5a54..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-00-00-37.bpo-17852.Q8BP8N.rst +++ /dev/null @@ -1 +0,0 @@ -Revert incorrect fix based on misunderstanding of _Py_PyAtExit() semantics. diff --git a/Misc/NEWS.d/next/Library/2017-12-13-16-47-38.bpo-32314.W4_U2j.rst b/Misc/NEWS.d/next/Library/2017-12-13-16-47-38.bpo-32314.W4_U2j.rst deleted file mode 100644 index 416906c9662..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-16-47-38.bpo-32314.W4_U2j.rst +++ /dev/null @@ -1 +0,0 @@ -Implement asyncio.run(). diff --git a/Misc/NEWS.d/next/Library/2017-12-13-19-02-38.bpo-29970.uxVOpk.rst b/Misc/NEWS.d/next/Library/2017-12-13-19-02-38.bpo-29970.uxVOpk.rst deleted file mode 100644 index d3d9ae94b32..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-19-02-38.bpo-29970.uxVOpk.rst +++ /dev/null @@ -1 +0,0 @@ -Abort asyncio SSLProtocol connection if handshake not complete within 10s diff --git a/Misc/NEWS.d/next/Library/2017-12-13-20-31-30.bpo-32308.CUbsb2.rst b/Misc/NEWS.d/next/Library/2017-12-13-20-31-30.bpo-32308.CUbsb2.rst deleted file mode 100644 index d760d6089ba..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-20-31-30.bpo-32308.CUbsb2.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`re.sub()` now replaces empty matches adjacent to a previous non-empty -match. diff --git a/Misc/NEWS.d/next/Library/2017-12-13-22-10-36.bpo-29711.hJjghA.rst b/Misc/NEWS.d/next/Library/2017-12-13-22-10-36.bpo-29711.hJjghA.rst deleted file mode 100644 index 6774172fb6b..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-22-10-36.bpo-29711.hJjghA.rst +++ /dev/null @@ -1 +0,0 @@ -Fix ``stop_serving`` in asyncio proactor loop kill all listening servers diff --git a/Misc/NEWS.d/next/Library/2017-12-13-22-38-08.bpo-32302.othtTr.rst b/Misc/NEWS.d/next/Library/2017-12-13-22-38-08.bpo-32302.othtTr.rst deleted file mode 100644 index abe51f094a8..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-13-22-38-08.bpo-32302.othtTr.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix bdist_wininst of distutils for CRT v142: it binary compatible with CRT -v140. diff --git a/Misc/NEWS.d/next/Library/2017-12-14-10-10-10.bpo-32323.ideco.rst b/Misc/NEWS.d/next/Library/2017-12-14-10-10-10.bpo-32323.ideco.rst deleted file mode 100644 index 3077d7cdfef..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-14-10-10-10.bpo-32323.ideco.rst +++ /dev/null @@ -1,2 +0,0 @@ -:func:`urllib.parse.urlsplit()` does not convert zone-id (scope) to lower case -for scoped IPv6 addresses in hostnames now. diff --git a/Misc/NEWS.d/next/Library/2017-12-14-16-00-25.bpo-32327.bbkSxA.rst b/Misc/NEWS.d/next/Library/2017-12-14-16-00-25.bpo-32327.bbkSxA.rst deleted file mode 100644 index 5fd9fbca4b4..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-14-16-00-25.bpo-32327.bbkSxA.rst +++ /dev/null @@ -1,3 +0,0 @@ -Convert asyncio functions that were documented as coroutines to coroutines. -Affected functions: loop.sock_sendall, loop.sock_recv, loop.sock_accept, -loop.run_in_executor, loop.getaddrinfo, loop.getnameinfo. diff --git a/Misc/NEWS.d/next/Library/2017-12-14-17-28-54.bpo-32311.DL5Ytn.rst b/Misc/NEWS.d/next/Library/2017-12-14-17-28-54.bpo-32311.DL5Ytn.rst deleted file mode 100644 index e2d10959476..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-14-17-28-54.bpo-32311.DL5Ytn.rst +++ /dev/null @@ -1 +0,0 @@ -Implement asyncio.create_task(coro) shortcut diff --git a/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst b/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst deleted file mode 100644 index 02b7e5fef11..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-15-15-34-12.bpo-32248.zmO8G2.rst +++ /dev/null @@ -1,3 +0,0 @@ -Add :class:`importlib.abc.ResourceReader` as an ABC for loaders to provide a -unified API for reading resources contained within packages. Also add -:mod:`importlib.resources` as the port of ``importlib_resources``. diff --git a/Misc/NEWS.d/next/Library/2017-12-15-23-48-43.bpo-32331.fIg1Uc.rst b/Misc/NEWS.d/next/Library/2017-12-15-23-48-43.bpo-32331.fIg1Uc.rst deleted file mode 100644 index 53a262cf220..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-15-23-48-43.bpo-32331.fIg1Uc.rst +++ /dev/null @@ -1,4 +0,0 @@ -Fix socket.settimeout() and socket.setblocking() to keep socket.type -as is. Fix socket.socket() constructor to reset any bit flags applied to -socket's type. This change only affects OSes that have SOCK_NONBLOCK -and/or SOCK_CLOEXEC. diff --git a/Misc/NEWS.d/next/Library/2017-12-16-18-50-57.bpo-32348.5j__he.rst b/Misc/NEWS.d/next/Library/2017-12-16-18-50-57.bpo-32348.5j__he.rst deleted file mode 100644 index b3618db7c33..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-16-18-50-57.bpo-32348.5j__he.rst +++ /dev/null @@ -1,2 +0,0 @@ -Optimize asyncio.Future schedule/add/remove callback. The optimization -shows 3-6% performance improvements of async/await code. diff --git a/Misc/NEWS.d/next/Library/2017-12-17-14-23-23.bpo-32351.95fh2K.rst b/Misc/NEWS.d/next/Library/2017-12-17-14-23-23.bpo-32351.95fh2K.rst deleted file mode 100644 index 56f52d2a418..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-17-14-23-23.bpo-32351.95fh2K.rst +++ /dev/null @@ -1 +0,0 @@ -Use fastpath in asyncio.sleep if delay<0 (2x boost) diff --git a/Misc/NEWS.d/next/Library/2017-12-17-21-42-24.bpo-32355.tbaTWA.rst b/Misc/NEWS.d/next/Library/2017-12-17-21-42-24.bpo-32355.tbaTWA.rst deleted file mode 100644 index ca908e97803..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-17-21-42-24.bpo-32355.tbaTWA.rst +++ /dev/null @@ -1 +0,0 @@ -Optimize asyncio.gather(); now up to 15% faster. diff --git a/Misc/NEWS.d/next/Library/2017-12-17-22-50-51.bpo-32356.roZJpA.rst b/Misc/NEWS.d/next/Library/2017-12-17-22-50-51.bpo-32356.roZJpA.rst deleted file mode 100644 index 84b5381fad3..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-17-22-50-51.bpo-32356.roZJpA.rst +++ /dev/null @@ -1,2 +0,0 @@ -asyncio.transport.resume_reading() and pause_reading() are now idempotent. -New transport.is_reading() method is added. diff --git a/Misc/NEWS.d/next/Library/2017-12-18-00-36-41.bpo-32357.t1F3sn.rst b/Misc/NEWS.d/next/Library/2017-12-18-00-36-41.bpo-32357.t1F3sn.rst deleted file mode 100644 index f51eaf541dc..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-18-00-36-41.bpo-32357.t1F3sn.rst +++ /dev/null @@ -1,5 +0,0 @@ -Optimize asyncio.iscoroutine() and loop.create_task() for non-native -coroutines (e.g. async/await compiled with Cython). - -'loop.create_task(python_coroutine)' used to be 20% faster than -'loop.create_task(cython_coroutine)'. Now, the latter is as fast. diff --git a/Misc/NEWS.d/next/Library/2017-12-19-00-37-28.bpo-32363.YTeGU0.rst b/Misc/NEWS.d/next/Library/2017-12-19-00-37-28.bpo-32363.YTeGU0.rst deleted file mode 100644 index 4c376c5ea91..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-19-00-37-28.bpo-32363.YTeGU0.rst +++ /dev/null @@ -1,4 +0,0 @@ -Make asyncio.Task.set_exception() and set_result() raise -NotImplementedError. Task._step() and Future.__await__() raise proper -exceptions when they are in an invalid state, instead of raising an -AssertionError. diff --git a/Misc/NEWS.d/next/Library/2017-12-21-11-08-42.bpo-26133.mt81QV.rst b/Misc/NEWS.d/next/Library/2017-12-21-11-08-42.bpo-26133.mt81QV.rst deleted file mode 100644 index 0653d1960e5..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-21-11-08-42.bpo-26133.mt81QV.rst +++ /dev/null @@ -1 +0,0 @@ -Don't unsubscribe signals in asyncio UNIX event loop on interpreter shutdown. diff --git a/Misc/NEWS.d/next/Library/2017-12-23-12-45-00.bpo-32415.YufXTU.rst b/Misc/NEWS.d/next/Library/2017-12-23-12-45-00.bpo-32415.YufXTU.rst deleted file mode 100644 index f1f57376241..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-23-12-45-00.bpo-32415.YufXTU.rst +++ /dev/null @@ -1 +0,0 @@ -asyncio: Add Task.get_loop() and Future.get_loop() diff --git a/Misc/NEWS.d/next/Library/2017-12-25-11-09-46.bpo-31721.5gM972.rst b/Misc/NEWS.d/next/Library/2017-12-25-11-09-46.bpo-31721.5gM972.rst deleted file mode 100644 index a989a94a7df..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-25-11-09-46.bpo-31721.5gM972.rst +++ /dev/null @@ -1,2 +0,0 @@ -Prevent Python crash from happening when Future._log_traceback is set to -True manually. Now it can only be set to False, or a ValueError is raised. diff --git a/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst b/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst deleted file mode 100644 index 5918c322237..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-25-20-22-47.bpo-32422.5H3Wq2.rst +++ /dev/null @@ -1,2 +0,0 @@ -``functools.lru_cache`` uses less memory (3 words for each cached key) and -takes about 1/3 time for cyclic GC. diff --git a/Misc/NEWS.d/next/Library/2017-12-28-21-30-40.bpo-32441.LqlboJ.rst b/Misc/NEWS.d/next/Library/2017-12-28-21-30-40.bpo-32441.LqlboJ.rst deleted file mode 100644 index a0fe4f3cc6c..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-28-21-30-40.bpo-32441.LqlboJ.rst +++ /dev/null @@ -1,2 +0,0 @@ -Return the new file descriptor (i.e., the second argument) from ``os.dup2``. -Previously, ``None`` was always returned. diff --git a/Misc/NEWS.d/next/Library/2017-12-29-00-44-42.bpo-23749.QL1Cxd.rst b/Misc/NEWS.d/next/Library/2017-12-29-00-44-42.bpo-23749.QL1Cxd.rst deleted file mode 100644 index d6de1fef901..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-29-00-44-42.bpo-23749.QL1Cxd.rst +++ /dev/null @@ -1 +0,0 @@ -asyncio: Implement loop.start_tls() diff --git a/Misc/NEWS.d/next/Library/2017-12-31-20-32-58.bpo-32468.YBs__0.rst b/Misc/NEWS.d/next/Library/2017-12-31-20-32-58.bpo-32468.YBs__0.rst deleted file mode 100644 index 135bbd816e8..00000000000 --- a/Misc/NEWS.d/next/Library/2017-12-31-20-32-58.bpo-32468.YBs__0.rst +++ /dev/null @@ -1 +0,0 @@ -Improve frame repr() to mention filename, code name and current line number. diff --git a/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst b/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst deleted file mode 100644 index bf3e99c8d86..00000000000 --- a/Misc/NEWS.d/next/Library/2018-01-06-10-54-16.bpo-32499.koyY-4.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add dataclasses.is_dataclass(obj), which returns True if obj is a dataclass -or an instance of one. diff --git a/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst b/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst deleted file mode 100644 index c627468072e..00000000000 --- a/Misc/NEWS.d/next/Library/2018-01-06-15-15-34.bpo-32278.bGnGc0.rst +++ /dev/null @@ -1,2 +0,0 @@ -Make type information optional on dataclasses.make_dataclass(). If omitted, -the string 'typing.Any' is used. diff --git a/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst b/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst deleted file mode 100644 index b7ef8c80f5a..00000000000 --- a/Misc/NEWS.d/next/Library/2018-01-06-16-50-11.bpo-32279.1xOpU8.rst +++ /dev/null @@ -1,2 +0,0 @@ -Add params to dataclasses.make_dataclasses(): init, repr, eq, order, hash, -and frozen. Pass them through to dataclass(). diff --git a/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst b/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst deleted file mode 100644 index e524769c6df..00000000000 --- a/Misc/NEWS.d/next/Library/2018-01-07-11-32-42.bpo-32506.MaT-zU.rst +++ /dev/null @@ -1,2 +0,0 @@ -Now that dict is defined as keeping insertion order, drop OrderedDict and -just use plain dict. diff --git a/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst b/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst deleted file mode 100644 index 9cc7ec22c45..00000000000 --- a/Misc/NEWS.d/next/Tests/2017-11-11-16-35-18.bpo-32002.itDxIo.rst +++ /dev/null @@ -1,2 +0,0 @@ -Adjust C locale coercion testing for the empty locale and POSIX locale -cases to more readily adjust to platform dependent behaviour. diff --git a/Misc/NEWS.d/next/Tests/2017-12-11-13-31-33.bpo-32252.YnFw7J.rst b/Misc/NEWS.d/next/Tests/2017-12-11-13-31-33.bpo-32252.YnFw7J.rst deleted file mode 100644 index ee4c56bb73f..00000000000 --- a/Misc/NEWS.d/next/Tests/2017-12-11-13-31-33.bpo-32252.YnFw7J.rst +++ /dev/null @@ -1,2 +0,0 @@ -Fix faulthandler_suppress_crash_report() used to prevent core dump files -when testing crashes. getrlimit() returns zero on success. diff --git a/Misc/NEWS.d/next/Tools-Demos/2017-12-22-09-25-51.bpo-24960.TGdAgO.rst b/Misc/NEWS.d/next/Tools-Demos/2017-12-22-09-25-51.bpo-24960.TGdAgO.rst deleted file mode 100644 index 6f9d83c5772..00000000000 --- a/Misc/NEWS.d/next/Tools-Demos/2017-12-22-09-25-51.bpo-24960.TGdAgO.rst +++ /dev/null @@ -1,3 +0,0 @@ -2to3 and lib2to3 can now read pickled grammar files using pkgutil.get_data() -rather than probing the filesystem. This lets 2to3 and lib2to3 work when run -from a zipfile. diff --git a/Misc/NEWS.d/next/Windows/2017-08-18-18-00-24.bpo-19764.ODpc9y.rst b/Misc/NEWS.d/next/Windows/2017-08-18-18-00-24.bpo-19764.ODpc9y.rst deleted file mode 100644 index b5f5cae8323..00000000000 --- a/Misc/NEWS.d/next/Windows/2017-08-18-18-00-24.bpo-19764.ODpc9y.rst +++ /dev/null @@ -1,2 +0,0 @@ -Implement support for `subprocess.Popen(close_fds=True)` on Windows. Patch -by Segev Finer. From webhook-mailer at python.org Tue Jan 9 10:28:44 2018 From: webhook-mailer at python.org (Ned Deily) Date: Tue, 09 Jan 2018 15:28:44 -0000 Subject: [Python-checkins] Post-release version bump to a4+ Message-ID: https://github.com/python/cpython/commit/2ab3a8fd264f24baf321b861a997bf8848f232d5 commit: 2ab3a8fd264f24baf321b861a997bf8848f232d5 branch: master author: Ned Deily committer: Ned Deily date: 2018-01-09T10:27:57-05:00 summary: Post-release version bump to a4+ files: M Include/patchlevel.h M README.rst diff --git a/Include/patchlevel.h b/Include/patchlevel.h index 49c76757674..cea35de9493 100644 --- a/Include/patchlevel.h +++ b/Include/patchlevel.h @@ -23,7 +23,7 @@ #define PY_RELEASE_SERIAL 4 /* Version as a string */ -#define PY_VERSION "3.7.0a4" +#define PY_VERSION "3.7.0a4+" /*--end constants--*/ /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. diff --git a/README.rst b/README.rst index 41f809b641f..b6d744d19eb 100644 --- a/README.rst +++ b/README.rst @@ -1,5 +1,5 @@ -This is Python version 3.7.0 alpha 4 -==================================== +This is Python version 3.7.0 alpha 4+ +===================================== .. image:: https://travis-ci.org/python/cpython.svg?branch=master :alt: CPython build status on Travis CI From webhook-mailer at python.org Tue Jan 9 14:38:10 2018 From: webhook-mailer at python.org (Antoine Pitrou) Date: Tue, 09 Jan 2018 19:38:10 -0000 Subject: [Python-checkins] bpo-32493: Not only AIX, but FreeBSD has uuid_create support (#5089) Message-ID: https://github.com/python/cpython/commit/b4ebaa7099c3413b42a97777581c4ca560fe7540 commit: b4ebaa7099c3413b42a97777581c4ca560fe7540 branch: master author: David Carlier committer: Antoine Pitrou date: 2018-01-09T20:38:07+01:00 summary: bpo-32493: Not only AIX, but FreeBSD has uuid_create support (#5089) Allow building the _uuid extension module on FreeBSD and OpenBSD. files: A Misc/NEWS.d/next/Library/2018-01-08-15-53-37.bpo-32493.vTXxGN.rst M Modules/_uuidmodule.c M configure M configure.ac M pyconfig.h.in diff --git a/Misc/NEWS.d/next/Library/2018-01-08-15-53-37.bpo-32493.vTXxGN.rst b/Misc/NEWS.d/next/Library/2018-01-08-15-53-37.bpo-32493.vTXxGN.rst new file mode 100644 index 00000000000..82d33aa55b7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-01-08-15-53-37.bpo-32493.vTXxGN.rst @@ -0,0 +1 @@ +UUID module fixes build for FreeBSD/OpenBSD diff --git a/Modules/_uuidmodule.c b/Modules/_uuidmodule.c index 1b37511c228..16aa09b04ff 100644 --- a/Modules/_uuidmodule.c +++ b/Modules/_uuidmodule.c @@ -19,10 +19,7 @@ py_uuid_generate_time_safe(void) res = uuid_generate_time_safe(uuid); return Py_BuildValue("y#i", (const char *) uuid, sizeof(uuid), res); #elif HAVE_UUID_CREATE -/* - * AIX support for uuid - RFC4122 - */ - unsigned32 status; + uint32_t status; uuid_create(&uuid, &status); return Py_BuildValue("y#i", (const char *) &uuid, sizeof(uuid), (int) status); #else diff --git a/configure b/configure index afffc190751..9286443124a 100755 --- a/configure +++ b/configure @@ -9560,8 +9560,9 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 (anno 2007) -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RFC4122 - uuid support on AIX" >&5 -$as_echo_n "checking for RFC4122 - uuid support on AIX... " >&6; } +# FreeBSD and OpenBSD provides support as well +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_create" >&5 +$as_echo_n "checking for uuid_create... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include diff --git a/configure.ac b/configure.ac index 0a48e41d5c3..1894e21f304 100644 --- a/configure.ac +++ b/configure.ac @@ -2696,13 +2696,14 @@ void *x = uuid_generate_time_safe ) # AIX provides support for RFC4122 (uuid) in libc.a starting with AIX 6.1 (anno 2007) -AC_MSG_CHECKING(for RFC4122 - uuid support on AIX) +# FreeBSD and OpenBSD provides support as well +AC_MSG_CHECKING(for uuid_create) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ #ifndef uuid_create void *x = uuid_create #endif ]])], - [AC_DEFINE(HAVE_UUID_CREATE, 1, Define if uuid_create() exists. AIX support for uuid:RFC4122) + [AC_DEFINE(HAVE_UUID_CREATE, 1, Define if uuid_create() exists.) AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)] ) diff --git a/pyconfig.h.in b/pyconfig.h.in index 7d366562b0c..ff1083ae0b0 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1191,7 +1191,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UTIME_H -/* Define if uuid_create() exists. AIX support for uuid:RFC4122 */ +/* Define if uuid_create() exists. */ #undef HAVE_UUID_CREATE /* Define if uuid_generate_time_safe() exists. */ From webhook-mailer at python.org Tue Jan 9 14:54:56 2018 From: webhook-mailer at python.org (Serhiy Storchaka) Date: Tue, 09 Jan 2018 19:54:56 -0000 Subject: [Python-checkins] bpo-24340: Fix estimation of the code stack size. (#5076) Message-ID: https://github.com/python/cpython/commit/d4864c61e3e27e337762dc45e504977299bd5b46 commit: d4864c61e3e27e337762dc45e504977299bd5b46 branch: master author: Serhiy Storchaka committer: GitHub date: 2018-01-09T21:54:52+02:00 summary: bpo-24340: Fix estimation of the code stack size. (#5076) files: A Misc/NEWS.d/next/Core and Builtins/2018-01-01-21-59-31.bpo-24340.hmKBvg.rst M Lib/test/test_compile.py M Lib/test/test_dis.py M Python/compile.c M Python/importlib.h M Python/importlib_external.h diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index ae3043af0bd..29aa362590f 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -672,7 +672,7 @@ def __fspath__(self): compile("42", PathLike("test_compile_pathlike"), "single") -class TestStackSize(unittest.TestCase): +class TestExpressionStackSize(unittest.TestCase): # These tests check that the computed stack size for a code object # stays within reasonable bounds (see issue #21523 for an example # dysfunction). @@ -710,5 +710,294 @@ def test_func_and(self): self.check_stack_size(code) +class TestStackSizeStability(unittest.TestCase): + # Check that repeating certain snippets doesn't increase the stack size + # beyond what a single snippet requires. + + def check_stack_size(self, snippet, async_=False): + def compile_snippet(i): + ns = {} + script = """def func():\n""" + i * snippet + if async_: + script = "async " + script + code = compile(script, "