diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-03-21 15:39:27 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-21 16:39:27 +0100 |
commit | d0d367369ec91450724ada8c90f1f41605d674ba (patch) | |
tree | 2b0d1dfa367780b391c7f84ef6e7e3d224b840b8 | |
parent | eab4e09a7034ea93f437e6de34bf411143d91c77 (diff) | |
download | cython-d0d367369ec91450724ada8c90f1f41605d674ba.tar.gz |
Only use PyUnicode_Concat on unicode object operations (GH-3433)
-rw-r--r-- | Cython/Compiler/ExprNodes.py | 27 | ||||
-rw-r--r-- | tests/run/test_unicode_string_tests.pxi | 8 |
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 |