Skip to content

Commit 426ba01

Browse files
committed
[GR-11836] Implementation of str.zfill is missing.
PullRequest: graalpython/203
2 parents a377c3f + 2fd43d8 commit 426ba01

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,8 @@ class subtype(self.__class__.type2test):
475475
else:
476476
obj = subtype(obj)
477477
realresult = getattr(obj, methodname)(*args)
478-
self.assertIsNot(obj, realresult)
478+
self.assertTrue(obj is not realresult)
479+
#self.assertIsNot(obj, realresult)
479480

480481
# check that obj.method(*args) raises exc
481482
def checkraises(self, exc, obj, methodname, *args):
@@ -688,6 +689,32 @@ def test_isprintable(self):
688689
self.assertTrue('\U0001F46F'.isprintable())
689690
# self.assertFalse('\U000E0020'.isprintable())
690691

692+
def test_zfill(self):
693+
self.checkequal('123', '123', 'zfill', 2)
694+
self.checkequal('123', '123', 'zfill', 3)
695+
self.checkequal('0123', '123', 'zfill', 4)
696+
self.checkequal('+123', '+123', 'zfill', 3)
697+
self.checkequal('+123', '+123', 'zfill', 4)
698+
self.checkequal('+0123', '+123', 'zfill', 5)
699+
self.checkequal('-123', '-123', 'zfill', 3)
700+
self.checkequal('-123', '-123', 'zfill', 4)
701+
self.checkequal('-0123', '-123', 'zfill', 5)
702+
self.checkequal('000', '', 'zfill', 3)
703+
self.checkequal('34', '34', 'zfill', 1)
704+
self.checkequal('0034', '34', 'zfill', 4)
705+
706+
self.checkraises(TypeError, '123', 'zfill')
707+
708+
def test_zfill_specialization(self):
709+
self.checkequal('123', '123', 'zfill', True)
710+
711+
class MyIndexable(object):
712+
def __init__(self, value):
713+
self.value = value
714+
def __index__(self):
715+
return self.value
716+
717+
self.checkequal('0123', '123', 'zfill', MyIndexable(4))
691718

692719
def test_same_id():
693720
empty_ids = set([id(str()) for i in range(100)])

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@
8686
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
8787
import com.oracle.graal.python.nodes.object.GetClassNode;
8888
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
89+
import com.oracle.graal.python.nodes.util.CastToIndexNode;
90+
import com.oracle.graal.python.nodes.util.CastToIntegerFromIndexNode;
8991
import com.oracle.graal.python.runtime.exception.PException;
9092
import com.oracle.graal.python.runtime.formatting.StringFormatter;
9193
import com.oracle.truffle.api.CompilerDirectives;
@@ -1543,6 +1545,61 @@ boolean doString(String self) {
15431545
}
15441546
}
15451547

1548+
@Builtin(name = "zfill", fixedNumOfPositionalArgs = 2)
1549+
@GenerateNodeFactory
1550+
@TypeSystemReference(PythonArithmeticTypes.class)
1551+
abstract static class ZFillNode extends PythonBinaryBuiltinNode {
1552+
1553+
public abstract String executeObject(String self, Object x);
1554+
1555+
@Specialization
1556+
public String doString(String self, long width) {
1557+
return zfill(self, (int) width);
1558+
}
1559+
1560+
@Specialization
1561+
public String doString(String self, PInt width,
1562+
@Cached("create()") CastToIndexNode toIndexNode) {
1563+
return zfill(self, toIndexNode.execute(width));
1564+
}
1565+
1566+
@Specialization
1567+
public String doString(String self, Object width,
1568+
@Cached("create()") CastToIntegerFromIndexNode widthCast,
1569+
@Cached("create()") ZFillNode recursiveNode) {
1570+
return recursiveNode.executeObject(self, widthCast.execute(width));
1571+
}
1572+
1573+
private static String zfill(String self, int width) {
1574+
int len = self.length();
1575+
if (len >= width) {
1576+
return self;
1577+
}
1578+
char[] chars = new char[width];
1579+
int nzeros = width - len;
1580+
int i = 0;
1581+
int sStart = 0;
1582+
if (len > 0) {
1583+
char start = self.charAt(0);
1584+
if (start == '+' || start == '-') {
1585+
chars[0] = start;
1586+
i += 1;
1587+
nzeros++;
1588+
sStart = 1;
1589+
}
1590+
}
1591+
for (; i < nzeros; i++) {
1592+
chars[i] = '0';
1593+
}
1594+
self.getChars(sStart, len, chars, i);
1595+
return new String(chars);
1596+
}
1597+
1598+
public static ZFillNode create() {
1599+
return StringBuiltinsFactory.ZFillNodeFactory.create();
1600+
}
1601+
}
1602+
15461603
@Builtin(name = __GETITEM__, fixedNumOfPositionalArgs = 2)
15471604
@GenerateNodeFactory
15481605
@TypeSystemReference(PythonArithmeticTypes.class)

0 commit comments

Comments
 (0)