Skip to content

Commit 39c0ba2

Browse files
committed
[GR-12446] First batch of small fixes needed to import full NumPy.
PullRequest: graalpython/271
2 parents 22509be + 4f20ee4 commit 39c0ba2

File tree

13 files changed

+178
-71
lines changed

13 files changed

+178
-71
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,3 +523,9 @@ def test_binary_op():
523523
assert b"123" <= b"1234"
524524
assert b"123" >= b"123"
525525
assert not (b"123" >= b"1234")
526+
527+
528+
def test_strip_bytearray():
529+
assert bytearray(b'abc').strip(b'ac') == b'b'
530+
assert bytearray(b'abc').lstrip(b'ac') == b'bc'
531+
assert bytearray(b'abc').rstrip(b'ac') == b'ab'

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,15 +698,15 @@ public PInt getFalse() {
698698
return pyFalse;
699699
}
700700

701-
public RuntimeException raiseInvalidSyntax(Source source, SourceSection section) {
701+
public RuntimeException raiseInvalidSyntax(Source source, SourceSection section, String message, Object... arguments) {
702702
Node location = new Node() {
703703
@Override
704704
public SourceSection getSourceSection() {
705705
return section;
706706
}
707707
};
708708
PBaseException instance;
709-
instance = factory().createBaseException(SyntaxError, "invalid syntax", new Object[0]);
709+
instance = factory().createBaseException(SyntaxError, message, arguments);
710710
String path = source.getPath();
711711
instance.setAttribute("filename", path != null ? path : source.getName() != null ? source.getName() : "<string>");
712712
instance.setAttribute("text", section.isAvailable() ? source.getCharacters(section.getStartLine()) : "");

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

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -708,4 +708,125 @@ Object doGeneric(@SuppressWarnings("unused") Object self) {
708708
return PNotImplemented.NOT_IMPLEMENTED;
709709
}
710710
}
711+
712+
abstract static class AStripNode extends PythonBinaryBuiltinNode {
713+
int mod() {
714+
throw new RuntimeException();
715+
}
716+
717+
int stop(@SuppressWarnings("unused") byte[] bs) {
718+
throw new RuntimeException();
719+
}
720+
721+
int start(@SuppressWarnings("unused") byte[] bs) {
722+
throw new RuntimeException();
723+
}
724+
725+
PByteArray newBytesFrom(@SuppressWarnings("unused") byte[] bs, @SuppressWarnings("unused") int i) {
726+
throw new RuntimeException();
727+
}
728+
729+
@Specialization
730+
PByteArray strip(PByteArray self, @SuppressWarnings("unused") PNone bytes,
731+
@Cached("create()") BytesNodes.ToBytesNode toBytesNode) {
732+
byte[] bs = toBytesNode.execute(self);
733+
int i = start(bs);
734+
int stop = stop(bs);
735+
for (; i != stop; i += mod()) {
736+
if (!isWhitespace(bs[i])) {
737+
break;
738+
}
739+
}
740+
return newBytesFrom(bs, i);
741+
}
742+
743+
@TruffleBoundary
744+
private static boolean isWhitespace(byte b) {
745+
return Character.isWhitespace(b);
746+
}
747+
748+
@Specialization
749+
PByteArray strip(PByteArray self, PBytes bytes,
750+
@Cached("create()") BytesNodes.ToBytesNode selfToBytesNode,
751+
@Cached("create()") BytesNodes.ToBytesNode otherToBytesNode) {
752+
byte[] stripBs = selfToBytesNode.execute(bytes);
753+
byte[] bs = otherToBytesNode.execute(self);
754+
int i = start(bs);
755+
int stop = stop(bs);
756+
outer: for (; i != stop; i += mod()) {
757+
for (byte b : stripBs) {
758+
if (b == bs[i]) {
759+
continue outer;
760+
}
761+
}
762+
break;
763+
}
764+
return newBytesFrom(bs, i);
765+
}
766+
767+
}
768+
769+
@Builtin(name = "lstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
770+
@GenerateNodeFactory
771+
abstract static class LStripNode extends AStripNode {
772+
@Override
773+
PByteArray newBytesFrom(byte[] bs, int i) {
774+
byte[] out;
775+
if (i != 0) {
776+
int len = bs.length - i;
777+
out = new byte[len];
778+
System.arraycopy(bs, i, out, 0, len);
779+
} else {
780+
out = bs;
781+
}
782+
return factory().createByteArray(out);
783+
}
784+
785+
@Override
786+
int mod() {
787+
return 1;
788+
}
789+
790+
@Override
791+
int stop(byte[] bs) {
792+
return bs.length;
793+
}
794+
795+
@Override
796+
int start(byte[] bs) {
797+
return 0;
798+
}
799+
}
800+
801+
@Builtin(name = "rstrip", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, keywordArguments = {"bytes"})
802+
@GenerateNodeFactory
803+
abstract static class RStripNode extends AStripNode {
804+
@Override
805+
PByteArray newBytesFrom(byte[] bs, int i) {
806+
byte[] out;
807+
int len = i + 1;
808+
if (len != bs.length) {
809+
out = new byte[len];
810+
System.arraycopy(bs, 0, out, 0, len);
811+
} else {
812+
out = bs;
813+
}
814+
return factory().createByteArray(out);
815+
}
816+
817+
@Override
818+
int mod() {
819+
return -1;
820+
}
821+
822+
@Override
823+
int stop(byte[] bs) {
824+
return -1;
825+
}
826+
827+
@Override
828+
int start(byte[] bs) {
829+
return bs.length - 1;
830+
}
831+
}
711832
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/common/SequenceStorageNodes.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,7 @@ private SequenceStorage createEmpty(SequenceStorage l, SequenceStorage r, int le
20122012
return createEmptyNode.execute(r, len);
20132013
}
20142014
SequenceStorage empty = createEmptyNode.execute(l, len);
2015+
empty.ensureCapacity(len);
20152016
empty.setNewLength(len);
20162017
return empty;
20172018
}
@@ -2427,8 +2428,8 @@ DoubleSequenceStorage doEmptyDouble(@SuppressWarnings("unused") EmptySequenceSto
24272428
}
24282429

24292430
@Specialization
2430-
ListSequenceStorage doEmptyPList(@SuppressWarnings("unused") EmptySequenceStorage s, PList val) {
2431-
return new ListSequenceStorage(val.getSequenceStorage());
2431+
ListSequenceStorage doEmptyPList(@SuppressWarnings("unused") EmptySequenceStorage s, @SuppressWarnings("unused") PList val) {
2432+
return new ListSequenceStorage(0);
24322433
}
24332434

24342435
@Specialization
@@ -2623,9 +2624,9 @@ DoubleSequenceStorage doDouble(@SuppressWarnings("unused") SequenceStorage s, in
26232624
}
26242625

26252626
@Specialization(guards = "isList(s)")
2626-
ListSequenceStorage doList(@SuppressWarnings("unused") SequenceStorage s, @SuppressWarnings("unused") int cap) {
2627+
ListSequenceStorage doList(@SuppressWarnings("unused") SequenceStorage s, int cap) {
26272628
// TODO not quite accurate in case of native sequence storage
2628-
return new ListSequenceStorage(s);
2629+
return new ListSequenceStorage(cap);
26292630
}
26302631

26312632
@Specialization(guards = "isTuple(s)")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/DestructuringAssignmentNode.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@
2525
*/
2626
package com.oracle.graal.python.nodes.frame;
2727

28-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
29-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.SyntaxError;
30-
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
3128
import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
3229
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETITEM__;
30+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
31+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
3332

3433
import java.util.Arrays;
3534

@@ -182,7 +181,7 @@ public void doWrite(VirtualFrame frame, Object rhsValue) {
182181
try {
183182
getNonExistingItem.execute(rhsValue, nonExistingItem);
184183
tooManyValuesProfile.enter();
185-
throw raise(SyntaxError, "too many values to unpack (expected %d)", nonExistingItem);
184+
throw getCore().raiseInvalidSyntax(getEncapsulatingSourceSection().getSource(), getEncapsulatingSourceSection(), "too many values to unpack (expected %d)", nonExistingItem);
186185
} catch (PException e) {
187186
if (tooManyValuesErrorProfile.profileException(e, IndexError)) {
188187
// expected, fall through

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/parser/PythonTreeTranslator.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ private void visitCallArglist(Python3Parser.ArglistContext arglist, List<Express
302302
}
303303
} else if (isStararg(argctx)) {
304304
if (kwargs != null) {
305-
throw errors.raise(SyntaxError, "iterable argument unpacking follows keyword argument unpacking");
305+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(argctx), "iterable argument unpacking follows keyword argument unpacking");
306306
}
307307
if (starargs != null) {
308308
starargs = factory.createBinaryOperation("+", starargs, arg);
@@ -311,10 +311,10 @@ private void visitCallArglist(Python3Parser.ArglistContext arglist, List<Express
311311
}
312312
} else {
313313
if (!keywords.isEmpty()) {
314-
throw errors.raise(SyntaxError, "positional argument follows keyword argument");
314+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(argctx), "positional argument follows keyword argument");
315315
}
316316
if (kwargs != null) {
317-
throw errors.raise(SyntaxError, "positional argument follows keyword argument unpacking");
317+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(argctx), "positional argument follows keyword argument unpacking");
318318
}
319319
argumentNodes.add(arg);
320320
}
@@ -355,7 +355,7 @@ private ExpressionNode getDefaultarg(Python3Parser.ArgumentContext ctx) {
355355
// In CPython, ast.c ensures this
356356
String argName = ctx.test(0).accept(new ExtractNameVisitor());
357357
if (argName == null) {
358-
throw errors.raise(SyntaxError, "Keyword can't be an expression");
358+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(ctx), "Keyword can't be an expression");
359359
}
360360
return factory.createKeywordLiteral((ExpressionNode) ctx.test(1).accept(this), argName);
361361
} else {
@@ -428,7 +428,7 @@ public Object visitAtom(Python3Parser.AtomContext ctx) {
428428
} else if (ctx.NAME() != null) {
429429
return environment.findVariable(ctx.NAME().getText());
430430
} else if (ctx.getChildCount() == 1) {
431-
return parseSpecialLiteral(ctx.getText());
431+
return parseSpecialLiteral(ctx);
432432
} else if (ctx.dictorsetmaker() != null) {
433433
return super.visitAtom(ctx);
434434
} else if (ctx.getChild(0).getText().equals("{")) { // empty dict
@@ -540,23 +540,24 @@ private ExpressionNode visitNormalDictmaker(Python3Parser.DictmakerContext ctx)
540540

541541
private PNode visitDictmakerComprehension(Python3Parser.DictmakerContext ctx) {
542542
if (!ctx.expr().isEmpty()) {
543-
throw errors.raise(SyntaxError, "dict unpacking cannot be used in dict comprehension");
543+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(ctx), "dict unpacking cannot be used in dict comprehension");
544544
}
545545
return factory.callBuiltin(DICT,
546546
createComprehensionExpression(ctx, ctx.comp_for(), c -> factory.createTupleLiteral((ExpressionNode) ctx.test(0).accept(this), (ExpressionNode) ctx.test(1).accept(this))));
547547
}
548548

549-
private Object parseSpecialLiteral(String text) {
550-
if (text.equals("...")) {
549+
private Object parseSpecialLiteral(Python3Parser.AtomContext ctx) {
550+
String txt = ctx.getText();
551+
if (txt.equals("...")) {
551552
return factory.createObjectLiteral(PEllipsis.INSTANCE);
552-
} else if (text.equals("None")) {
553+
} else if (txt.equals("None")) {
553554
return factory.createObjectLiteral(PNone.NONE);
554-
} else if (text.equals("True")) {
555+
} else if (txt.equals("True")) {
555556
return factory.createBooleanLiteral(true);
556-
} else if (text.equals("False")) {
557+
} else if (txt.equals("False")) {
557558
return factory.createBooleanLiteral(false);
558559
} else {
559-
throw errors.raise(SyntaxError, "Unknown literal %s", text);
560+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(ctx), "Unknown literal %s", txt);
560561
}
561562
}
562563

@@ -975,7 +976,7 @@ public Object visitImport_from(Python3Parser.Import_fromContext ctx) {
975976
return factory.createImportFrom(sb.toString(), fromlist.toArray(new String[0]), asNodes.toArray(new WriteNode[0]), level);
976977
} else {
977978
if (!environment.atModuleLevel()) {
978-
throw errors.raise(SyntaxError, "import * only allowed at module level");
979+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(ctx), "import * only allowed at module level");
979980
}
980981
return factory.createImportStar(sb.toString(), level);
981982
}
@@ -1097,7 +1098,7 @@ private void delTarget(List<StatementNode> blockList, PNode target) {
10971098
delTarget(blockList, targetValue);
10981099
}
10991100
} else {
1100-
throw errors.raise(SyntaxError, "can't delete '%s'", target.getSourceSection().getCharacters());
1101+
throw errors.raiseInvalidSyntax(target.getSourceSection().getSource(), target.getSourceSection(), "can't delete '%s'", target.getSourceSection().getCharacters());
11011102
}
11021103
}
11031104

@@ -1156,7 +1157,7 @@ public Object visitReturn_stmt(Python3Parser.Return_stmtContext ctx) {
11561157
return factory.createFrameReturn(factory.createWriteLocal((ExpressionNode) ctx.testlist().accept(this), environment.getReturnSlot()));
11571158
}
11581159
}
1159-
throw errors.raise(SyntaxError, "'return' outside function");
1160+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(ctx), "'return' outside function");
11601161
}
11611162

11621163
private static boolean lastChildIsComma(ParserRuleContext ctx) {
@@ -1369,7 +1370,7 @@ public Object visitTry_stmt(Python3Parser.Try_stmtContext ctx) {
13691370
WriteNode exceptName = null;
13701371
if (excctx.test() != null) {
13711372
if (gotDefaultExcept) {
1372-
throw errors.raise(SyntaxError, "default except: must be last");
1373+
throw errors.raiseInvalidSyntax(source, deriveSourceSection(excctx), "default except: must be last");
13731374
}
13741375
exceptType = (ExpressionNode) excctx.test().accept(this);
13751376
if (excctx.NAME() != null) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonParser.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ public enum ParserMode {
7272
public interface ParserErrorCallback {
7373
RuntimeException raise(PythonBuiltinClassType type, String message, Object... args);
7474

75-
RuntimeException raiseInvalidSyntax(Source source, SourceSection section);
75+
RuntimeException raiseInvalidSyntax(Source source, SourceSection section, String message, Object... arguments);
76+
77+
default RuntimeException raiseInvalidSyntax(Source source, SourceSection section) {
78+
return raiseInvalidSyntax(source, section, "invalid syntax", new Object[0]);
79+
}
7680

7781
PythonLanguage getLanguage();
7882
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/sequence/storage/EmptySequenceStorage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public SequenceStorage generalizeFor(Object value, SequenceStorage target) {
5757
} else if (value instanceof Double) {
5858
generalized = new DoubleSequenceStorage();
5959
} else if (value instanceof PList) {
60-
generalized = new ListSequenceStorage(((PList) value).getSequenceStorage());
60+
generalized = new ListSequenceStorage(0);
6161
} else if (value instanceof PTuple) {
6262
generalized = new TupleSequenceStorage();
6363
} else {

0 commit comments

Comments
 (0)