Skip to content

Commit b76b045

Browse files
committed
[GR-13171] rstrip and lstrip is missing for PBytes.
PullRequest: graalpython/337
2 parents 07e2049 + f8eba82 commit b76b045

File tree

5 files changed

+185
-132
lines changed

5 files changed

+185
-132
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,3 +529,8 @@ def test_strip_bytearray():
529529
assert bytearray(b'abc').strip(b'ac') == b'b'
530530
assert bytearray(b'abc').lstrip(b'ac') == b'bc'
531531
assert bytearray(b'abc').rstrip(b'ac') == b'ab'
532+
533+
def test_strip_bytes():
534+
assert b'abc'.strip(b'ac') == b'b'
535+
assert b'abc'.lstrip(b'ac') == b'bc'
536+
assert b'abc'.rstrip(b'ac') == b'ab'

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/AbstractBytesBuiltins.java

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@
4545
import com.oracle.graal.python.builtins.CoreFunctions;
4646
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4747
import com.oracle.graal.python.builtins.PythonBuiltins;
48+
import com.oracle.graal.python.builtins.objects.PNone;
4849
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
50+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
4951
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
5052
import com.oracle.truffle.api.CompilerDirectives;
53+
import com.oracle.truffle.api.dsl.Cached;
5154
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
5255
import com.oracle.truffle.api.dsl.NodeFactory;
5356
import com.oracle.truffle.api.dsl.Specialization;
@@ -116,4 +119,175 @@ PBytes replace(PBytes self) {
116119
return factory().createBytes(upper(toBytes.execute(self)));
117120
}
118121
}
122+
123+
abstract static class AStripNode extends PythonBinaryBuiltinNode {
124+
int mod() {
125+
throw new RuntimeException();
126+
}
127+
128+
int stop(@SuppressWarnings("unused") byte[] bs) {
129+
throw new RuntimeException();
130+
}
131+
132+
int start(@SuppressWarnings("unused") byte[] bs) {
133+
throw new RuntimeException();
134+
}
135+
136+
PByteArray newByteArrayFrom(@SuppressWarnings("unused") byte[] bs, @SuppressWarnings("unused") int i) {
137+
throw new RuntimeException();
138+
}
139+
140+
PBytes newBytesFrom(@SuppressWarnings("unused") byte[] bs, @SuppressWarnings("unused") int i) {
141+
throw new RuntimeException();
142+
}
143+
144+
private int findIndex(byte[] bs) {
145+
int i = start(bs);
146+
int stop = stop(bs);
147+
for (; i != stop; i += mod()) {
148+
if (!isWhitespace(bs[i])) {
149+
break;
150+
}
151+
}
152+
return i;
153+
}
154+
155+
@Specialization
156+
PByteArray strip(PByteArray self, @SuppressWarnings("unused") PNone bytes,
157+
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
158+
byte[] bs = toBytesNode.execute(self);
159+
return newByteArrayFrom(bs, findIndex(bs));
160+
}
161+
162+
@Specialization
163+
PBytes strip(PBytes self, @SuppressWarnings("unused") PNone bytes,
164+
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
165+
byte[] bs = toBytesNode.execute(self);
166+
return newBytesFrom(bs, findIndex(bs));
167+
}
168+
169+
@CompilerDirectives.TruffleBoundary
170+
private static boolean isWhitespace(byte b) {
171+
return Character.isWhitespace(b);
172+
}
173+
174+
private int findIndex(byte[] bs, byte[] stripBs) {
175+
int i = start(bs);
176+
int stop = stop(bs);
177+
outer: for (; i != stop; i += mod()) {
178+
for (byte b : stripBs) {
179+
if (b == bs[i]) {
180+
continue outer;
181+
}
182+
}
183+
break;
184+
}
185+
return i;
186+
}
187+
188+
@Specialization
189+
PByteArray strip(PByteArray self, PBytes bytes,
190+
@Cached("create()") BytesNodes.ToBytesNode selfToBytesNode,
191+
@Cached("create()") BytesNodes.ToBytesNode otherToBytesNode) {
192+
byte[] stripBs = selfToBytesNode.execute(bytes);
193+
byte[] bs = otherToBytesNode.execute(self);
194+
return newByteArrayFrom(bs, findIndex(bs, stripBs));
195+
}
196+
197+
@Specialization
198+
PBytes strip(PBytes self, PBytes bytes,
199+
@Cached("create()") BytesNodes.ToBytesNode selfToBytesNode,
200+
@Cached("create()") BytesNodes.ToBytesNode otherToBytesNode) {
201+
byte[] stripBs = selfToBytesNode.execute(bytes);
202+
byte[] bs = otherToBytesNode.execute(self);
203+
return newBytesFrom(bs, findIndex(bs, stripBs));
204+
}
205+
206+
}
207+
208+
@Builtin(name = "lstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
209+
@GenerateNodeFactory
210+
abstract static class LStripNode extends AStripNode {
211+
212+
private static byte[] getResultBytes(int i, byte[] bs) {
213+
byte[] out;
214+
if (i != 0) {
215+
int len = bs.length - i;
216+
out = new byte[len];
217+
System.arraycopy(bs, i, out, 0, len);
218+
} else {
219+
out = bs;
220+
}
221+
return out;
222+
}
223+
224+
@Override
225+
PByteArray newByteArrayFrom(byte[] bs, int i) {
226+
return factory().createByteArray(getResultBytes(i, bs));
227+
}
228+
229+
@Override
230+
PBytes newBytesFrom(byte[] bs, int i) {
231+
return factory().createBytes(getResultBytes(i, bs));
232+
}
233+
234+
@Override
235+
int mod() {
236+
return 1;
237+
}
238+
239+
@Override
240+
int stop(byte[] bs) {
241+
return bs.length;
242+
}
243+
244+
@Override
245+
int start(byte[] bs) {
246+
return 0;
247+
}
248+
}
249+
250+
@Builtin(name = "rstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
251+
@GenerateNodeFactory
252+
abstract static class RStripNode extends AStripNode {
253+
254+
private static byte[] getResultBytes(int i, byte[] bs) {
255+
byte[] out;
256+
int len = i + 1;
257+
if (len != bs.length) {
258+
out = new byte[len];
259+
System.arraycopy(bs, 0, out, 0, len);
260+
} else {
261+
out = bs;
262+
}
263+
return out;
264+
}
265+
266+
@Override
267+
PByteArray newByteArrayFrom(byte[] bs, int i) {
268+
byte[] out = getResultBytes(i, bs);
269+
return factory().createByteArray(out);
270+
}
271+
272+
@Override
273+
PBytes newBytesFrom(byte[] bs, int i) {
274+
byte[] out = getResultBytes(i, bs);
275+
return factory().createBytes(out);
276+
}
277+
278+
@Override
279+
int mod() {
280+
return -1;
281+
}
282+
283+
@Override
284+
int stop(byte[] bs) {
285+
return -1;
286+
}
287+
288+
@Override
289+
int start(byte[] bs) {
290+
return bs.length - 1;
291+
}
292+
}
119293
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java

Lines changed: 0 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
import com.oracle.graal.python.runtime.sequence.storage.IntSequenceStorage;
8080
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
8181
import com.oracle.truffle.api.CompilerDirectives;
82-
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
8382
import com.oracle.truffle.api.dsl.Cached;
8483
import com.oracle.truffle.api.dsl.Fallback;
8584
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -730,124 +729,4 @@ Object doGeneric(@SuppressWarnings("unused") Object self) {
730729
}
731730
}
732731

733-
abstract static class AStripNode extends PythonBinaryBuiltinNode {
734-
int mod() {
735-
throw new RuntimeException();
736-
}
737-
738-
int stop(@SuppressWarnings("unused") byte[] bs) {
739-
throw new RuntimeException();
740-
}
741-
742-
int start(@SuppressWarnings("unused") byte[] bs) {
743-
throw new RuntimeException();
744-
}
745-
746-
PByteArray newBytesFrom(@SuppressWarnings("unused") byte[] bs, @SuppressWarnings("unused") int i) {
747-
throw new RuntimeException();
748-
}
749-
750-
@Specialization
751-
PByteArray strip(PByteArray self, @SuppressWarnings("unused") PNone bytes,
752-
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
753-
byte[] bs = toBytesNode.execute(self);
754-
int i = start(bs);
755-
int stop = stop(bs);
756-
for (; i != stop; i += mod()) {
757-
if (!isWhitespace(bs[i])) {
758-
break;
759-
}
760-
}
761-
return newBytesFrom(bs, i);
762-
}
763-
764-
@TruffleBoundary
765-
private static boolean isWhitespace(byte b) {
766-
return Character.isWhitespace(b);
767-
}
768-
769-
@Specialization
770-
PByteArray strip(PByteArray self, PBytes bytes,
771-
@Cached("create()") BytesNodes.ToBytesNode selfToBytesNode,
772-
@Cached("create()") BytesNodes.ToBytesNode otherToBytesNode) {
773-
byte[] stripBs = selfToBytesNode.execute(bytes);
774-
byte[] bs = otherToBytesNode.execute(self);
775-
int i = start(bs);
776-
int stop = stop(bs);
777-
outer: for (; i != stop; i += mod()) {
778-
for (byte b : stripBs) {
779-
if (b == bs[i]) {
780-
continue outer;
781-
}
782-
}
783-
break;
784-
}
785-
return newBytesFrom(bs, i);
786-
}
787-
788-
}
789-
790-
@Builtin(name = "lstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
791-
@GenerateNodeFactory
792-
abstract static class LStripNode extends AStripNode {
793-
@Override
794-
PByteArray newBytesFrom(byte[] bs, int i) {
795-
byte[] out;
796-
if (i != 0) {
797-
int len = bs.length - i;
798-
out = new byte[len];
799-
System.arraycopy(bs, i, out, 0, len);
800-
} else {
801-
out = bs;
802-
}
803-
return factory().createByteArray(out);
804-
}
805-
806-
@Override
807-
int mod() {
808-
return 1;
809-
}
810-
811-
@Override
812-
int stop(byte[] bs) {
813-
return bs.length;
814-
}
815-
816-
@Override
817-
int start(byte[] bs) {
818-
return 0;
819-
}
820-
}
821-
822-
@Builtin(name = "rstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
823-
@GenerateNodeFactory
824-
abstract static class RStripNode extends AStripNode {
825-
@Override
826-
PByteArray newBytesFrom(byte[] bs, int i) {
827-
byte[] out;
828-
int len = i + 1;
829-
if (len != bs.length) {
830-
out = new byte[len];
831-
System.arraycopy(bs, 0, out, 0, len);
832-
} else {
833-
out = bs;
834-
}
835-
return factory().createByteArray(out);
836-
}
837-
838-
@Override
839-
int mod() {
840-
return -1;
841-
}
842-
843-
@Override
844-
int stop(byte[] bs) {
845-
return -1;
846-
}
847-
848-
@Override
849-
int start(byte[] bs) {
850-
return bs.length - 1;
851-
}
852-
}
853732
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -455,17 +455,6 @@ private int getLength(SequenceStorage s) {
455455
}
456456
}
457457

458-
@Builtin(name = "strip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
459-
@GenerateNodeFactory
460-
abstract static class StripNode extends PythonBuiltinNode {
461-
@Specialization
462-
@TruffleBoundary
463-
PBytes strip(PBytes self, @SuppressWarnings("unused") PNone bytes,
464-
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
465-
return factory().createBytes(new String(toBytesNode.execute(self)).trim().getBytes());
466-
}
467-
}
468-
469458
// bytes.find(bytes[, start[, end]])
470459
@Builtin(name = "find", minNumOfPositionalArgs = 2, maxNumOfPositionalArgs = 4)
471460
@GenerateNodeFactory

graalpython/lib-graalpython/bytes.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,9 @@ def rfind(self, sub, start=None, end=None):
109109

110110

111111
bytes.rfind = rfind
112+
113+
def strip(self, what=None):
114+
return self.lstrip(what).rstrip(what)
115+
116+
117+
bytes.strip = strip

0 commit comments

Comments
 (0)