From b121a4a45ff4bab8812a9b26ceffe5ad642f5d5a Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sun, 5 Jan 2020 12:03:56 -0500 Subject: [PATCH] Fix constant folding optimization for positional only arguments (GH-17837) --- Lib/test/test_positional_only_arg.py | 12 ++++++++++++ .../2020-01-05-06-55-52.bpo-39216.74jLh9.rst | 2 ++ Python/ast_opt.c | 1 + 3 files changed, 15 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9.rst diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index 63dee7ca434..2ef40e3a5a1 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -1,5 +1,6 @@ """Unit tests for the positional only argument syntax specified in PEP 570.""" +import dis import pickle import unittest @@ -419,6 +420,17 @@ class PositionalOnlyTestCase(unittest.TestCase): def test_annotations(self): assert global_inner_has_pos_only().__annotations__ == {'x': int} + def test_annotations_constant_fold(self): + def g(): + def f(x: not (int is int), /): ... + + # without constant folding we end up with + # COMPARE_OP(is), UNARY_NOT + # with constant folding we should expect a COMPARE_OP(is not) + codes = [(i.opname, i.argval) for i in dis.get_instructions(g)] + self.assertNotIn(('UNARY_NOT', None), codes) + self.assertIn(('COMPARE_OP', 'is not'), codes) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9.rst b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9.rst new file mode 100644 index 00000000000..971b0655297 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-01-05-06-55-52.bpo-39216.74jLh9.rst @@ -0,0 +1,2 @@ +Fix constant folding optimization for positional only arguments - by Anthony +Sottile. diff --git a/Python/ast_opt.c b/Python/ast_opt.c index 96c766fc095..f2a2c259149 100644 --- a/Python/ast_opt.c +++ b/Python/ast_opt.c @@ -617,6 +617,7 @@ astfold_comprehension(comprehension_ty node_, PyArena *ctx_, int optimize_) static int astfold_arguments(arguments_ty node_, PyArena *ctx_, int optimize_) { + CALL_SEQ(astfold_arg, arg_ty, node_->posonlyargs); CALL_SEQ(astfold_arg, arg_ty, node_->args); CALL_OPT(astfold_arg, arg_ty, node_->vararg); CALL_SEQ(astfold_arg, arg_ty, node_->kwonlyargs);