diff options
author | da-woods <dw-git@d-woods.co.uk> | 2020-03-21 15:39:27 +0000 |
---|---|---|
committer | Stefan Behnel <stefan_ml@behnel.de> | 2020-03-21 16:42:23 +0100 |
commit | 6642d167837ebf03f31cd4298f3850b851441902 (patch) | |
tree | a0efe79bfa0995fa1cecf9c564901e45ccc2ad9d | |
parent | 033e68643732fc550b82f03f58a2c84204cd2ea3 (diff) | |
download | cython-6642d167837ebf03f31cd4298f3850b851441902.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 179132bfe..19e7d733a 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -11390,19 +11390,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 |