Skip to content

Commit db4f133

Browse files
committed
Fix str.capitalize
1 parent e995be2 commit db4f133

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_unicode.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_additional_split
1313
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_ascii
1414
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_bytes_comparison
15+
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_capitalize
16+
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_capitalize_nonascii
1517
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_case_operation_overflow
1618
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_center
1719
*graalpython.lib-python.3.test.test_unicode.UnicodeTest.test_codecs

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565

6666
import com.ibm.icu.lang.UCharacter;
6767
import com.ibm.icu.lang.UProperty;
68+
import com.ibm.icu.text.CaseMap;
6869
import com.oracle.graal.python.PythonLanguage;
6970
import com.oracle.graal.python.annotations.ArgumentClinic;
7071
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
@@ -136,6 +137,7 @@
136137
import com.oracle.graal.python.util.PythonUtils;
137138
import com.oracle.truffle.api.CompilerAsserts;
138139
import com.oracle.truffle.api.CompilerDirectives;
140+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
139141
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
140142
import com.oracle.truffle.api.dsl.Cached;
141143
import com.oracle.truffle.api.dsl.Cached.Exclusive;
@@ -920,19 +922,34 @@ static String doGeneric(Object self,
920922
@GenerateNodeFactory
921923
public abstract static class CapitalizeNode extends PythonUnaryBuiltinNode {
922924

925+
@CompilationFinal private static CaseMap.Title titlecaser;
926+
927+
@Specialization
928+
static String capitalize(String self) {
929+
if (self.isEmpty()) {
930+
return "";
931+
} else {
932+
return capitalizeImpl(self);
933+
}
934+
}
935+
923936
@Specialization
924937
static String doGeneric(Object self,
925938
@Cached CastToJavaStringCheckedNode castToJavaStringNode) {
926939
return capitalize(castToJavaStringNode.cast(self, ErrorMessages.REQUIRES_STR_OBJECT_BUT_RECEIVED_P, "capitalize", self));
927940
}
928941

929-
@TruffleBoundary
930-
private static String capitalize(String self) {
931-
if (self.isEmpty()) {
932-
return "";
933-
} else {
934-
return self.substring(0, 1).toUpperCase() + self.substring(1).toLowerCase();
942+
private static String capitalizeImpl(String str) {
943+
if (titlecaser == null) {
944+
CompilerDirectives.transferToInterpreterAndInvalidate();
945+
titlecaser = CaseMap.toTitle().wholeString().noBreakAdjustment();
935946
}
947+
return apply(str);
948+
}
949+
950+
@TruffleBoundary
951+
private static String apply(String str) {
952+
return titlecaser.apply(Locale.ROOT, null, str);
936953
}
937954
}
938955

0 commit comments

Comments
 (0)