Skip to content

Commit 8d52d9d

Browse files
committed
[GR-11977] center, rjust and ljust methods are not implemented for str.
1 parent 99cfb32 commit 8d52d9d

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_string.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,38 @@ def test_title_uni(self):
742742
self.assertEqual('fifiNNfiISH'.title(), 'Fifinnfiish')
743743
self.assertEqual('A\u03a3A'.title(), 'A\u03c3a')
744744

745+
def test_ljust(self):
746+
self.checkequal('abc ', 'abc', 'ljust', 10)
747+
self.checkequal('abc ', 'abc', 'ljust', 6)
748+
self.checkequal('abc', 'abc', 'ljust', 3)
749+
self.checkequal('abc', 'abc', 'ljust', 2)
750+
self.checkequal('abc*******', 'abc', 'ljust', 10, '*')
751+
self.checkraises(TypeError, 'abc', 'ljust')
752+
753+
def test_rjust(self):
754+
self.checkequal(' abc', 'abc', 'rjust', 10)
755+
self.checkequal(' abc', 'abc', 'rjust', 6)
756+
self.checkequal('abc', 'abc', 'rjust', 3)
757+
self.checkequal('abc', 'abc', 'rjust', 2)
758+
self.checkequal('*******abc', 'abc', 'rjust', 10, '*')
759+
self.checkraises(TypeError, 'abc', 'rjust')
760+
761+
def test_center(self):
762+
self.checkequal(' abc ', 'abc', 'center', 10)
763+
self.checkequal(' abc ', 'abc', 'center', 6)
764+
self.checkequal('abc', 'abc', 'center', 3)
765+
self.checkequal('abc', 'abc', 'center', 2)
766+
self.checkequal('***abc****', 'abc', 'center', 10, '*')
767+
self.checkraises(TypeError, 'abc', 'center')
768+
769+
def test_center_uni(self):
770+
self.assertEqual('x'.center(2, '\U0010FFFF'),
771+
'x\U0010FFFF')
772+
self.assertEqual('x'.center(3, '\U0010FFFF'),
773+
'\U0010FFFFx\U0010FFFF')
774+
self.assertEqual('x'.center(4, '\U0010FFFF'),
775+
'\U0010FFFFx\U0010FFFF\U0010FFFF')
776+
745777
def test_same_id():
746778
empty_ids = set([id(str()) for i in range(100)])
747779
assert len(empty_ids) == 1

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

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,113 @@ public String doTitle(String self) {
16641664
}
16651665
}
16661666

1667+
@Builtin(name = "center", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
1668+
@GenerateNodeFactory
1669+
@TypeSystemReference(PythonArithmeticTypes.class)
1670+
abstract static class CenterNode extends PythonBuiltinNode {
1671+
1672+
protected CastToIndexNode toIndexNode;
1673+
1674+
private CastToIndexNode getCastToIndexNode() {
1675+
if (toIndexNode == null) {
1676+
toIndexNode = CastToIndexNode.createOverflow();
1677+
}
1678+
return toIndexNode;
1679+
}
1680+
1681+
@Specialization
1682+
public String createDefault(String self, long width, @SuppressWarnings("unused") PNone fill) {
1683+
return make(self, getCastToIndexNode().execute(width), " ");
1684+
}
1685+
1686+
@Specialization(guards = "fill.codePointCount(0, fill.length()) == 1")
1687+
public String create(String self, long width, String fill) {
1688+
return make(self, getCastToIndexNode().execute(width), fill);
1689+
}
1690+
1691+
@Specialization(guards = "fill.codePointCount(0, fill.length()) != 1")
1692+
public String createError(String self, long width, String fill) {
1693+
throw raise(TypeError, "The fill character must be exactly one character long");
1694+
}
1695+
1696+
@Specialization
1697+
public String createDefault(String self, PInt width, @SuppressWarnings("unused") PNone fill) {
1698+
return make(self, getCastToIndexNode().execute(width), " ");
1699+
}
1700+
1701+
@Specialization(guards = "fill.codePointCount(0, fill.length()) == 1")
1702+
public String create(String self, PInt width, String fill) {
1703+
return make(self, getCastToIndexNode().execute(width), fill);
1704+
}
1705+
1706+
@Specialization(guards = "fill.codePointCount(0, fill.length()) != 1")
1707+
public String createError(String self, PInt width, String fill) {
1708+
throw raise(TypeError, "The fill character must be exactly one character long");
1709+
}
1710+
1711+
protected String make(String self, int width, String fill) {
1712+
int fillChar = parseCodePoint(fill);
1713+
int len = width - self.length();
1714+
if (len <= 0) {
1715+
return self;
1716+
}
1717+
int half = len / 2;
1718+
if (len % 2 > 0 && width % 2 > 0) {
1719+
half += 1;
1720+
}
1721+
1722+
return padding(half, fillChar) + self + padding(len - half, fillChar);
1723+
}
1724+
1725+
protected static String padding(int len, int codePoint) {
1726+
int[] result = new int[len];
1727+
for (int i = 0; i < len; i++) {
1728+
result[i] = codePoint;
1729+
}
1730+
return new String(result, 0, len);
1731+
}
1732+
1733+
@TruffleBoundary
1734+
protected static int parseCodePoint(String fillchar) {
1735+
if (fillchar == null) {
1736+
return ' ';
1737+
}
1738+
return fillchar.codePointAt(0);
1739+
}
1740+
}
1741+
1742+
@Builtin(name = "ljust", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
1743+
@GenerateNodeFactory
1744+
abstract static class LJustNode extends CenterNode {
1745+
1746+
@Override
1747+
protected String make(String self, int width, String fill) {
1748+
int fillChar = parseCodePoint(fill);
1749+
int len = width - self.length();
1750+
if (len <= 0) {
1751+
return self;
1752+
}
1753+
return self + padding(len, fillChar);
1754+
}
1755+
1756+
}
1757+
1758+
@Builtin(name = "rjust", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 3)
1759+
@GenerateNodeFactory
1760+
abstract static class RJustNode extends CenterNode {
1761+
1762+
@Override
1763+
protected String make(String self, int width, String fill) {
1764+
int fillChar = parseCodePoint(fill);
1765+
int len = width - self.length();
1766+
if (len <= 0) {
1767+
return self;
1768+
}
1769+
return padding(len, fillChar) + self;
1770+
}
1771+
1772+
}
1773+
16671774
@Builtin(name = __GETITEM__, fixedNumOfPositionalArgs = 2)
16681775
@GenerateNodeFactory
16691776
@TypeSystemReference(PythonArithmeticTypes.class)

0 commit comments

Comments
 (0)