summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorda-woods <dw-git@d-woods.co.uk>2020-03-21 15:39:27 +0000
committerGitHub <noreply@github.com>2020-03-21 16:39:27 +0100
commitd0d367369ec91450724ada8c90f1f41605d674ba (patch)
tree2b0d1dfa367780b391c7f84ef6e7e3d224b840b8
parenteab4e09a7034ea93f437e6de34bf411143d91c77 (diff)
downloadcython-d0d367369ec91450724ada8c90f1f41605d674ba.tar.gz
Only use PyUnicode_Concat on unicode object operations (GH-3433)
-rw-r--r--Cython/Compiler/ExprNodes.py27
-rw-r--r--tests/run/test_unicode_string_tests.pxi8
2 files changed, 24 insertions, 11 deletions
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index 1915369df..d9ad15808 100644
--- a/Cython/Compiler/ExprNodes.py
+++ b/Cython/Compiler/ExprNodes.py
@@ -11364,19 +11364,24 @@ class AddNode(NumBinopNode):
self, type1, type2)
def py_operation_function(self, code):
- is_unicode_concat = False
- if isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
- is_unicode_concat = True
- else:
- type1, type2 = self.operand1.type, self.operand2.type
- if type1 is unicode_type or type2 is unicode_type:
- is_unicode_concat = type1.is_builtin_type and type2.is_builtin_type
+ type1, type2 = self.operand1.type, self.operand2.type
- if is_unicode_concat:
- if self.operand1.may_be_none() or self.operand2.may_be_none():
- return '__Pyx_PyUnicode_ConcatSafe'
+ if type1 is unicode_type or type2 is unicode_type:
+ if type1 in (unicode_type, str_type) and type2 in (unicode_type, str_type):
+ is_unicode_concat = True
+ elif isinstance(self.operand1, FormattedValueNode) or isinstance(self.operand2, FormattedValueNode):
+ # Assume that even if we don't know the second type, it's going to be a string.
+ is_unicode_concat = True
else:
- return '__Pyx_PyUnicode_Concat'
+ # Operation depends on the second type.
+ is_unicode_concat = False
+
+ if is_unicode_concat:
+ if self.operand1.may_be_none() or self.operand2.may_be_none():
+ return '__Pyx_PyUnicode_ConcatSafe'
+ else:
+ return '__Pyx_PyUnicode_Concat'
+
return super(AddNode, self).py_operation_function(code)
diff --git a/tests/run/test_unicode_string_tests.pxi b/tests/run/test_unicode_string_tests.pxi
index 61cc6f2ac..b8fb171da 100644
--- a/tests/run/test_unicode_string_tests.pxi
+++ b/tests/run/test_unicode_string_tests.pxi
@@ -993,6 +993,14 @@ class CommonTest(BaseTest):
self.checkequal('\u019b\u1d00\u1d86\u0221\u1fb7',
'\u019b\u1d00\u1d86\u0221\u1fb7', 'capitalize')
+ def test_list_concat(self):
+ # https://github.com/cython/cython/issues/3426
+ y = []
+ y += 'ab'
+ self.assertEqual('a', y[0])
+ self.assertEqual('b', y[1])
+ self.assertEqual(['a', 'b'], y)
+
class MixinStrUnicodeUserStringTest:
# additional tests that only work for