diff options
author | da-woods <dw-git@d-woods.co.uk> | 2022-07-16 09:25:26 +0100 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2022-07-16 10:26:15 +0200 |
commit | 2f1c338ac4e7333823be84cc0d8df80acc5e23f3 (patch) | |
tree | bd6a11a13b4cba06133f09267a561ae0a949f65c | |
parent | e4ef0c1e807aab8c20fb08b638550c912c166be3 (diff) | |
download | cython-2f1c338ac4e7333823be84cc0d8df80acc5e23f3.tar.gz |
Fixed over-zealous optimization of append attribute usage to "__Pyx_PyObject_Append" (GH-4834)
Fixes https://github.com/cython/cython/issues/4828
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 2 | ||||
-rw-r--r-- | Cython/Compiler/Optimize.py | 2 | ||||
-rw-r--r-- | tests/run/append.pyx | 34 |
3 files changed, 36 insertions, 2 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 69632a4fe..2c5d70936 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -306,8 +306,8 @@ class ExprNode(Node): # Cached result of subexpr_nodes() # use_managed_ref boolean use ref-counted temps/assignments/etc. # result_is_used boolean indicates that the result will be dropped and the - # is_numpy_attribute boolean Is a Numpy module attribute # result_code/temp_result can safely be set to None + # is_numpy_attribute boolean Is a Numpy module attribute # annotation ExprNode or None PEP526 annotation for names or expressions result_ctype = None diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 3cb77efe2..7e9435ba0 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -2860,7 +2860,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, """Optimistic optimisation as X.append() is almost always referring to a list. """ - if len(args) != 2 or node.result_is_used: + if len(args) != 2 or node.result_is_used or node.function.entry: return node return ExprNodes.PythonCapiCallNode( diff --git a/tests/run/append.pyx b/tests/run/append.pyx index 1976780d5..dcc3fe7c9 100644 --- a/tests/run/append.pyx +++ b/tests/run/append.pyx @@ -1,3 +1,5 @@ +cimport cython + class A: def append(self, x): print u"appending", x @@ -94,3 +96,35 @@ def method_name(): 'append' """ return [].append.__name__ + +@cython.test_assert_path_exists( + '//PythonCapiCallNode') +def append_optimized(probably_list): + """ + >>> l = [] + >>> append_optimized(l) + >>> l + [1] + """ + probably_list.append(1) + +cdef class AppendBug: + # https://github.com/cython/cython/issues/4828 + # if the attribute "append" is found it shouldn't be replaced with + # __Pyx_PyObject_Append + cdef object append + def __init__(self, append): + self.append = append + +@cython.test_fail_if_path_exists( + '//PythonCapiCallNode') +def specific_attribute(AppendBug a): + """ + >>> def append_to_default_arg(a, arg=[]): + ... arg.append(a) + ... return arg + >>> specific_attribute(AppendBug(append_to_default_arg)) + >>> append_to_default_arg(None) + [1, None] + """ + a.append(1) |