Skip to content

Commit 3c022c5

Browse files
committed
[GR-40968] Various fixes for Pygal
PullRequest: graalpython/2436
2 parents 0b53ad4 + 241ce05 commit 3c022c5

File tree

11 files changed

+201
-32
lines changed

11 files changed

+201
-32
lines changed

graalpython/com.oracle.graal.python.cext/include/Python.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@
144144
#include "pystrtod.h"
145145
#include "tracemalloc.h"
146146
#include "genobject.h"
147+
#include "osmodule.h"
147148

148149
#include "abstract.h"
149150

graalpython/com.oracle.graal.python.cext/include/object.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ PyAPI_FUNC(void) _Py_SET_TYPE(PyObject *, struct _typeobject *);
130130
PyAPI_FUNC(Py_ssize_t) _Py_SIZE(PyVarObject *);
131131
PyAPI_FUNC(void) _Py_SET_SIZE(PyVarObject *, Py_ssize_t);
132132

133-
#define Py_REFCNT(ob) (_Py_REFCNT(_PyObject_CAST(ob)))
134-
#define Py_SET_REFCNT(ob, v) (_Py_SET_REFCNT(_PyObject_CAST(ob), v))
135-
#define Py_TYPE(ob) (_Py_TYPE(_PyObject_CAST(ob)))
136-
#define Py_SIZE(ob) (_Py_SIZE(_PyVarObject_CAST(ob)))
133+
#define Py_REFCNT(ob) (_PyObject_CAST(ob)->ob_refcnt)
134+
#define Py_TYPE(ob) (_PyObject_CAST(ob)->ob_type)
135+
#define Py_SIZE(ob) (_PyVarObject_CAST(ob)->ob_size)
137136

137+
#define Py_SET_REFCNT(ob, v) (_Py_SET_REFCNT(_PyObject_CAST(ob), v))
138138
#define Py_SET_TYPE(ob, v) (_Py_SET_TYPE(_PyObject_CAST(ob), (struct _typeobject *) v))
139139
#define Py_SET_SIZE(ob, v) (_Py_SET_SIZE(_PyVarObject_CAST(ob), (Py_ssize_t) v))
140140

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* Copyright (c) 2022, Oracle and/or its affiliates.
2+
* Copyright (C) 1996-2017 Python Software Foundation
3+
*
4+
* Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
5+
*/
6+
/* os module interface */
7+
8+
#ifndef Py_OSMODULE_H
9+
#define Py_OSMODULE_H
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03060000
15+
PyAPI_FUNC(PyObject *) PyOS_FSPath(PyObject *path);
16+
#endif
17+
18+
#ifdef __cplusplus
19+
}
20+
#endif
21+
#endif /* !Py_OSMODULE_H */
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright (c) 2022, 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+
#include "capi.h"
42+
43+
UPCALL_ID(PyOS_FSPath);
44+
PyObject* PyOS_FSPath(PyObject* path) {
45+
return UPCALL_CEXT_O(_jls_PyOS_FSPath, native_to_java(path));
46+
}

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
# SOFTWARE.
3939

4040
import sys
41+
import pathlib
42+
import os
4143
from . import CPyExtTestCase, CPyExtFunction, CPyExtFunctionOutVars, unhandled_error_compare, GRAALPYTHON
4244
import builtins
4345
__dir__ = __file__.rpartition("/")[0]
@@ -251,7 +253,7 @@ def compile_module(self, name):
251253
return 0;
252254
}
253255
#endif
254-
256+
255257
PyObject* primitive_sharing(PyObject* val) {
256258
Py_ssize_t val_refcnt = Py_REFCNT(val);
257259
// assume val's refcnt is X > 0
@@ -319,3 +321,24 @@ def compile_module(self, name):
319321
callfunction="wrap_PyEval_GetBuiltins",
320322
cmpfunc=unhandled_error_compare
321323
)
324+
325+
test_PyOS_FSPath = CPyExtFunction(
326+
lambda args: os.fspath(*args),
327+
lambda: (
328+
(b"bytespath",),
329+
("stringpath",),
330+
(pathlib.Path("pathpath"),),
331+
(123,),
332+
(object(),),
333+
),
334+
callfunction="call_PyOS_FSPath",
335+
code="""
336+
static PyObject* call_PyOS_FSPath(PyObject* value) {
337+
return PyOS_FSPath(value);
338+
}
339+
""",
340+
resultspec="O",
341+
argspec="O",
342+
arguments=["PyObject* value"],
343+
cmpfunc=unhandled_error_compare
344+
)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
import com.oracle.graal.python.builtins.modules.cext.PythonCextModuleBuiltins;
149149
import com.oracle.graal.python.builtins.modules.cext.PythonCextNamespaceBuiltins;
150150
import com.oracle.graal.python.builtins.modules.cext.PythonCextObjectBuiltins;
151+
import com.oracle.graal.python.builtins.modules.cext.PythonCextPosixmoduleBuiltins;
151152
import com.oracle.graal.python.builtins.modules.cext.PythonCextPyLifecycleBuiltins;
152153
import com.oracle.graal.python.builtins.modules.cext.PythonCextPyStateBuiltins;
153154
import com.oracle.graal.python.builtins.modules.cext.PythonCextPythonRunBuiltins;
@@ -546,6 +547,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed)
546547
new PythonCextMethodBuiltins(),
547548
new PythonCextModuleBuiltins(),
548549
new PythonCextObjectBuiltins(),
550+
new PythonCextPosixmoduleBuiltins(),
549551
new PythonCextPyLifecycleBuiltins(),
550552
new PythonCextPyStateBuiltins(),
551553
new PythonCextPythonRunBuiltins(),

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

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode;
8181
import com.oracle.graal.python.lib.PyLongAsLongNode;
8282
import com.oracle.graal.python.lib.PyNumberIndexNode;
83+
import com.oracle.graal.python.lib.PyOSFSPathNode;
8384
import com.oracle.graal.python.lib.PyObjectAsFileDescriptor;
8485
import com.oracle.graal.python.lib.PyObjectSizeNode;
8586
import com.oracle.graal.python.nodes.ErrorMessages;
@@ -2130,27 +2131,10 @@ PNone kill(VirtualFrame frame, long pid, int signal,
21302131
@GenerateNodeFactory
21312132
// Can be used as an equivalent of PyOS_FSPath()
21322133
public abstract static class FspathNode extends PythonUnaryBuiltinNode {
2133-
2134-
@Specialization(guards = "isPath(value)")
2135-
static Object doTrivial(Object value) {
2136-
return value;
2137-
}
2138-
2139-
@Specialization(guards = "!isPath(value)")
2140-
Object callFspath(VirtualFrame frame, Object value,
2141-
@Cached("create(T___FSPATH__)") LookupAndCallUnaryNode callFSPath) {
2142-
Object pathObject = callFSPath.executeObject(frame, value);
2143-
if (isPath(pathObject)) {
2144-
return pathObject;
2145-
} else if (pathObject == PNone.NO_VALUE) {
2146-
throw raise(TypeError, ErrorMessages.EXPECTED_STR_BYTE_OSPATHLIKE_OBJ, value);
2147-
} else {
2148-
throw raise(TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, value, pathObject);
2149-
}
2150-
}
2151-
2152-
protected static boolean isPath(Object obj) {
2153-
return PGuards.isString(obj) || obj instanceof PBytes;
2134+
@Specialization
2135+
static Object doTrivial(VirtualFrame frame, Object value,
2136+
@Cached PyOSFSPathNode fsPathNode) {
2137+
return fsPathNode.execute(frame, value);
21542138
}
21552139
}
21562140

@@ -2243,14 +2227,14 @@ abstract static class ObjectToOpaquePathNode extends PNodeWithRaise {
22432227

22442228
@Specialization(guards = "!checkEmpty")
22452229
static Object noCheck(VirtualFrame frame, Object obj, @SuppressWarnings("unused") boolean checkEmpty,
2246-
@Cached FspathNode fspathNode,
2230+
@Cached PyOSFSPathNode fspathNode,
22472231
@Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode) {
22482232
return stringOrBytesToOpaquePathNode.execute(fspathNode.execute(frame, obj));
22492233
}
22502234

22512235
@Specialization(guards = "checkEmpty")
22522236
Object withCheck(VirtualFrame frame, Object obj, @SuppressWarnings("unused") boolean checkEmpty,
2253-
@Cached FspathNode fspathNode,
2237+
@Cached PyOSFSPathNode fspathNode,
22542238
@Cached PyObjectSizeNode sizeNode,
22552239
@Cached StringOrBytesToOpaquePathNode stringOrBytesToOpaquePathNode) {
22562240
Object stringOrBytes = fspathNode.execute(frame, obj);
@@ -2415,7 +2399,7 @@ public static PBytes opaquePathToBytes(Object opaquePath, PosixSupportLibrary po
24152399
public abstract static class FsConverterNode extends ArgumentCastNodeWithRaise {
24162400
@Specialization
24172401
static PBytes convert(VirtualFrame frame, Object value,
2418-
@Cached FspathNode fspathNode,
2402+
@Cached PyOSFSPathNode fspathNode,
24192403
@Cached StringOrBytesToBytesNode stringOrBytesToBytesNode) {
24202404
return stringOrBytesToBytesNode.execute(fspathNode.execute(frame, value));
24212405
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2021, 2022, 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.builtins.modules.cext;
42+
43+
import java.util.List;
44+
45+
import com.oracle.graal.python.builtins.Builtin;
46+
import com.oracle.graal.python.builtins.CoreFunctions;
47+
import com.oracle.graal.python.builtins.Python3Core;
48+
import com.oracle.graal.python.builtins.PythonBuiltins;
49+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
50+
import com.oracle.graal.python.lib.PyOSFSPathNode;
51+
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
52+
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
53+
import com.oracle.graal.python.runtime.PythonContext;
54+
import com.oracle.graal.python.runtime.exception.PException;
55+
import com.oracle.truffle.api.dsl.Cached;
56+
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
57+
import com.oracle.truffle.api.dsl.NodeFactory;
58+
import com.oracle.truffle.api.dsl.Specialization;
59+
import com.oracle.truffle.api.frame.VirtualFrame;
60+
61+
@CoreFunctions(extendsModule = PythonCextBuiltins.PYTHON_CEXT)
62+
@GenerateNodeFactory
63+
public final class PythonCextPosixmoduleBuiltins extends PythonBuiltins {
64+
65+
@Override
66+
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
67+
return PythonCextPosixmoduleBuiltinsFactory.getFactories();
68+
}
69+
70+
@Override
71+
public void initialize(Python3Core core) {
72+
super.initialize(core);
73+
}
74+
75+
@Builtin(name = "PyOS_FSPath", minNumOfPositionalArgs = 1)
76+
@GenerateNodeFactory
77+
abstract static class PyOS_FSPath extends PythonUnaryBuiltinNode {
78+
@Specialization
79+
static Object doit(VirtualFrame frame, Object path,
80+
@Cached PyOSFSPathNode fspathNode,
81+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
82+
try {
83+
return fspathNode.execute(frame, path);
84+
} catch (PException e) {
85+
transformExceptionToNativeNode.execute(frame, e);
86+
return PythonContext.get(fspathNode).getNativeNull();
87+
}
88+
}
89+
}
90+
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
import com.oracle.graal.python.annotations.ClinicConverterFactory.ArgumentIndex;
6161
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
6262
import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins;
63-
import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins;
6463
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
6564
import com.oracle.graal.python.builtins.objects.PNone;
6665
import com.oracle.graal.python.builtins.objects.buffer.BufferFlags;
@@ -79,6 +78,7 @@
7978
import com.oracle.graal.python.lib.PyIndexCheckNode;
8079
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
8180
import com.oracle.graal.python.lib.PyNumberIndexNode;
81+
import com.oracle.graal.python.lib.PyOSFSPathNode;
8282
import com.oracle.graal.python.lib.PyObjectGetIter;
8383
import com.oracle.graal.python.nodes.ErrorMessages;
8484
import com.oracle.graal.python.nodes.PGuards;
@@ -848,7 +848,7 @@ TruffleString doit(VirtualFrame frame, Object value,
848848
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
849849
@CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib,
850850
@Cached CastToTruffleStringNode toString,
851-
@Cached PosixModuleBuiltins.FspathNode fsPath,
851+
@Cached PyOSFSPathNode fsPath,
852852
@Cached TruffleString.FromByteArrayNode fromByteArrayNode,
853853
@Cached TruffleString.SwitchEncodingNode switchEncodingNode) {
854854
Object path = fsPath.execute(frame, value);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyOSFSPathNode.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ static Object callFspath(VirtualFrame frame, Object object,
9696
throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_STR_BYTE_OSPATHLIKE_OBJ, object);
9797
}
9898
Object result = callFSPath.executeObject(frame, fspathMethod, object);
99-
if (isJavaString(result) || result instanceof TruffleString || result instanceof PString || result instanceof PBytes) {
99+
assert !isJavaString(result);
100+
if (result instanceof TruffleString || result instanceof PString || result instanceof PBytes) {
100101
return result;
101102
}
102103
throw raiseNode.raise(TypeError, ErrorMessages.EXPECTED_FSPATH_TO_RETURN_STR_OR_BYTES, object, result);

0 commit comments

Comments
 (0)