Skip to content

Commit 85c2ec7

Browse files
committed
[GR-23306] - Make a few test_json tests pass
PullRequest: graalpython/1278
2 parents 9768df3 + 99b4975 commit 85c2ec7

File tree

12 files changed

+131
-102
lines changed

12 files changed

+131
-102
lines changed

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/ArgumentClinic.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,9 @@ enum ClinicConversion {
132132
* {@link #defaultValue()}, and {@link #useDefaultForNone()}.
133133
*/
134134
CodePoint,
135+
/**
136+
* Corresponds to CPython's {@code Py_buffer} convertor.
137+
*/
138+
Buffer,
135139
}
136140
}

graalpython/com.oracle.graal.python.cext/src/object.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,9 @@ int PyObject_Print(PyObject* object, FILE* fd, int flags) {
372372
int f = fileno(fd);
373373
PyTuple_SetItem(args, 0, PyLong_FromLong(f));
374374
kwargs = PyDict_New();
375-
int buffering = 0;
375+
int buffering = 1;
376376
PyDict_SetItemString(kwargs, "buffering", PyLong_FromLong(buffering));
377-
PyDict_SetItemString(kwargs, "mode", polyglot_from_string("wb", SRC_CS));
377+
PyDict_SetItemString(kwargs, "mode", polyglot_from_string("w", SRC_CS));
378378
file = PyObject_Call(openFunc, args, kwargs);
379379

380380
printfunc = UPCALL_CEXT_O(_jls_PyTruffle_GetBuiltin, polyglot_from_string("print", SRC_CS));

graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/ArgumentClinicModel.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public static String getCodeSnippet(ArgumentClinic annotation, BuiltinAnnotation
7373
return format("JavaIntConversionNodeGen.create(%s, %s)", annotation.defaultValue(), annotation.useDefaultForNone());
7474
case CodePoint:
7575
return format("CodePointConversionNodeGen.create(\"%s\", %s, %s)", builtin.name, annotation.defaultValue(), annotation.useDefaultForNone());
76+
case Buffer:
77+
return "BufferConversionNodeGen.create()";
7678
case Index:
7779
return format("IndexConversionNodeGen.create(%s, %s)", annotation.defaultValue(), annotation.useDefaultForNone());
7880
case None:
@@ -107,6 +109,8 @@ private static String getConvertorImport(ArgumentClinic annotation) {
107109
return "IndexConversionNodeGen";
108110
case CodePoint:
109111
return "CodePointConversionNodeGen";
112+
case Buffer:
113+
return "BufferConversionNodeGen";
110114
case None:
111115
return "DefaultValueNode";
112116
default:
@@ -120,6 +124,7 @@ public static PrimitiveType[] getAcceptedPrimitiveTypes(ArgumentClinic annotatio
120124
return new PrimitiveType[]{PrimitiveType.Boolean};
121125
case String:
122126
case CodePoint:
127+
case Buffer:
123128
return new PrimitiveType[0];
124129
case Int:
125130
case Index:

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/module/PosixTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,17 +140,17 @@ public void lseek() throws IOException {
140140
@Test
141141
public void write() throws IOException {
142142
assertPrints("", open("posix.O_RDWR") +
143-
"posix.write(fd, 'hello')");
143+
"posix.write(fd, b'hello')");
144144
assertTrue(new String(Files.readAllBytes(tmpfile)).equals("hello"));
145145
}
146146

147147
@Test
148148
public void close() throws IOException {
149149
assertLastLineErrorContains("OSError",
150150
open("posix.O_RDWR") +
151-
"posix.write(fd, 'hello')\n" +
151+
"posix.write(fd, b'hello')\n" +
152152
"posix.close(fd)\n" +
153-
"posix.write(fd, 'world')");
153+
"posix.write(fd, b'world')");
154154
assertTrue(new String(Files.readAllBytes(tmpfile)).equals("hello"));
155155
}
156156

@@ -179,7 +179,7 @@ public void printToFile() throws IOException {
179179
assertPrints("", open("posix.O_CREAT") +
180180
"import _io\n" +
181181
"f = _io.FileIO(fd, mode='w')\n" +
182-
"print('hello', file=f)");
182+
"print('hello', file=_io.TextIOWrapper(f))");
183183
assertEquals("hello\n", new String(Files.readAllBytes(tmpfile)));
184184
}
185185

graalpython/com.oracle.graal.python.test/src/tests/cpyext/__init__.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -341,10 +341,7 @@ def create_module(self, name=None):
341341
code = self.template.format(**fargs)
342342

343343
with open("%s/%s.c" % (__dir__, self.name), "wb", buffering=0) as f:
344-
if GRAALPYTHON:
345-
f.write(code)
346-
else:
347-
f.write(bytes(code, 'utf-8'))
344+
f.write(bytes(code, 'utf-8'))
348345

349346
def _insert(self, d, name, default_value):
350347
d[name] = d.get(name, default_value)
@@ -597,10 +594,7 @@ def CPyExtType(name, code, **kwargs):
597594

598595
source_file = "%s/%s.c" % (__dir__, name)
599596
with open(source_file, "wb", buffering=0) as f:
600-
if GRAALPYTHON:
601-
f.write(c_source)
602-
else:
603-
f.write(bytes(c_source, 'utf-8'))
597+
f.write(bytes(c_source, 'utf-8'))
604598

605599
# ensure file was really written
606600
try:

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,3 +879,8 @@ def test_short_repr(self):
879879
# Since Python 3.2, repr and str are identical
880880
self.assertEqual(repr(float(s)), str(float(s)))
881881
self.assertEqual(repr(float(negs)), str(float(negs)))
882+
883+
884+
class SubclassTests(unittest.TestCase):
885+
def test_subclass_nan(self):
886+
self.assertEqual(MyFloat, type(MyFloat('nan')))

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,6 @@ public abstract static class FloatNode extends PythonBinaryBuiltinNode {
809809
@Child private LookupAndCallUnaryNode callReprNode;
810810

811811
@Child private IsBuiltinClassProfile isPrimitiveProfile = IsBuiltinClassProfile.create();
812-
private ConditionProfile isNanProfile;
813812

814813
public abstract Object executeWith(VirtualFrame frame, Object cls, Object arg);
815814

@@ -859,7 +858,7 @@ Object floatFromDouble(Object cls, double arg) {
859858
if (isPrimitiveFloat(cls)) {
860859
return arg;
861860
}
862-
return factoryCreateFloat(cls, arg);
861+
return factory().createFloat(cls, arg);
863862
}
864863

865864
@Specialization(guards = "!isNativeClass(cls)")
@@ -868,7 +867,7 @@ Object floatFromString(VirtualFrame frame, Object cls, String arg) {
868867
if (isPrimitiveFloat(cls)) {
869868
return value;
870869
}
871-
return factoryCreateFloat(cls, value);
870+
return factory().createFloat(cls, value);
872871
}
873872

874873
private double convertBytesToDouble(VirtualFrame frame, PBytesLike arg) {
@@ -1011,21 +1010,6 @@ private byte[] getByteArray(VirtualFrame frame, PBytesLike pByteArray) {
10111010
}
10121011
return toByteArrayNode.execute(frame, pByteArray);
10131012
}
1014-
1015-
private PFloat factoryCreateFloat(Object cls, double arg) {
1016-
if (isNaN(arg)) {
1017-
return getCore().getNaN();
1018-
}
1019-
return factory().createFloat(cls, arg);
1020-
}
1021-
1022-
private boolean isNaN(double d) {
1023-
if (isNanProfile == null) {
1024-
CompilerDirectives.transferToInterpreterAndInvalidate();
1025-
isNanProfile = ConditionProfile.createBinaryProfile();
1026-
}
1027-
return isNanProfile.profile(Double.isNaN(d));
1028-
}
10291013
}
10301014

10311015
// frozenset([iterable])

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java

Lines changed: 20 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,10 @@
9898
import com.oracle.graal.python.builtins.objects.PNone;
9999
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
100100
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
101-
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
102101
import com.oracle.graal.python.builtins.objects.common.SequenceNodes;
103102
import com.oracle.graal.python.builtins.objects.common.SequenceNodes.LenNode;
104-
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
105103
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemDynamicNode;
106104
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
107-
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodesFactory.ToByteArrayNodeGen;
108105
import com.oracle.graal.python.builtins.objects.dict.PDict;
109106
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
110107
import com.oracle.graal.python.builtins.objects.floats.PFloat;
@@ -143,7 +140,6 @@
143140
import com.oracle.graal.python.runtime.exception.PythonExitException;
144141
import com.oracle.graal.python.runtime.sequence.PSequence;
145142
import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage;
146-
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
147143
import com.oracle.graal.python.util.FileDeleteShutdownHook;
148144
import com.oracle.graal.python.util.OverflowException;
149145
import com.oracle.truffle.api.CompilerDirectives;
@@ -1145,80 +1141,37 @@ Object mkdirMode(VirtualFrame frame, Object pathArg, @SuppressWarnings("unused")
11451141
}
11461142
}
11471143

1148-
@Builtin(name = "write", minNumOfPositionalArgs = 2)
1144+
@Builtin(name = "write", minNumOfPositionalArgs = 2, parameterNames = {"fd", "str"})
1145+
@ArgumentClinic(name = "fd", conversion = ClinicConversion.Int, defaultValue = "-1")
1146+
@ArgumentClinic(name = "str", conversion = ClinicConversion.Buffer)
11491147
@GenerateNodeFactory
1150-
@TypeSystemReference(PythonArithmeticTypes.class)
1151-
public abstract static class WriteNode extends PythonFileNode {
1152-
@Child private SequenceStorageNodes.ToByteArrayNode toByteArrayNode;
1153-
private final BranchProfile gotException = BranchProfile.create();
1154-
private final BranchProfile notWritable = BranchProfile.create();
1155-
1156-
public abstract Object executeWith(VirtualFrame frame, Object fd, Object data);
1148+
public abstract static class WriteNode extends PythonBinaryClinicBuiltinNode {
1149+
@Override
1150+
protected ArgumentClinicProvider getArgumentClinic() {
1151+
return PosixModuleBuiltinsClinicProviders.WriteNodeClinicProviderGen.INSTANCE;
1152+
}
11571153

11581154
@TruffleBoundary(allowInlining = true, transferToInterpreterOnException = false)
1159-
private static Object writableOp(byte[] data, Object channel) throws IOException {
1160-
if (channel instanceof WritableByteChannel) {
1161-
return doWriteOp(data, channel);
1162-
}
1163-
return null;
1155+
private static int doWriteOp(byte[] data, WritableByteChannel channel) throws IOException {
1156+
return channel.write(ByteBuffer.wrap(data));
11641157
}
11651158

11661159
@Specialization
11671160
Object write(VirtualFrame frame, int fd, byte[] data,
1168-
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
1169-
Channel channel = getResources().getFileChannel(fd, channelClassProfile);
1161+
@Cached("createClassProfile()") ValueProfile channelClassProfile,
1162+
@Cached BranchProfile gotExceptionProfile,
1163+
@Cached BranchProfile nonWritableChannelProfile) {
1164+
Channel channel = getContext().getResources().getFileChannel(fd, channelClassProfile);
1165+
if (!(channel instanceof WritableByteChannel)) {
1166+
nonWritableChannelProfile.enter();
1167+
throw raiseOSError(frame, OSErrorEnum.EBADF);
1168+
}
11701169
try {
1171-
Object ret = writableOp(data, channel);
1172-
if (ret != null) {
1173-
return ret;
1174-
}
1170+
return doWriteOp(data, (WritableByteChannel) channel);
11751171
} catch (Exception e) {
1176-
gotException.enter();
1172+
gotExceptionProfile.enter();
11771173
throw raiseOSError(frame, e);
11781174
}
1179-
notWritable.enter();
1180-
throw raiseOSError(frame, OSErrorEnum.EBADF);
1181-
}
1182-
1183-
@TruffleBoundary(allowInlining = true, transferToInterpreterOnException = false)
1184-
private static int doWriteOp(byte[] data, Object channel) throws IOException {
1185-
return ((WritableByteChannel) channel).write(ByteBuffer.wrap(data));
1186-
}
1187-
1188-
@Specialization
1189-
Object write(VirtualFrame frame, int fd, String data,
1190-
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
1191-
return write(frame, fd, stringToBytes(data), channelClassProfile);
1192-
}
1193-
1194-
@TruffleBoundary
1195-
private static byte[] stringToBytes(String data) {
1196-
return data.getBytes();
1197-
}
1198-
1199-
@Specialization
1200-
Object write(VirtualFrame frame, int fd, PBytesLike data,
1201-
@Cached("createClassProfile()") ValueProfile channelClassProfile) {
1202-
return write(frame, fd, getByteArray(data.getSequenceStorage()), channelClassProfile);
1203-
}
1204-
1205-
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
1206-
static Object writePInt(VirtualFrame frame, Object fd, Object data,
1207-
@CachedLibrary("fd") PythonObjectLibrary lib,
1208-
@Cached("create()") WriteNode recursive) {
1209-
return recursive.executeWith(frame, lib.asSizeWithState(fd, PArguments.getThreadState(frame)), data);
1210-
}
1211-
1212-
private byte[] getByteArray(SequenceStorage storage) {
1213-
if (toByteArrayNode == null) {
1214-
CompilerDirectives.transferToInterpreterAndInvalidate();
1215-
toByteArrayNode = insert(ToByteArrayNodeGen.create());
1216-
}
1217-
return toByteArrayNode.execute(storage);
1218-
}
1219-
1220-
public static WriteNode create() {
1221-
return PosixModuleBuiltinsFactory.WriteNodeFactory.create(null);
12221175
}
12231176
}
12241177

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.nodes.function.builtins.clinic;
42+
43+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
44+
import com.oracle.graal.python.nodes.ErrorMessages;
45+
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode.ArgumentCastNodeWithRaise;
46+
import com.oracle.graal.python.runtime.exception.PythonErrorType;
47+
import com.oracle.truffle.api.CompilerDirectives;
48+
import com.oracle.truffle.api.dsl.Specialization;
49+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
50+
import com.oracle.truffle.api.library.CachedLibrary;
51+
52+
public abstract class BufferConversionNode extends ArgumentCastNodeWithRaise {
53+
54+
@Specialization(limit = "getCallSiteInlineCacheMaxDepth()")
55+
byte[] doObject(Object value,
56+
@CachedLibrary("value") PythonObjectLibrary lib) {
57+
if (lib.isBuffer(value)) {
58+
try {
59+
return lib.getBufferBytes(value);
60+
} catch (UnsupportedMessageException e) {
61+
throw CompilerDirectives.shouldNotReachHere("Buffer-like object does not support getBufferBytes()");
62+
}
63+
}
64+
throw raise(PythonErrorType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value);
65+
}
66+
}

graalpython/lib-graalpython/_io.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,24 @@ def truncate(self, size=-1):
534534
return size
535535

536536

537+
class StdPrinter:
538+
def __init__(self, file_io):
539+
self.file_io = file_io
540+
541+
def write(self, data):
542+
return self.file_io.write(bytes(data, "utf-8"))
543+
544+
def __getattr__(self, attr):
545+
return self.file_io.__getattribute__(attr)
546+
547+
537548
sys.stdin = FileIO(0, mode='r', closefd=False)
538549
sys.stdin.name = "<stdin>"
539550
sys.__stdin__ = sys.stdin
540551
sys.stdout = FileIO(1, mode='w', closefd=False)
541552
sys.stdout.name = "<stdout>"
542553
sys.__stdout__ = sys.stdout
543-
sys.stderr = FileIO(2, mode='w', closefd=False)
554+
sys.stderr = StdPrinter(FileIO(2, mode='w', closefd=False))
544555
sys.stderr.name = "<stderr>"
545556
sys.__stderr__ = sys.stderr
546557

0 commit comments

Comments
 (0)